Grafana 不直接采集 PHP 指标,需通过 promphp/prometheus_client_php 库暴露 /metrics 端点供 Prometheus 抓取,再由 Grafana 展示;关键点包括正确设置 Content-Type、避免超时、规范指标命名、在 PromQL 中合理使用标签和聚合函数,并结合日志与 FPM 状态交叉验证业务瓶颈。

Grafana 本身不直接支持 PHP 应用指标采集,必须通过中间服务暴露指标(如 Prometheus)再由 Grafana 展示。PHP 不是 Grafana 的数据源,而是被监控对象。
PHP 如何暴露 Prometheus 兼容的指标
最常用方式是使用 promphp/prometheus_client_php 库,它提供符合 Prometheus 文本格式的 HTTP 端点(如 /metrics)。
- 安装:
composer require promphp/prometheus_client_php - 在 Web 入口(如
index.php或独立metrics.php)中初始化 Registry 并注册指标,例如:$registry = \Prometheus\CollectorRegistry::getDefault(); $counter = $registry->getOrRegisterCounter('php_app', 'http_requests_total', 'HTTP Requests', ['method', 'path']); $counter->inc(['GET', '/home']); - 暴露指标:调用
$renderer = new \Prometheus\RenderTextFormat(); echo $renderer->render($registry->getMetricFamilySamples());,确保响应 Content-Type 为text/plain; version=0.0.4 - 关键点:该端点必须可被 Prometheus Server 访问(不能仅限 localhost,需注意防火墙和反向代理配置)
Prometheus 抓取 PHP 指标失败的常见原因
即使 PHP 能返回指标文本,Prometheus 仍可能报 server returned HTTP status 500 或 context deadline exceeded。
- PHP 脚本执行超时:默认
max_execution_time=30,而 Prometheus 抓取可能触发大量逻辑(如 DB 查询、缓存读取),建议在 metrics 路由中设set_time_limit(5) - 未正确设置响应头:缺失
Content-Type: text/plain; version=0.0.4会导致 Prometheus 解析失败,错误日志显示expected text format - 路径未被 Prometheus 配置覆盖:检查
scrape_configs中static_configs.targets是否包含 PHP 服务地址+端口,例如targets: ['192.168.1.10:8080'],且 PHP 是监听在对应端口或有反代透传 - 指标命名含非法字符:Prometheus 要求指标名只含 ASCII 字母、数字、下划线,
$counter->inc(['GET', '/user?id=1'])中的?和=不影响计数,但 label 值本身无需编码;真正要避免的是 label 名含破折号或空格
Grafana 中添加 PHP 指标图表的关键配置
数据源必须是已成功抓取到 PHP 指标的 Prometheus 实例,不是直接连 PHP。
- 新建 Dashboard → Add new panel → Query:输入 PromQL,例如
rate(http_requests_total{job="php-app"}[5m]),注意job标签需与 Prometheus 配置中的job_name一致 - 若指标无标签或标签值为空,
http_requests_total可能返回多条时间序列,导致图表混乱,建议至少添加一个区分维度,如instance或自定义environment - PHP 中动态创建的 Histogram(如请求耗时)需配合
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))使用,不能直接查_sum或_count做平均 - 面板右上角「Legend」默认显示
{{instance}} {{job}}」,如需显示 PHP 版本或部署分支,应在 PHP 端注册指标时主动添加 label,例如$counter->inc(['GET', '/api', phpversion(), $_ENV['APP_ENV'] ?? 'prod'])
PHP 指标可视化真正的难点不在 Grafana 配置,而在于指标是否真实反映业务瓶颈——比如只统计“进入路由”次数,却忽略中间件异常中断、FPM worker crash 或 OPcache 编译失败,这些都不会出现在 http_requests_total 里。得结合 php-fpm.status、syslog 和错误日志交叉验证。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











