arquivei/laravel-prometheus-exporter

Laravel 和 Lumen 的 Prometheus 导出器

4.0.0 2023-07-05 21:30 UTC

README

Laravel 和 Lumen 的 Prometheus 导出器包。

Software License

简介

Prometheus 是一个带有 UI 和复杂查询语言(PromQL)的时间序列数据库,可以通过 HTTP 提取指标、计数器、仪表和直方图。

本包是一个包装器,将 jimdo/prometheus_client_php 集成到 Laravel 和 Lumen 中。

示例

前往 examples/lumen-app 查看我们的优秀示例应用程序。要获取它,您需要克隆 Laravel Prometheus Exporter 仓库,因为示例在通过 composer 下载时并未包含在内。

示例是一个包含自己的 README.md 的完整项目,因此您可以检查库的功能及其预期使用方式。

安装

将存储库添加到 composer.json

"repositories": [
  {
    "type": "vcs",
    "url": "https://github.com/arquivei/laravel-prometheus-exporter"
  }
],

通过 composer 安装此包

composer require arquivei/laravel-prometheus-exporter

之后,您可以在应用程序的 bootstrap/app.php 中启用 facade 并注册 facade

$userAliases = [
    // ...
    Arquivei\LaravelPrometheusExporter\PrometheusFacade::class => 'Prometheus',
];
$app->withFacades(true, $userAliases);

然后应在 bootstrap/app.php 中注册服务提供者

$app->register(Arquivei\LaravelPrometheusExporter\PrometheusServiceProvider::class);

有关在应用程序路由、Guzzle 调用和 SQL 查询上启用指标的操作说明,请参阅以下内容。

配置

该包有一个默认配置,使用以下环境变量。

PROMETHEUS_NAMESPACE=app

PROMETHEUS_METRICS_ROUTE_ENABLED=true
PROMETHEUS_METRICS_ROUTE_PATH=metrics
PROMETHEUS_METRICS_ROUTE_MIDDLEWARE=null
PROMETHEUS_COLLECT_FULL_SQL_QUERY=true
PROMETHEUS_STORAGE_ADAPTER=memory

PROMETHEUS_REDIS_HOST=localhost
PROMETHEUS_REDIS_PORT=6379
PROMETHEUS_REDIS_TIMEOUT=0.1
PROMETHEUS_REDIS_READ_TIMEOUT=10
PROMETHEUS_REDIS_PERSISTENT_CONNECTIONS=0
PROMETHEUS_REDIS_PREFIX=PROMETHEUS_

要自定义配置值,您可以覆盖上述环境变量(通常在应用程序的 .env 文件中完成),或者您可以复制包含的 prometheus.phpconfig/prometheus.php,编辑它并在应用程序中使用如下所示

$app->loadComponent('prometheus', [
    Arquivei\LaravelPrometheusExporter\PrometheusServiceProvider::class
]);

指标

该包允许您观察以下指标

  • 应用程序路由。关于请求方法、请求路径和状态码的指标。
  • Guzzle 调用。关于请求方法、URI 和状态码的指标。
  • SQL 查询。关于 SQL 查询和查询类型的指标。

为了在应用程序路由中观察指标(请求与响应之间的时间),您应在应用程序的 bootstrap/app.php 中注册以下中间件

$app->middleware([
    Arquivei\LaravelPrometheusExporter\RouteMiddleware::class,
]);

导出的标签是

[
    'method',
    'route',
    'status_code',
]

要观察 Guzzle 指标,您应在 bootstrap/app.php 中注册以下提供者

$app->register(Arquivei\LaravelPrometheusExporter\GuzzleServiceProvider::class);

导出的标签是

[
    'method',
    'external_endpoint',
    'status_code'
]

要观察 SQL 指标,您应在 bootstrap/app.php 中注册以下提供者

$app->register(Arquivei\LaravelPrometheusExporter\DatabaseServiceProvider::class);

导出的标签是

[
    'query',
    'query_type',
]

注意:您可以通过关闭 PROMETHEUS_COLLECT_FULL_SQL_QUERY 的配置来禁用记录完整查询。

存储适配器

存储适配器用于在请求之间持久化指标。默认启用 memory 适配器,这意味着数据只会跨当前请求持久化。

我们建议在生产环境中使用 redisapc 适配器。当然,您的安装必须提供 Redis 或 APC 实现。

PROMETHEUS_STORAGE_ADAPTER 环境变量用于指定存储适配器。

如果使用 redis,则还需要配置 PROMETHEUS_REDIS_HOSTPROMETHEUS_REDIS_PORT 变量。可选地,您可以更改 PROMETHEUS_REDIS_TIMEOUTPROMETHEUS_REDIS_READ_TIMEOUTPROMETHEUS_REDIS_PERSISTENT_CONNECTIONS 变量。

导出指标

该包添加了一个默认启用的 /metrics 端点,它暴露了收集器收集的所有指标。

可以使用 PROMETHEUS_METRICS_ROUTE_ENABLED 环境变量来开启或关闭此功能,也可以使用 PROMETHEUS_METRICS_ROUTE_PATH 环境变量进行更改。

收集器

收集器是一个类,实现了 CollectorInterface 接口,负责收集一个或多个指标的数据。

请参阅以下包含的 示例

您可以通过将它们添加到 prometheus.php 配置文件中的 collectors 数组来自动加载您的收集器。

示例

示例用法

以下是一个针对 Lumen 应用的示例用法

// retrieve the exporter (you can also use app('prometheus') or Prometheus::getFacadeRoot())
$exporter = app(\Arquivei\LaravelPrometheusExporter\PrometheusExporter::class);

// register a new collector
$collector = new \My\New\Collector();
$exporter->registerCollector($collector);

// retrieve all collectors
var_dump($exporter->getCollectors());

// retrieve a collector by name
$collector = $exporter->getCollector('user');

// export all metrics
// this is called automatically when the /metrics end-point is hit
var_dump($exporter->export());

// the following methods can be used to create and interact with counters, gauges and histograms directly
// these methods will typically be called by collectors, but can be used to register any custom metrics directly,
// without the need of a collector

// create a counter
$counter = $exporter->registerCounter('search_requests_total', 'The total number of search requests.');
$counter->inc(); // increment by 1
$counter->incBy(2);

// create a counter (with labels)
$counter = $exporter->registerCounter('search_requests_total', 'The total number of search requests.', ['request_type']);
$counter->inc(['GET']); // increment by 1
$counter->incBy(2, ['GET']);

// retrieve a counter
$counter = $exporter->getCounter('search_requests_total');

// create a gauge
$gauge = $exporter->registerGauge('users_online_total', 'The total number of users online.');
$gauge->inc(); // increment by 1
$gauge->incBy(2);
$gauge->dec(); // decrement by 1
$gauge->decBy(2);
$gauge->set(36);

// create a gauge (with labels)
$gauge = $exporter->registerGauge('users_online_total', 'The total number of users online.', ['group']);
$gauge->inc(['staff']); // increment by 1
$gauge->incBy(2, ['staff']);
$gauge->dec(['staff']); // decrement by 1
$gauge->decBy(2, ['staff']);
$gauge->set(36, ['staff']);

// retrieve a gauge
$counter = $exporter->getGauge('users_online_total');

// create a histogram
$histogram = $exporter->registerHistogram(
    'response_time_seconds',
    'The response time of a request.',
    [],
    [0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0]
);
// the buckets must be in asc order
// if buckets aren't specified, the default 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0 buckets will be used
$histogram->observe(5.0);

// create a histogram (with labels)
$histogram = $exporter->registerHistogram(
    'response_time_seconds',
    'The response time of a request.',
    ['request_type'],
    [0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0]
);
// the buckets must be in asc order
// if buckets aren't specified, the default 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0 buckets will be used
$histogram->observe(5.0, ['GET']);

// retrieve a histogram
$counter = $exporter->getHistogram('response_time_seconds');

收集器

以下是一个示例收集器实现

<?php

declare(strict_types = 1);

namespace Arquivei\LaravelPrometheusExporter;

use Prometheus\Gauge;

class ExampleCollector implements CollectorInterface
{
    /**
     * @var Gauge
     */
    protected $usersRegisteredGauge;

    /**
     * Return the name of the collector.
     *
     * @return string
     */
    public function getName() : string
    {
        return 'users';
    }

    /**
     * Register all metrics associated with the collector.
     *
     * The metrics needs to be registered on the exporter object.
     * eg:
     * ```php
     * $exporter->registerCounter('search_requests_total', 'The total number of search requests.');
     * ```
     *
     * @param PrometheusExporter $exporter
     */
    public function registerMetrics(PrometheusExporter $exporter) : void
    {
        $this->usersRegisteredGauge = $exporter->registerGauge(
            'users_registered_total',
            'The total number of registered users.',
            ['group']
        );
    }

    /**
     * Collect metrics data, if need be, before exporting.
     *
     * As an example, this may be used to perform time consuming database queries and set the value of a counter
     * or gauge.
     */
    public function collect() : void
    {
        // retrieve the total number of staff users registered
        // eg: $totalUsers = Users::where('group', 'staff')->count();
        $this->usersRegisteredGauge->set(36, ['staff']);

        // retrieve the total number of regular users registered
        // eg: $totalUsers = Users::where('group', 'regular')->count();
        $this->usersRegisteredGauge->set(192, ['regular']);
    }
}