Telegraf nginx_upstream_check 输入插件实战:基于 Nginx 主动探测模块监控上游服务器健康状态
Telegraf 的 nginx_upstream_check 输入插件(自 Telegraf v1.10.0 引入)专门用于采集 Nginx 中由第三方 nginx_upstream_check 模块提供的上游服务器主动健康探测数据。该插件会定期拉取 Nginx 状态页的 JSON 响应,将每台上游服务器的存活/宕机状态、成功/失败探测计数转化为 Telegraf 指标。阅读本文后,你将掌握该插件的完整配置方法、指标与标签结构、示例输出格式,以及从源码层面理解其 HTTP 请求、JSON 解析与指标生成的完整调用链。
插件工作原理
Nginx 官方本身并不内置对 upstream 后端服务器的主动健康检查能力,而第三方 nginx_upstream_check 模块通过在 upstream 块中配置 check 指令,周期性地向各后端服务器发送配置好的请求(支持 http/tcp 等类型),并根据结果判定服务器可用性。该模块还会在 Nginx 中暴露一个状态查询入口(通过 check_status 指令启用),Telegraf 的 nginx_upstream_check 插件正是这个入口的消费方。
插件的工作流程可以概括为三步:
- 运维人员将 nginx_upstream_check 模块编译进 Nginx,在配置中为 upstream 块开启主动探测,并暴露一个返回 JSON 格式的状态页;
- Telegraf 按
interval周期向配置的url发起 HTTP 请求(默认GET,超时默认 5 秒); - 插件解析响应 JSON 中
servers.server数组的每一条记录,为每台上游服务器生成一条nginx_upstream_check测量值。
从源码结构看,插件主体 nginx_upstream_check.go 中的 Gather 方法是核心入口(第 62–83 行),它依次完成:惰性创建并复用 HTTP 客户端 → 解析状态页 URL → 调用 gatherStatusData 拉取并转换数据。
完整配置说明
以下是该插件的完整示例配置,与仓库中的 sample.conf 完全一致,可直接复制使用:
# Read nginx_upstream_check module status information (https://github.com/yaoweibin/nginx_upstream_check_module)
[[inputs.nginx_upstream_check]]
## An URL where Nginx Upstream check module is enabled
## It should be set to return a JSON formatted response
url = "http://127.0.0.1/status?format=json"
## You can also point it at a unix socket too
# url = "http+unix:///var/run/nginx.sock:/status?format=json"
## HTTP method
# method = "GET"
## Optional HTTP headers
# headers = {"X-Special-Header" = "Special-Value"}
## Override HTTP "Host" header
# host_header = "check.example.com"
## Timeout for HTTP requests
timeout = "5s"
## Optional HTTP Basic Auth credentials
# username = "username"
# password = "pa$$word"
## 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
核心参数详解
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url |
string | http://127.0.0.1/status?format=json |
必须指向 nginx_upstream_check 模块的状态页,且需返回 JSON 格式响应。支持 http+unix:// 前缀访问 Unix Socket(如 http+unix:///var/run/nginx.sock:/status?format=json) |
method |
string | GET |
HTTP 请求方法,源码中未设置时回退为 GET |
headers |
map | 空表 | 附加的 HTTP 请求头,逐条通过 Header.Add 写入请求 |
host_header |
string | 空(不覆盖) | 覆盖请求的 HTTP Host 头,用于 Nginx 按 server_name 虚拟主机路由的场景 |
timeout |
duration | 5s |
HTTP 请求超时;底层客户端在未设置时也会回退为 5 秒 |
username / password |
string | 空 | 配置后自动附加 HTTP Basic Auth 认证头 |
tls_ca / tls_cert / tls_key |
string | 空 | 标准 TLS 证书配置 |
insecure_skip_verify |
bool | false |
跳过 TLS 证书链与主机名校验 |
这些默认值可以从 newNginxUpstreamCheck 工厂函数 得到印证:URL 默认 http://127.0.0.1/status?format=json、Method 默认 GET、Timeout 默认 5s。插件结构体 NginxUpstreamCheck 还内嵌了 common_http.HTTPClientConfig,这意味着除示例中列出的参数外,该插件还继承了 Telegraf 通用 HTTP 客户端的完整能力,包括 OAuth2 认证、Cookie 认证、代理以及连接池调优(idle_conn_timeout、max_idle_conn 等),其定义见 plugins/common/http/config.go。
关于 Unix Socket 支持并非空话:通用 HTTP 客户端在 CreateClient 中显式注册了 http+unix / https+unix 协议处理器(config.go 第 82 行),因此 url = "http+unix:///var/run/nginx.sock:/status?format=json" 这类写法可以直接工作。
指标与标签结构
插件生成的测量值名称固定为 nginx_upstream_check,每台被探测的上游服务器生成一条指标。
字段(Fields)
| 字段 | 类型 | 说明 |
|---|---|---|
fall |
计数器(uint64) | 检查失败的累计次数 |
rise |
计数器(uint64) | 检查成功的累计次数 |
status |
字符串 | 服务器当前状态(up / down 等) |
status_code |
整型(uint8) | 状态码映射:1 - up,2 - down,0 - 其他 |
README 中特别指出 status_code 通常是最好用的字段:它允许你判断每一台服务器的当前状态并据此配置告警。虽然 InfluxDB 支持字符串字段,可以直接用 status,但大多数其他监控方案更适合使用整型代码。这个映射关系在源码中的实现非常直观——getStatusCode 函数 对 up 返回 1,对 down 返回 2,其余情况返回 0。
标签(Tags)
所有测量值都携带以下标签:
| 标签 | 说明 |
|---|---|
name |
上游服务器的主机名或 IP(含端口,形如 192.168.0.1:8080) |
port |
备用检查端口;使用默认端口时为 0 |
type |
检查类型,http 或 tcp |
upstream |
Nginx 配置中 upstream 块的名称 |
url |
Telegraf 实际使用的状态页 URL |
标签与字段的生成逻辑集中在 gatherStatusData 方法:它遍历 JSON 响应中 servers.server 数组的每一项,逐项构建标签表和字段表后调用 accumulator.AddFields("nginx_upstream_check", fields, tags) 写入指标。
示例输出
按 README 所述,运行以下命令:
./telegraf --config telegraf.conf --input-filter nginx_upstream_check --test
可以得到如下结果(--test 表示只执行一次采集并打印结果):
nginx_upstream_check,host=node1,name=192.168.0.1:8080,port=0,type=http,upstream=my_backends,url=http://127.0.0.1:80/status?format\=json fall=0i,rise=100i,status="up",status_code=1i 1529088524000000000
nginx_upstream_check,host=node2,name=192.168.0.2:8080,port=0,type=http,upstream=my_backends,url=http://127.0.0.1:80/status?format\=json fall=100i,rise=0i,status="down",status_code=2i 1529088524000000000
可以看到第一条指标对应一台健康的后端(rise=100i、status="up"、status_code=1i),第二条对应一台宕机的后端(fall=100i、status="down"、status_code=2i)。注意输出中的 url 标签对 = 做了反斜杠转义,这是 InfluxDB line protocol 对标签值中特殊字符的常规转义。
源码解析:一次采集的完整调用链
结合 nginx_upstream_check.go 的源码,一次完整采集的调用链如下:
- HTTP 客户端的惰性初始化:
Gather首次执行时调用createHTTPClient(第 86–95 行),通过内嵌的HTTPClientConfig.CreateClient构建带 TLS、代理、超时等设置的*http.Client并缓存到check.client,后续采集周期复用,避免重复建连; - 请求构造与发送:gatherJSONData 方法 按配置确定 HTTP 方法(默认
GET),依次附加 Basic Auth、自定义请求头与Host头后发出请求; - 错误处理细节:若响应状态码非 200,插件会读取响应体前 200 字节(
io.LimitReader(response.Body, 200))拼入错误信息返回,便于排查状态页 404/500 等问题(第 127–131 行); - JSON 解码与映射:响应体解码到
nginxUpstreamCheckData结构,其内部镜像了状态页 JSON 的servers→server<a href="https://link.gitcode.com/i/02464b3e694b222241de2341d5af391c" target="_blank">]结构,包含upstream、name、status、rise、fall、type、port等字段([第 39–56 行),随后逐条转换为 Telegraf 指标。
测试用例对行为的验证
仓库自带的测试文件 nginx_upstream_check_test.go 用 httptest 模拟了 Nginx 状态页,覆盖了上述行为:
TestNginxUpstreamCheckData(第 44–102 行):构造含两台服务器(一台up/http,一台down/tcp且使用备用端口 8080)的 JSON 响应,断言生成的标签(upstream、type、name、port、url)与字段(status、status_code、rise、fall)与预期完全一致,其中status_code按up→1、down→2映射;TestNginxUpstreamCheckRequest(第 104–154 行):在模拟服务端的处理函数中校验Method=POST、自定义请求头X-Test、Basic Auth 生成的Authorization: Basic头以及Host: status.local均被正确发送到请求上,验证了method、headers、username/password、host_header四个参数确实生效。
前置条件与使用限制
使用该插件需要满足以下前提,否则采集会失败:
- Nginx 必须编译并加载 nginx_upstream_check 模块,并在
upstream块中配置主动探测指令(如检查间隔、连续成功/失败阈值、检查类型 http/tcp);插件本身不发起对后端服务器的探测,只读取模块统计的结果,探测策略由 Nginx 侧决定; - 状态页必须返回 JSON 格式,因此 URL 通常携带
?format=json之类的查询参数(具体参数形式以所安装模块版本为准); - 注意状态页暴露面:状态页包含完整的上游拓扑信息,建议仅允许受信任地址(如本机)访问,Telegraf 侧可配合
username/passwordBasic Auth 进一步加固; - 该插件的采集频率由 Telegraf 的全局
interval(或插件级interval)控制,它反映的是模块计数器在每个采集周期的快照;rise/fall为模块内部累计值,如需"每周期新增失败次数",可结合first/diff等聚合器或下游查询处理。
更多通用插件配置(如字段/标签过滤、别名、pass/name_override 等)参见 CONFIGURATION.md,插件源码与示例配置分别位于 nginx_upstream_check.go 和 sample.conf,官方说明见 插件 README。
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