/php-prometheus-client

Collect and export PHP App metrics with ease

Primary LanguagePHPMIT LicenseMIT

PHP Prometheus Client

codecov

This package provides you an ability to collect and export Prometheus metrics from any modern PHP application.

Why?

  • Until now, there was no working Prometheus client for modern PHP
  • Framework-agnostic
  • Almost zero dependencies
  • Won't break your business logic even if something is wrong with Metrics Storage
  • Ready to use with static analysis tools (PHPStan, Psalm)

Supported metric types

  1. Counter
  2. Gauge
  3. Histogram

Summary is still in development. What can I do if my client library does not support the metric type I need?

Adapters

Installation

composer require zlodes/prometheus-exporter

Class responsibilities

Interface Description Default implementation
Registry To declare a specific metric ArrayRegistry
Storage Metrics values storage InMemoryStorage
Exporter Output collected metrics StoredMetricsExporter

Each class should be registered as a service. As a singleton in Laravel or shared service in Symfony.

Simple example

<?php

use Psr\Log\NullLogger;
use Zlodes\PrometheusClient\Collector\CollectorFactory;
use Zlodes\PrometheusClient\Exporter\StoredMetricsExporter;
use Zlodes\PrometheusClient\Metric\Counter;
use Zlodes\PrometheusClient\Metric\Gauge;
use Zlodes\PrometheusClient\Metric\Histogram;
use Zlodes\PrometheusClient\Registry\ArrayRegistry;
use Zlodes\PrometheusClient\Storage\InMemoryStorage;

$registry = new ArrayRegistry();
$storage = new InMemoryStorage();

// Register your metrics
$registry
    ->registerMetric(
        new Gauge('body_temperature', 'Body temperature in Celsius')
    )
    ->registerMetric(
        new Counter('steps', 'Steps count')
    )
    ->registerMetric(
        new Histogram('request_duration', 'Request duration in seconds'),
    );

// Create a Collector factory
$collectorFactory = new CollectorFactory(
    $registry,
    $storage,
    new NullLogger(),
);

// Collect metrics
$bodyTemperatureGauge = $collectorFactory->gauge('body_temperature');

$bodyTemperatureGauge
    ->withLabels(['source' => 'armpit'])
    ->update(36.6);

$bodyTemperatureGauge
    ->withLabels(['source' => 'ass'])
    ->update(37.2);

$collectorFactory
    ->counter('steps')
    ->increment();

$requestTimer = $collectorFactory
    ->histogram('request_duration')
    ->startTimer();

usleep(50_000);

$requestTimer->stop();

// Export metrics
$exporter = new StoredMetricsExporter(
    $registry,
    $storage,
);

foreach ($exporter->export() as $metricOutput) {
    echo $metricOutput . "\n\n";
}

Output example:

# HELP body_temperature Body temperature in Celsius
# TYPE body_temperature gauge
body_temperature{source="armpit"} 36.6
body_temperature{source="ass"} 37.2

# HELP steps Steps count
# TYPE steps counter
steps 1

Testing

Run tests

php ./vendor/bin/phpunit

Creating your own Storage

Keys serialization

There is a Serializer interface (with JSON-based implementation) to simplify work with a key-value storage.

Example can be found in InMemoryStorage.

Storage Testing

There is a simple trait to tests any storage you want. Here is an example:

class InMemoryStorageTest extends TestCase
{
    use StorageTesting;

    private function createStorage(): Storage
    {
        return new InMemoryStorage();
    }
}