定制 ensi/laravel-prometheus 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

ensi/laravel-prometheus

Composer 安装命令:

composer require ensi/laravel-prometheus

包简介

laravel prometheus

README 文档

README

Latest Version on Packagist Tests Total Downloads

Adapter for promphp/prometheus_client_php

Installation

You can install the package via composer:

composer require ensi/laravel-prometheus

Publish the config with:

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

Version Compatibility

Laravel Prometheus Laravel PHP
^1.0.0 ^9.x ^8.1
^1.0.4 ^9.x || ^10.x ^8.1
^1.0.9 ^9.x || ^10.x || ^11.x ^8.1
^1.1.0 ^9.x || ^10.x || ^11.x || ^12.x ^8.1

Basic Usage

Before you wind up the metric counters, you need to register them. The best thing to do is to use the boot() method from the application service provider.

# 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]);
}

Updating the counter value is just as easy

# 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;
}

Configuration

The structure of the configuration file

# 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

You may want to have several sets of metrics, for example, one set with technical metrics, such as the number of http requests or unexpected exceptions, and a second set for business values, such as the number of orders or impressions of a particular page. To do this, the concept of bag is introduced. You can configure several bugs by specifying your own data warehouse for each, a separate endpoint for collecting metrics, etc.

Storage type

You can use all the storage (Adapters) from the promphp/prometheus_client_php package. In addition, you can specify the name of the redis connection from the file config/databases.php.

Storage configuration options.
Store metrics in the process memory.

'memory' => true

Use apcupsd

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

or an alternative APCuNG adapter

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

A Redis adapter that will create a phpredis connection by itself

'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'
]

Laravel Redis connection from config/databases.php. The same Redis adapter will be created under the hood, but it will take the native phpredis connection object from laravel's Redismanager.

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

Advanced Usage

You can select another bag to create and update metrics in it using the bag($bagName) method.

# 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 Middlewares

You can add a label to all bagmetrics by specifying the so-called Label middleware in its configuration. Label middleware is triggered at the moment the metric is determined and at the moment its counter is updated, adding in the first case to the label name, and in the second case the value.

For example, we have a TenantLabelProvider

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

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

We register it in the bag configuration.

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

Then, as usual, we work with metrics.

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

As a result, the metric will have not two, but three labels

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

On demand metrics

Sometimes metrics are not linked to application events. Usually these are metrics of the gauge type, which it makes no sense to update on each incoming request, because prometheus will still take only the last set value. Such metrics can be calculated at the time of collection of metrics by prometheus. To do this, you need to create a so-called on demand metric. This is the class in which you register metrics and set values in them.

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());
    }
}

The update of such metrics occurs at the moment prometheus addresses the endpoint of obtaining metrics.

Contributing

Please see CONTRIBUTING for details.

Testing

  1. composer install
  2. composer test

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

License

The MIT License (MIT). Please see License File for more information.

ensi/laravel-prometheus 适用场景与选型建议

ensi/laravel-prometheus 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 92.82k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2022 年 12 月 10 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 ensi/laravel-prometheus 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 ensi/laravel-prometheus 我们能提供哪些服务?
定制开发 / 二次开发

基于 ensi/laravel-prometheus 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 92.82k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 18
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 2
  • Forks: 3
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-12-10