Telegraf phpfpm 输入插件:通过 HTTP、Unix Socket 与 FastCGI 三种模式采集 PHP-FPM 运行指标
本文围绕 Telegraf 的 phpfpm 输入插件,完整讲解其三种采集模式(HTTP 状态页、Unix socket、FastCGI/TCP 直连)、全部配置参数、指标与标签体系,以及 JSON 扩展指标(phpfpm_process)的生成逻辑。读完你可以为任意部署形态的 PHP-FPM(含 Nginx 反向代理、裸 socket、TCP 监听)配置出可复制可用的采集方案,并能从源码层面理解插件的地址解析、glob 匹配、FastCGI 协议交互与指标解析细节。
插件概览
phpfpm 插件采集 PHP FastCGI Process Manager 的运行时统计信息,数据源可以是 FPM 的 HTTP 状态页(status page),也可以是 FPM 的 socket 本身。插件自 Telegraf v0.1.10 引入,适用于所有平台,分类标签为 server、web。
从源码结构看,插件的核心实现在 plugins/inputs/phpfpm/phpfpm.go。Gather 方法会对 urls 中的每个地址并发启动一个 goroutine 采集(见 phpfpm.go#L120-L133),任一地址失败只通过 acc.AddError 上报错误,不会中断其他地址的采集——这意味着混合配置多个地址时,单点故障不影响整体监控。
地址到采集方式的映射在 gatherServer 中完成(见 phpfpm.go#L136-L184),按前缀分派为三条路径:
http:///https://前缀 → 走标准 HTTP GET 请求拉取状态页;fcgi:///cgi://前缀 → 走 TCP 连接 + FastCGI 协议直连 FPM;- 其他(无 scheme 的裸路径)→ 视为本地 Unix socket 路径,同样通过 FastCGI 协议通信。
配置说明
以下是插件完整的示例配置(与 sample.conf 一致):
# Read metrics of phpfpm, via HTTP status page or socket
[[inputs.phpfpm]]
## An array of addresses to gather stats about. Specify an ip or hostname
## with optional port and path
##
## Plugin can be configured in three modes (either can be used):
## - http: the URL must start with http:// or https://, ie:
## "http://localhost/status"
## "http://192.168.130.1/status?full"
##
## - unixsocket: path to fpm socket, ie:
## "/var/run/php5-fpm.sock"
## or using a custom fpm status path:
## "/var/run/php5-fpm.sock:fpm-custom-status-path"
## glob patterns are also supported:
## "/var/run/php*.sock"
##
## - fcgi: the URL must start with fcgi:// or cgi://, and port must be present, ie:
## "fcgi://10.0.0.12:9000/status"
## "cgi://10.0.10.12:9001/status"
##
## Example of multiple gathering from local socket and remote host
## urls = ["http://192.168.1.20/status", "/tmp/fpm.sock"]
urls = ["http://localhost/status"]
## Format of stats to parse, set to "status" or "json"
## If the user configures the URL to return JSON (e.g.
## http://localhost/status?json), set to JSON. Otherwise, will attempt to
## parse line-by-line. The JSON mode will produce additional metrics.
# format = "status"
## Duration allowed to complete HTTP requests.
# timeout = "5s"
## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
# tls_key = "/etc/telegraf/key.pem"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
插件还支持 Telegraf 的全局插件配置选项(如指标/标签/字段过滤、别名、插件排序等),详见 CONFIGURATION.md。
urls:三种模式的地址写法
urls 是一个地址数组,可同时混写不同模式,例如 urls = ["http://192.168.1.20/status", "/tmp/fpm.sock"] 会同时从远程 HTTP 主机和本地 socket 采集。三种模式的要点:
- http 模式:URL 必须以
http://或https://开头,路径通常指向 FPM 状态页,例如http://localhost/status。查询参数可以保留(如?full、?json),HTTP 模式会原样请求该 URL。 - unixsocket 模式:直接写 FPM 的 socket 路径,例如
/var/run/php5-fpm.sock。可用socket路径:自定义状态路径的写法指定非默认的状态路径(/var/run/php5-fpm.sock:fpm-custom-status-path),并支持 glob 通配(/var/run/php*.sock)。使用此模式时,Telegraf 必须运行在 FPM 所在的同一台主机上,且运行 Telegraf 的用户须能访问该 socket。 - fcgi 模式:URL 必须以
fcgi://或cgi://开头,且必须带端口,例如fcgi://10.0.0.12:9000/status。这对应 FPM 以 TCP 方式监听(listen = 127.0.0.1:9000)的部署形态,无需经过 Web 服务器。
从源码看,expandUrls 负责地址预处理(见 phpfpm.go#L344-L394):
- 以
http://、https://、fcgi://、cgi://开头的地址被判定为网络 URL,原样使用; - 其余地址交给 globpath 编译为 glob 模式并对本地文件系统做匹配。若匹配结果为空会报错
socket doesn't exist;若地址带:状态路径后缀,该后缀会在每个匹配到的 socket 路径上重新拼接; - unixsocket 模式下若未指定状态路径,默认使用
status(见 phpfpm.go#L171-L177)。
另外,Init 中当 urls 为空时会回退到默认值 http://127.0.0.1/status,且 format 为空时默认解析为 status 格式(见 phpfpm.go#L92-L118)。
format:status 与 json
format 取值 status 或 json:
status(默认):状态页返回的文本按行解析,只产生phpfpm指标;json:将 URL 配置为返回 JSON(例如http://localhost/status?json或?full&json),除phpfpm指标外,还会为每个 FPM 子进程产生phpfpm_process指标。
两种格式对应的解析入口在 importMetric 中分派(见 phpfpm.go#L231-L238):json 走 parseJSON,其余走 parseLines。仓库中的测试样例 testdata/phpfpm.json 展示了 JSON 状态页的真实结构:顶层含 pool、accepted conn、processes 等字段,processes 数组中每个进程带 pid、state、requests、last request cpu、last request memory 等键,与下文 phpfpm_process 指标一一对应。
timeout 与 TLS 配置
timeout(默认5s):HTTP 模式下作为http.Client的整体请求超时(见 phpfpm.go#L111-L116);fcgi/unixsocket 模式下则用于连接超时与连接读写 deadline(见 fcgi_client.go#L13-L45)。tls_ca/tls_cert/tls_key/insecure_skip_verify:可选 TLS 配置,仅对https://地址生效,底层是通用的 tls.ClientConfig。
指标说明
phpfpm 指标
标签:pool(FPM 池名)、url(采集地址,即 urls 中的原始条目)。
字段(均为计数值):
| 字段 | 含义 |
|---|---|
accepted_conn |
已接受的连接总数 |
listen_queue |
当前监听队列中的连接数 |
max_listen_queue |
监听队列达到过的最大长度 |
listen_queue_len |
监听队列长度(backlog) |
idle_processes |
空闲进程数 |
active_processes |
正在处理请求的进程数 |
total_processes |
进程总数 |
max_active_processes |
历史最大并发进程数 |
max_children_reached |
达到 max_children 上限的次数 |
slow_requests |
慢请求次数(超过 request_slowlog_timeout 的请求) |
phpfpm_process 指标(仅 JSON 模式)
标签:pool、url、user、request_method、request_uri、script(即每个进程最近一次请求的方法、URI、脚本名)。
字段:
| 字段 | 含义 |
|---|---|
pid |
进程 PID |
state |
进程状态(如 Running、Idle) |
start_time |
进程启动时间戳 |
start_since |
进程启动以来的秒数(在 phpfpm 指标上体现) |
requests |
该进程已处理的请求数 |
request_duration |
最近一次请求耗时 |
content_length |
请求体长度 |
last_request_cpu |
最近一次请求消耗的 CPU 时间(浮点) |
last_request_memory |
最近一次请求消耗的内存(字节,浮点) |
从源码结构看,phpfpm 指标字段由 parseLines/parseJSON 分别生成:文本模式仅提取 10 个以 pool: 行分隔的整数字段,键名中的空格会被替换为下划线(如 accepted conn → accepted_conn,见 phpfpm.go#L280-L291);JSON 模式则额外输出 start_since 字段和 phpfpm_process 明细指标(见 phpfpm.go#L294-L342)。
示例输出
status 格式的典型输出:
phpfpm,pool=www accepted_conn=13i,active_processes=2i,idle_processes=1i,listen_queue=0i,listen_queue_len=0i,max_active_processes=2i,max_children_reached=0i,max_listen_queue=0i,slow_requests=0i,total_processes=3i 1453011293083331187
phpfpm,pool=www2 accepted_conn=12i,active_processes=1i,idle_processes=2i,listen_queue=0i,listen_queue_len=0i,max_active_processes=2i,max_children_reached=0i,max_listen_queue=0i,slow_requests=0i,total_processes=3i 1453011293083691422
phpfpm,pool=www3 accepted_conn=11i,active_processes=1i,idle_processes=2i,listen_queue=0i,listen_queue_len=0i,max_active_processes=2i,max_children_reached=0i,max_listen_queue=0i,slow_requests=0i,total_processes=3i 1453011293083691658
注意不同 pool 各产生一条独立的 phpfpm 指标(文本状态页中每个 pool 段落都被 parseLines 归入独立的 pool 标签)。
JSON 模式下会额外产生进程级明细:
phpfpm,pool=www,url=http://127.0.0.1:44637?full&json accepted_conn=3879i,active_processes=1i,idle_processes=9i,listen_queue=0i,listen_queue_len=0i,max_active_processes=3i,max_children_reached=0i,max_listen_queue=0i,slow_requests=0i,start_since=4901i,total_processes=10i
phpfpm_process,pool=www,request_method=GET,request_uri=/fpm-status?json&full,script=-,url=http://127.0.0.1:44637?full&json,user=- content_length=0i,pid=583i,last_request_cpu=0,last_request_memory=0,request_duration=159i,requests=386i,start_time=1702044927i,state="Running"
phpfpm_process,pool=www,request_method=GET,request_uri=/index.php,script=script.php,url=http://127.0.0.1:44637?full&json,user=- content_length=0i,pid=585i,last_request_cpu=104.93,last_request_memory=2097152,request_duration=9530i,requests=389i,start_time=1702044927i,state="Idle"
从示例可见 last_request_cpu 为浮点(如 104.93),last_request_memory 以字节计(2097152 即 2 MiB),state 为字符串标签值。
FastCGI 直连的实现细节
fcgi/TCP 与 unixsocket 两种模式共用同一套内置的 FastCGI 客户端,源码分布在三个文件中:
- fcgi.go:实现 FastCGI 协议的原始记录层——
header结构、记录读写(record.read/conn.writeRecord)、参数键值对编码(writePairs),以及分块流写入器streamWriter(单条记录体最大maxWrite = 65535字节,超出自动分段); - fcgi_client.go:
newFcgiClient负责建立连接——参数为int时按tcp拨号(对应fcgi:///cgi://模式),为string时按unixsocket 拨号(对应 unixsocket 模式),并在设置了timeout时同时施加连接超时和 I/O deadline;conn.request则发出BEGIN_REQUEST+PARAMS记录,然后循环读取STDOUT/STDERR记录直到收到END_REQUEST或流结束; - child.go:提供
roleResponder等协议常量的配套定义(源自 Go 标准库风格的 FastCGI 实现移植)。
具体到状态页请求,gatherFcgi(见 phpfpm.go#L186-L203)会构造一组模拟 Web 服务器转发的环境变量(SCRIPT_NAME、REQUEST_METHOD=GET、SERVER_PROTOCOL=HTTP/1.0 等)作为 FastCGI 参数发出,FPM 收到后直接返回状态页内容,因此无需经过 Nginx/Apache 等反向代理。fcgi 模式下若 URL 未写路径(或路径仅为 /),默认使用 status 作为状态路径。
fcgi:// 地址的解析有严格校验:host 必须形如 地址:端口,端口必须可解析为整数,否则报错(见 phpfpm.go#L148-L162)。
测试验证与已知限制
phpfpm_test.go 对该插件做了端到端验证,与上文各功能点一一对应:
TestPhpFpmGeneratesMetrics_From_Http:用httptest服务器模拟状态页,断言生成的phpfpm指标各字段值(accepted_conn、listen_queue等)与pool/url标签;TestPhpFpmGeneratesJSONMetrics_From_Http:以Format: "json"采集,并与 testdata/expected.out 同源的期望指标集比对,覆盖phpfpm_process明细;TestPhpFpmGeneratesMetrics_From_Fcgi/TestPhpFpmGeneratesMetrics_From_Socket:分别在 TCP 端口和/tmp下的 Unix socket 上启动fcgi.Serve模拟 FPM,验证两种直连模式;TestPhpFpmGeneratesMetrics_From_Multiple_Sockets_With_Glob:创建两个 socket 后用"/tmp/test-fpm[\\-0-9]*.sock"这类 glob 模式一次匹配两个地址,验证每个匹配 socket 都按独立url标签产出指标;TestPhpFpmTimeout_From_Fcgi:验证服务端无响应时timeout生效(无指标产出且耗时不小于超时值);TestPhpFpmCrashWithTimeout_From_Fcgi:回归测试——端口无人监听且启用 timeout 时不再触发空指针崩溃。
需要注意的平台限制:测试文件带有 //go:build !windows 约束并附 TODO 说明(见 phpfpm_test.go#L1-L4),即 Unix socket 相关测试目前仅在非 Windows 平台运行;插件本身的 fcgi 客户端对 unix socket 的拨号也依赖 net.DialUnix,Windows 上的 unixsocket 模式可用性与平台支持情况应结合实际环境验证。
适用场景小结
- 生产环境通常经 Nginx/Apache 暴露状态页 → 用
http://(或https://+ TLS 配置)模式; - Telegraf 与 FPM 同机、且 FPM 监听 socket → 用 unixsocket 模式(支持 glob 批量采集多个 FPM 实例),需保证运行用户对 socket 有访问权限;
- FPM 以
listen = IP:port方式暴露 FastCGI → 用fcgi://或cgi://模式直连,省去状态页中转; - 需要进程级观测(每个 worker 的 CPU、内存、状态、请求数)→ 将 URL 指向
?full&json形式的 JSON 状态页并设置format = "json"。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python670
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#230
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52874
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351