tasko-products/symfony-prometheus-exporter

一个通用的指标导出器,适用于Symfony,包括通过中间件的消息传递事件指标、请求指标、日志指标和通过收集器组合的自定义指标

2.1.0 2024-02-08 12:49 UTC

This package is not auto-updated.

Last update: 2024-09-19 17:26:37 UTC


README

Code Checks Tests

请注意,此包处于积极开发状态。在收集指标时,仍可能出现偶尔的错误。

请将错误报告为Github上的一个问题(新建问题)或向我们发送拉取请求

Symfony Prometheus Exporter是一个包含大量通用Prometheus指标的bundle,存储在您的Redis仓库中。

每个指标收集器都可以分别启用和禁用,因此您可以决定为您的应用程序收集哪些数据并提供给Prometheus查询。

  • 通过中间件的消息传递指标
  • 通过事件的消息传递指标
  • (待办)请求指标
  • (待办)日志指标
  • (待办)通过收集器组合的自定义指标

此Symfony bundle基于非官方的Prometheus PHP客户端PHP库

通过中间件的消息传递指标

在消息被发送以及从工作者接收时,计数器将增加。

通过事件的消息传递指标

适用于使用Symfony Flex的应用程序的安装

打开命令行,进入您的项目目录并执行

$ composer require tasko-products/symfony-prometheus-exporter

不使用Symfony Flex的应用程序的安装

步骤1:使用Composer下载SymfonyPrometheusExporter

使用Composer Composer 需要 tasko-products/symfony-prometheus-exporter

$ composer require tasko-products/symfony-prometheus-exporter

步骤2:启用bundle

然后,通过将其添加到项目中config/bundles.php文件中注册的bundle列表中来启用bundle。

// config/bundles.php

return [
    // ...
    TaskoProducts\SymfonyPrometheusExporterBundle\TaskoProductsSymfonyPrometheusExporterBundle::class => ['all' => true],
];

配置

打开指标路由(可选)

1. 注册路由

将以下yaml添加到您的路由配置中,以注册open_metrics路由。

# app/config/routes.yaml

open_metrics:
    path: /metrics
    controller: TaskoProducts\SymfonyPrometheusExporterBundle\Controller\OpenMetricsController::metrics

2. 使用基本身份验证保护路由

如果您通过TLS与您的应用程序通信,或者用于开发目的,请仅使用基本身份验证。您的密码仅是base64编码。

为了保护您的路由,您需要Symfony Security Bundle。确保已安装,运行以下命令:

$ composer require symfony/security-bundle

然后定义一个密码散列器,如果尚未定义,请确保已安装,运行以下命令:

$ composer require symfony/password-hasher

然后将它添加到您的安全配置中。

# app/config/packages/security.yaml

security:
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
            algorithm: 'auto'
            cost:      15

生成一个编码的密码。

Symfony版本 < 6

$ bin/console security:encode-password

Symfony版本 >= 6

$ bin/console security:hash-password

将编码的密码和用户名存储在您的环境文件中。

# app/.env
OPEN_METRICS_BASIC_AUTH_USERNAME='secure-user-name'
OPEN_METRICS_BASIC_AUTH_PASSWORD='$argon2id$v=19$m=65536,t=4,p=1$DbXHchj+n5kTi9CNG7JhFA$HXtY5aSueVGbK3RxkvBlc8U1+d6Y7VJtYGbbV4CbpFw'

将Symfony的内存用户提供者添加到安全提供者中。在这里,您使用之前定义的环境变量。

# app/config/packages/security.yaml

security:
    providers:
        open_metrics_basic_auth:
            memory:
                users:
                - identifier: '%env(OPEN_METRICS_BASIC_AUTH_USERNAME)%'
                  password: '%env(OPEN_METRICS_BASIC_AUTH_PASSWORD)%'
                  roles: [ ROLE_OPEN_METRICS_USER ]

最后,您需要一个防火墙来保护您的路由。将以下http_basic防火墙添加到您的安全配置中。

# app/config/packages/security.yaml

security:
    firewalls:
        open_metrics:
            pattern:  ^/metrics
            http_basic:
                provider: open_metrics_basic_auth

尝试使用以下curl检索您的指标,并将Authorization头设置为您的密钥。

在Linux和Mac上编码您的密钥

# output base64 string:
# c2VjdXJlLXVzZXItbmFtZTpzZWN1cmUtdXNlci1wYXNzd29yZAo=

$ echo 'secure-user-name:secure-user-passwort' | base64

在Windows上使用Certutil将您的机密信息编码为base64。

# Certutils requires you to encode based on files

$ certutil -encode your-secrets.txt tmp.b64 && findstr /v /c:- tmp.b64 > encoded-secrets.b64
$ curl --request GET \
  --url https:///metrics \
  --header 'Authorization: Basic c2VjdXJlLXVzZXItbmFtZTpzZWN1cmUtdXNlci1wYXNzd29yZAo='

Prometheus Redis配置(可选)

将Prometheus Redis配置添加到您的服务中。

# app/config/services.yaml

services:
    Prometheus\Storage\Redis:
        arguments:
            - host: '%env(PROMETHEUS_REDIS_HOST)%'
              port: '%env(PROMETHEUS_REDIS_PORT)%'
              password: '%env(PROMETHEUS_REDIS_PASSWORD)%'
              # timeout: '%env(PROMETHEUS_REDIS_TIMEOUT)%'
              # read_timeout: '%env(PROMETHEUS_REDIS_READ_TIMEOUT)%'
              # persistent_connections: '%env(PROMETHEUS_REDIS_PERSISTENT_CONNECTIONS)%'
    Prometheus\CollectorRegistry: ['@Prometheus\Storage\Redis']

默认情况下,捆绑包附带内存配置

# Bundle: services.yaml
Prometheus\Storage\InMemory: ~
Prometheus\CollectorRegistry: ['@Prometheus\Storage\InMemory']
Prometheus\RegistryInterface: '@Prometheus\CollectorRegistry'

启用symfony/messenger中间件指标收集器(可选)

注册您的消息总线所需的中间件。

# app/config/messenger.yaml

framework:
    messenger:
        buses:
            message.bus.commands:
                middleware:
                    - 'TaskoProducts\SymfonyPrometheusExporterBundle\Middleware\MessengerEventMiddleware'
                    - 'TaskoProducts\SymfonyPrometheusExporterBundle\Middleware\RetryMessengerEventMiddleware'

要覆盖默认标签和文本

请注意,只有当指标名称与以下正则表达式匹配时,对指标名称的更改才是有效的

/^[a-zA-Z_:][a-zA-Z0-9_:]*$/

请在regex101.com上验证您的名称

如果不存在,创建一个新的yaml配置文件app/config/packages/prometheus_metrics.yaml。添加以下配置,现在您可以通过以下配置调整标签和文本。

# app/config/packages/prometheus_metrics.yaml

tasko_products_symfony_prometheus_exporter:
  middlewares:
    event_middleware:
      # enabled by 'app/config/messenger.yaml'
      namespace: 'middleware'
      metric_name: 'message'
      help_text: 'Executed Messages'
      labels:
        bus: 'bus'
        message: 'message'
        label: 'label'
      error_help_text: 'Failed Messages'
      error_labels:
        bus: 'bus'
        message: 'message'
        label: 'label'

    retry_event_middleware:
      # enabled by 'app/config/messenger.yaml'
      namespace: 'middleware'
      metric_name: 'retry_message'
      help_text: 'Retried Messages'
      labels:
        bus: 'bus'
        message: 'message'
        label: 'label'
        retry: 'retry'

MessengerEventMiddleware的示例

# HELP middleware_message Executed Messages
# TYPE middleware_message counter
middleware_message{bus="message_bus_commands",message="App\\Message\\FailingFooBarMessage",label="FailingFooBarMessage"} 1337
middleware_message{bus="message_bus_commands",message="App\\Message\\FooBarMessage",label="FooBarMessage"} 2096
# HELP middleware_message_error Failed Messages
# TYPE middleware_message_error counter
middleware_message_error{bus="message_bus_commands",message="App\\Message\\FailingFooBarMessage",label="FailingFooBarMessage"} 1337
middleware_message_error{bus="message_bus_commands",message="App\\Message\\FooBarMessage",label="FooBarMessage"} 0

RetryMessengerEventMiddleware的示例

# HELP middleware_retry_message Retried Messages
# TYPE middleware_retry_message counter
middleware_retry_message{bus="message_bus_commands",message="App\\Message\\FailingFooBarMessage",label="FailingFooBarMessage",retry="0"} 0
middleware_retry_message{bus="message_bus_commands",message="App\\Message\\FooBarMessage",label="FooBarMessage",retry="0"} 0
middleware_retry_message{bus="message_bus_commands",message="App\\Message\\FooBarMessage",label="FooBarMessage",retry="2"} 666

启用消息事件订阅者指标收集器(可选)

请注意,只有当指标名称与以下正则表达式匹配时,对指标名称的更改才是有效的

/^[a-zA-Z_:][a-zA-Z0-9_:]*$/

请在regex101.com上验证您的名称

根据需要注册所需的事件订阅者。创建一个新的配置yaml文件app/config/packages/prometheus_metrics.yaml。添加以下配置,现在您可以激活/禁用事件订阅者并通过以下配置调整标签和文本。

# app/config/packages/prometheus_metrics.yaml

tasko_products_symfony_prometheus_exporter:
  event_subscribers:
    active_workers:
      enabled: false
    #   namespace: 'messenger_events'
    #   metric_name: 'active_workers'
    #   help_text: 'Active Workers'
    #   labels:
    #     queue_names: 'queue_names'
    #     transport_names: 'transport_names'

    messages_in_process:
      enabled: false
    #   namespace: 'messenger_events'
    #   metric_name: 'messages_in_process'
    #   help_text: 'Messages In Process'
    #   labels:
    #     message_path: 'message_path'
    #     message_class: 'message_class'
    #     receiver: 'receiver'
    #     bus: 'bus'

    messages_in_transport:
      enabled: false
    #   namespace: 'messenger_events'
    #   metric_name: 'messages_in_transport'
    #   help_text: 'Messages In Transport'
    #   labels:
    #     message_path: 'message_path'
    #     message_class: 'message_class'
    #     bus: 'bus'

active_workers(ActiveWorkersMetricEventSubscriber)的示例

# HELP messenger_events_active_workers Active Workers
# TYPE messenger_events_active_workers gauge
messenger_events_active_workers{queue_names="default_queue, priority_queue",transport_names="async"} 1

messages_in_process(MessagesInProcessMetricEventSubscriber)的示例

# HELP messenger_events_messages_in_process Messages In Process
# TYPE messenger_events_messages_in_process gauge
messenger_events_messages_in_process{message_path="App\\Message\\FailingFooBarMessage",message_class="FailingFooBarMessage",receiver="async",bus="messenger_bus_default"} 1
messenger_events_messages_in_process{message_path="App\\Message\\FooBarMessage",message_class="FooBarMessage",receiver="async",bus="messenger_bus_default"} 0

messages_in_transport(MessagesInTransportMetricEventSubscriber)的示例

# HELP messenger_events_messages_in_transport Messages In Transport
# TYPE messenger_events_messages_in_transport gauge
messenger_events_messages_in_transport{message_path="App\\Message\\FailingFooBarMessage",message_class="FailingFooBarMessage",bus="messenger_bus_default"} 0
messenger_events_messages_in_transport{message_path="App\\Message\\FooBarMessage",message_class="FooBarMessage",bus="messenger_bus_default"} 1412

测试

PHPUnit

安装依赖项

$ composer install

运行测试

$ ./vendor/bin/phpunit

通过docker-compose运行PHPUnit

只需使用docker-compose启动nginx、fpm和Redis设置

$ docker-compose up -d

然后通过docker-compose运行phpunit:

$ docker-compose run phpunit vendor/bin/phpunit

静态代码分析

PHPStan

安装依赖项

$ composer install

只需运行分析

$ vendor/bin/phpstan analyse src tests

代码清理

php-cs-fixer

安装依赖项

$ composer install

只需运行清理

$ vendor/bin/php-cs-fixer fix

版权(c)2022 tasko Products GmbH 2022。MIT许可。

有关完整的版权和许可信息,请查看与此源代码一起分发的LICENSE文件。