如何统计Symfony的HttpClient与Doctrine查询耗时并生成Prometheus指标
Symfony 中统计 HttpClient 与 Doctrine 耗时并上报 Prometheus 方案
一、Doctrine 查询耗时统计(解决你的监听器适用范围与性能顾虑)
你之前的误解是错的——Doctrine 有专门针对查询操作的轻量统计方案:
- 放弃实体生命周期监听器,改用
Doctrine\DBAL\Logging\SQLLogger接口,这是 Doctrine 官方提供的 SQL 日志/统计入口,覆盖所有 SQL 执行(包括 SELECT 查询)。 - 实现自定义 SQLLogger:
- 创建类实现
SQLLogger接口,在startQuery方法用microtime(true)记录当前时间戳,暂存时间戳、SQL 语句及参数。 - 在
stopQuery方法计算耗时(当前时间 - 开始时间),同时可解析 SQL 类型(SELECT/INSERT/UPDATE/DELETE)、关联表名等标签信息。
- 创建类实现
- 注册到 Doctrine 配置:在
config/packages/doctrine.yaml中配置doctrine.dbal.logger: App\Logging\PrometheusDoctrineSqlLogger(替换为你的类路径)。 - 性能说明:这种方式仅做时间戳记录与简单计算,几乎无性能开销,比监听实体生命周期事件高效得多,完全适配生产环境。
二、HttpClient 外部请求耗时统计
利用 Symfony HttpClient 的事件机制即可实现:
- 监听两个核心事件:
Symfony\Contracts\HttpClient\Event\BeforeRequestEvent:请求发送前,将当前时间戳存入请求属性(如$event->getRequest()->attributes->set('start_time', microtime(true)))。Symfony\Contracts\HttpClient\Event\ResponseEvent:响应返回后,从请求属性取出开始时间计算耗时。
- 注意事项:异步请求需确保时间戳与响应正确关联;对动态路径(如
/users/123)做归一化处理(转为/users/{id}),避免标签基数爆炸。
三、Prometheus 指标上报(基于你已安装的 promphp/prometheus_client_php)
针对两种耗时场景,推荐使用**直方图(Histogram)**类型指标,方便后续计算分位数(如95线、99线耗时):
1. Doctrine 查询指标
定义直方图:
use Prometheus\CollectorRegistry; $registry = CollectorRegistry::getDefault(); $doctrineQueryHistogram = $registry->registerHistogram( 'symfony_doctrine_query_duration_seconds', 'Duration of Doctrine SQL queries', ['query_type', 'table'] // 标签:查询类型、表名 );
在自定义 SQLLogger 的 stopQuery 方法中,调用 $doctrineQueryHistogram->observe($duration, [$queryType, $tableName]) 上报耗时。
2. HttpClient 请求指标
定义直方图:
$httpClientHistogram = $registry->registerHistogram( 'symfony_httpclient_request_duration_seconds', 'Duration of HttpClient external requests', ['method', 'host', 'endpoint'] // 标签:请求方法、目标主机、归一化接口路径 );
在 ResponseEvent 监听器中,调用 $httpClientHistogram->observe($duration, [$method, $host, $normalizedEndpoint]) 上报耗时。
最佳实践
- 控制标签基数:避免使用高基数标签值(如用户ID、随机参数),防止 Prometheus 存储压力过大。
- 环境开关:通过环境变量(如
APP_PERF_MONITORING_ENABLED)控制统计逻辑是否开启,方便在开发/测试环境关闭。 - 敏感数据过滤:不要在指标标签或日志中记录 SQL 参数、请求体等敏感信息。
内容的提问来源于stack exchange,提问作者Trayan
相关产品推荐
相关产品推荐

