ensi/laravel-prometheus

1.0.10 2024-06-26 09:14 UTC

This package is auto-updated.

Last update: 2024-08-27 08:54:36 UTC


README

Latest Version on Packagist Tests Total Downloads

适配器,用于promphp/prometheus_client_php

安装

您可以通过 composer 安装此软件包

composer require ensi/laravel-prometheus

使用以下命令发布配置

php artisan vendor:publish --provider="Ensi\LaravelPrometheus\PrometheusServiceProvider"

版本兼容性

基本用法

在您完成指标计数器之前,您需要注册它们。最佳做法是使用应用程序服务提供者的 boot() 方法。

# app/Providers/AppServiceProvider.php
public function boot() {
    Prometheus::counter('http_requests_count')->labels(['endpoint', 'code']);
    Prometheus::summary('http_requests_duration_seconds', 60, [0.5, 0.95, 0.99]);
}

更新计数器值同样简单

# app/Http/Middleware/Telemetry.php
public function handle($request, Closure $next)
{
    $startTime = microtime(true);
    $response = $next($request);
    $endTime = microtime(true);
    
    Prometheus::update('http_requests_count', 1, [Route::current()?->uri, $response->status()]);
    Prometheus::update('http_requests_duration_seconds', $endTime - $startTime);
    
    return $response;
}

配置

配置文件的架构

# config/prometheus.php
return [
    'default_bag' => '<bag-name>',
    'enabled' => env('PROMETHEUS_ENABLED', true),
    'app_name' => env('PROMETHEUS_APP_NAME', env('APP_NAME')),
    'bags' => [
        '<bag-name>' => [
            'namespace' => '<prometheus-namespace>',
            'route' => '<path-of-scrape-endpoint>',
            'basic_auth' => [
                'login' => env('PROMETHEUS_AUTH_LOGIN'),
                'password' => env('PROMETHEUS_AUTH_PASSWORD'),
            ],
            '<storage-type>' => [
                '<connection-parameters>'
            ],
            'label_middlewares' => [
                '<middleware-class>'
            ],
            'on_demand_metrics' => [
                '<on-demand-metric-class>'
            ]  
        ],
    ],
];

Bag

您可能希望拥有多组指标,例如,一组包含技术指标,如 HTTP 请求次数或意外异常的数量,另一组包含业务值,如订单数量或特定页面的展示次数。为此,引入了 Bag 的概念。您可以为每个 Bag 配置多个指标,指定您自己的数据仓库,为收集指标设置单独的端点等。

存储类型

您可以使用 promphp/prometheus_client_php 软件包中的所有存储(适配器)。此外,您还可以在 config/databases.php 文件中指定 redis 连接的名称。

存储配置选项。
将指标存储在进程内存中。

'memory' => true

使用 apcupsd

'apcu' => [
    'prefix' => 'metrics'
]

或替代 APCuNG 适配器

'apcu-ng' => [
    'prefix' => 'metrics'
]

创建一个将自行建立 phpredis 连接的 Redis 适配器

'redis' => [
    'host' => '127.0.0.1',
    'port' => 6379,
    'timeout' => 0.1,
    'read_timeout' => '10',
    'persistent_connections' => false,
    'password' => null,
    'prefix' => 'my-app',
    'bag' => 'my-metrics-bag'
]

来自 config/databases.php 的 Laravel Redis 连接。底层将创建相同的 Redis 适配器,但它将从 Laravel 的 Redismanager 中获取本机 phpredis 连接对象。

'connection' => [
    'connection' => 'default',
    'bag' => 'default',
]

高级用法

您可以使用 bag($bagName) 方法选择另一个 Bag,并在其中创建和更新指标。

# app/Providers/AppServiceProvider.php
public function boot() {
    // создаём метрики в конкретном bag
    Prometheus::bag('business')->counter('orders_count')->labels(['delivery_type', 'payment_method'])
}

# app/Actions/CreateOrder.php
public function execute(Order $order) {
    // ...
    Prometheus::bag('business')->update('orders_count', 1, [$order->delivery_type, $order->payment_method]);
}

标签中间件

您可以通过指定配置中的所谓 Label 中间件来为所有 Bagmetric 添加标签。标签中间件在确定指标时以及更新其计数器时被触发,在第一种情况下添加到标签名称中,在第二种情况下添加到值中。

例如,我们有一个 TenantLabelProvider

class TenantLabelMiddleware implements LabelMiddleware
{
    public function labels(): array
    {
        return ['tenant'];
    }

    public function values(): array
    {
        return [Tenant::curent()->id];
    }
}

我们将其注册到 Bag 配置中。

# config/prometheus.php
return [
    // ...
    'bags' => [
        'default' => [
            // ...
            'label_middlewares' => [
                \App\System\TenantLabelMiddleware::class,
            ]
        ],
    ],
];

然后,像往常一样,我们处理指标。

Prometheus::counter('http_requests_count')->labels(['endpoint', 'code']);
// ...
Prometheus::update('http_requests_count', 1, [Route::current()?->uri, $response->status()]);

结果,指标将具有三个标签,而不是两个

app_http_requests_count{endpoint="catalog/products",code="200",tenant="JBZ-987-H6"} 987

按需指标

有时指标与应用程序事件无关。通常这些是 gauge 类型的指标,没有必要在每个请求上更新它们,因为 Prometheus 仍然只取最后设置值。此类指标可以在 Prometheus 收集指标时计算。为此,您需要创建所谓的按需指标。这是您在其中注册指标并设置值的类。

class QueueLengthOnDemandMetric extends OnDemandMetric {
    public function register(MetricsBag $metricsBag): void
    {
        $metricsBag->gauge('queue_length');
    }

    public function update(MetricsBag $metricsBag): void
    {
        $metricsBag->update('queue_length', Queue::size());
    }
}

此类指标的更新发生在 Prometheus 地址获取指标端点时。

贡献

有关详细信息,请参阅 CONTRIBUTING

测试

  1. composer install
  2. composer test

安全漏洞

请查看我们的安全策略 如何报告安全漏洞

许可协议

MIT许可证(MIT)。更多信息请参阅许可证文件