voodoosms/laravel-metrics

Laravel Metrics package

v1.6.3 2024-05-03 10:23 UTC

This package is auto-updated.

Last update: 2024-05-03 09:33:15 UTC


README

This package handles collecting and emitting metrics from a Laravel application.

Usage

Installation

composer require voodoosms/laravel-metrics

If you want to configure channels and auto-discovery, you need to publish the config file by running:

php artisan vendor:publish

Defining Metrics

Create a new class which either implements the VoodooSMS\LaravelMetrics\Interfaces\Metric or extends VoodooSMS\LaravelMetrics\Abstracts\Metric. You can use php artisan make:metric to generate this for you.

Then write the key and value methods. The key is the identifier of the of the metric, e.g. queue-size:

class TestMetric extends Metric
{
    public function key(): string
    {
        return 'queue-size';
    }

    public function collect()
    {
        $this->value = Queue::size();

        return $this;
    }
}

You can run this command php artisan make:metric --cached to create a cached metric, this will store the value of the metric in the cache, and adds a getCachedValue() function which retrieves this cached value..

Prometheus Metrics

Prometheus is an events monitoring and alerting tool. When deployed in a kubernetes cluster, you can expose custom metrics to it from within a deployment which can then be used to automatically scale that deployment.

Create a new class which either implements the VoodooSMS\LaravelMetrics\Interfaces\Metric and VoodooSMS\LaravelMetrics\Interfaces\PrometheusMetric interfaces, or extends VoodooSMS\LaravelMetrics\Abstracts\PrometheusMetric. You can use php artisan make:metric --prometheus to generate this for you. (Note: this generated class has the $channels property set to [PrometheusChannel::class] so you will need to update this if you want this metric to broadcast via other channels.

There is one more method that needs defining for a prometheus metric:

public function getPrometheusKey(): string
{
    return 'queue_size{queue="multisms"}';
}

This is the metric label that prometheus will pick up, see the prometheus docs for more info on this.

The final step to exposing metrics for prometheus is to add:

use VoodooSMS\LaravelMetrics\Metrics;

Metrics::routes();

to your routes file so that the /metrics endpoint is registered in the router.

Note: as prometheus polls the /metrics endpoint to collect the data, the latest result of a prometheus metric is stored in the cache in order to improve response times (with a lot of metrics to collect and no caching this could take a long time). This means that running php artisan cache:clear will affect the response times of this endpoint.

To get prometheus to start scraping metrics from this endpoint, add these annotations to the nginx/php-fpm deployment:

prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "80"

Alternatively, you can use the exporter voodoosms/metrics-exporter, passing through the redis connection details. This image will connect to redis and expose the metrics on port 8080 at /metrics.

Metrics discovery

You can rely on the package's auto-discovery to find and process your metrics classes. For a default laravel install, all you need to do is create your metrics in app/Metrics. If you are storing your classes in a different folder/namespace, you need to set the metrics.path and metrics.namespace config values accordingly.

Alternatively, you can set metrics.autodiscover to false, and set the metrics.metrics array to define your metrics classes statically. These need to be a fully-qualified class name, e.g. TestMetric::class or it will not work.

Defining Channels

Channels are where your metrics are sent to. There are three built-in channels:

  • VoodooSMS\LaravelMetrics\Channels\StackChannel - the default laravel log file
  • VoodooSMS\LaravelMetrics\Channels\DatadogChannel - sends a datadog log
  • VoodooSMS\LaravelMetrics\Channels\CacheChannel - exports a cached metric to redis (requires redis)
  • VoodooSMS\LaravelMetrics\Channels\PrometheusChannel - exports a prometheus metric (requires redis)

You can easily add your own channel by creating a class that implements VoodooSMS\LaravelMetrics\Interfaces\Channel. You can also run the php artisan make:metrics-channel command to generate this for you.

You can set the default channels metrics get sent to in the config metrics.reporting.channels. This should be an array of fully-qualified channel classes, e.g.:


[
    'reporting' => [
        'channels' => [
            VoodooSMS\LaravelMetrics\Channels\StackChannel::class,
        ]
    ],
]

Or, if you want different channels for a particular metric, you can set the protected $channels property on the Metric class:

protected ?array $channels = [StackChannel::class];

Note: if you set the channels property in the class, it will only be sent to the channels in that array.

Collecting & Emitting Metrics

You can then use the VoodooSMS\LaravelMetrics\Metrics class to collect and send these metrics (you can instantiate your own Collector and Emitter instances if you need to). You can either instantiate this yourself, or let laravel do this via dependency injection.

Once you have an instance of the Metrics class, you just need to call handle() method.

Commands

You can call the built-in command to collect and display metrics in the temrinal:

php artisan metrics:collect

You can call the built-in command to collect and emit metrics:

php artisan metrics:emit

This command will run indefinitely and will collect and emit metrics every x seconds, based on the config metrics.reporting.interval. This defaults to every 5 seconds.

Deploying

There is an image that can be used to emit these metrics voodoosms/metrics (see the dockerhub repo for more details).

To use this image all you need to do is copy the laravel code into /var/www/microservice and the metrics:emit command will be the container's entrypoint.