Developed with love by KnpLabs Hire us for your project!
43

prometheus-metrics-bundle

by artprima

Symfony 5 Prometheus Metrics Bundle

Master Develop

Symfony 4/5 Prometheus Metrics Bundle

Installation

Applications that use Symfony Flex

Open a command console, enter your project directory and execute:

$ composer require artprima/prometheus-metrics-bundle

Applications that don't use Symfony Flex

Step 1: Download the Bundle

Open a command console, enter your project directory and execute the
following command to download the latest stable version of this bundle:

$ composer require artprima/prometheus-metrics-bundle

This command requires you to have Composer installed globally, as explained
in the installation chapter
of the Composer documentation.

Step 2: Enable the Bundle

Then, enable the bundle by adding it to the list of registered bundles
in the app/AppKernel.php file of your project:

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Artprima\PrometheusMetricsBundle\ArtprimaPrometheusMetricsBundle(),
        );

        // ...
    }

    // ...
}

Configuration

config.yaml

artprima_prometheus_metrics:
    # namespace is used to prefix the prometheus metrics
    namespace: myapp

    # metrics backend type
    type: in_memory # possible values: in_memory, apcu, redis

    # ignoring some routes in metrics
    ignored_routes: [some_route_name, another_route_name]

    # used in case of type = "redis"
    redis:
        host: 127.0.0.1
        port: 6379
        timeout: 0.1
        read_timeout: 10
        persistent_connections: false
        password: ~

routes.yaml

# expose /metrics/prometheus in your application
app_metrics:
    resource: '@ArtprimaPrometheusMetricsBundle/Resources/config/routing.xml'

You can alternatively define your own path and rules:

app_metrics:
    path: /mypath/mymetrics
    controller: Artprima\PrometheusMetricsBundle\Controller\MetricsController::prometheus

Now your metrics are available to Prometheus using http:///metrics/prometheus.

Custom Metrics Generator

If you want to collect your own metrics, you should create a class that will implement Artprima\PrometheusMetricsBundle\Metrics\MetricsGeneratorInterface. Something like this:

<?php

declare(strict_types=1);

namespace App\Metrics;

use Artprima\PrometheusMetricsBundle\Metrics\MetricsGeneratorInterface;
use Prometheus\CollectorRegistry;
use Prometheus\Exception\MetricNotFoundException;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\TerminateEvent;

/**
 * Class MyMetricsGenerator.
 */
class MyMetricsGenerator implements MetricsGeneratorInterface
{
    /**
     * @var string
     */
    private $namespace;

    /**
     * @var CollectorRegistry
     */
    private $collectionRegistry;

    public function init(string $namespace, CollectorRegistry $collectionRegistry): void
    {
        $this->namespace = $namespace;
        $this->collectionRegistry = $collectionRegistry;
    }

    private function incRequestsTotal(?string $method = null, ?string $route = null): void
    {
        $counter = $this->collectionRegistry->getOrRegisterCounter(
            $this->namespace,
            'http_requests_total',
            'total request count',
            ['action']
        );

        $counter->inc(['all']);

        if (null !== $method && null !== $route) {
            $counter->inc([sprintf('%s-%s', $method, $route)]);
        }
    }

    private function incResponsesTotal(?string $method = null, ?string $route = null): void
    {
        $counter = $this->collectionRegistry->getOrRegisterCounter(
            $this->namespace,
            'http_responses_total',
            'total response count',
            ['action']
        );
        $counter->inc(['all']);

        if (null !== $method && null !== $route) {
            $counter->inc([sprintf('%s-%s', $method, $route)]);
        }
    }

    // called on the `kernel.request` event
    public function collectRequest(RequestEvent $event): void
    {
        $request = $event->getRequest();
        $requestMethod = $request->getMethod();
        $requestRoute = $request->attributes->get('_route');

        // do not track "OPTIONS" requests
        if ('OPTIONS' === $requestMethod) {
            return;
        }

        $this->incRequestsTotal($requestMethod, $requestRoute);
    }

    // called on the `kernel.terminate` event
    public function collectResponse(TerminateEvent $event): void
    {
        $response = $event->getResponse();
        $request = $event->getRequest();

        $requestMethod = $request->getMethod();
        $requestRoute = $request->attributes->get('_route');

        $this->incResponsesTotal($requestMethod, $requestRoute);
    }
}

Then declare it this way:

    App\Metrics\MyMetricsGenerator:
        # NB: do NOT add a call to `init()` as it will be done automatically by the relevant compiler pass.
        tags:
            - { name: prometheus_metrics_bundle.metrics_generator }

Code license

You are free to use the code in this repository under the terms of the MIT license. LICENSE contains a copy of this license.

MIT License

Copyright (c) 2018 artprima

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
  • Merge branch 'release/1.3.0'
    By Denis V, 5 months ago
  • update ci php versions to 7.3 and 7.4, remove 7.1
    By Denis V, 6 months ago
  • Scrutinizer Auto-Fixes (#8)
    By , 6 months ago
  • remove backwards compatibility workaround
    By Denis V, 6 months ago
  • update readme to show develop branch status as well
    By Denis V, 6 months ago
  • GetResponseEvent => RequestEvent, PostResponseEvent => TerminateEvent (#7)
    By denisvmedia, 6 months ago
  • Fix readme
    By denisvmedia, 8 months ago
  • add support for Symfony 5 and fix tests
    By denisvmedia, 8 months ago
  • Update README.md
    By web-flow, 1 year ago
  • symfony 4.2 deprecation solved
    By Denis Voytyuk, 1 year ago
  • redis database config option (#1)
    By denisvmedia, 1 year ago
  • fix organization name for the prometheus php client
    By Denis V, 1 year ago
  • change vendor name
    By Denis V, 1 year ago
  • massive refactoring + new tests + docs
    By Denis V, 1 year ago
  • write tests
    By Denis V, 1 year ago
  • initial commit
    By Denis V, 1 year ago