Telegraf Zookeeper 输入插件实战:通过 mntr 命令采集 ZooKeeper 运行指标
Telegraf 的 inputs.zookeeper 插件通过 ZooKeeper 四字母命令 mntr(monitoring)从一台或多台 ZooKeeper 服务端采集运行状态指标,涵盖延迟、连接数、znode 数量、文件描述符水位等关键健康数据。本文完整覆盖该插件的配置参数、mntr 采集机制与指标结构,并结合源码解析其字段解析逻辑、TLS 选项与超时行为,读完即可在生产环境中独立完成部署、排障与指标定制。
工作原理:一次简单的四字母命令
该插件的采集机制非常简单直接:对每台配置的服务器建立 TCP 连接,写入 mntr 并换行,然后逐行读取响应。每一行形如 zk_xxx 值,插件将其转换为 Telegraf 指标。
从源码 zookeeper.go 可以看到核心流程(gatherServer 方法):
- 若
servers中的地址未带端口,自动补:2181; - 使用带超时的
context发起拨号(配置了 TLS 时走tls.DialWithDialer,否则走普通 TCP); - 写入
mntr\n,用bufio.Scanner逐行读取; - 用正则
^zk_(\w[\w\.\-]*)\s+([\w\.\-]+)匹配每行,提取字段名(去掉zk_前缀)与值; zk_server_state一行比较特殊:其值不作为字段,而是提取为指标的state标签;- 其余行按“先 int、再 float(可选)、最后 string”的顺序解析后写入
zookeeper指标。
插件在 plugins/inputs/all 中注册,插件名为 zookeeper,即配置节为 [[inputs.zookeeper]]。
注意:如果 ZooKeeper 已启用 Prometheus Metric provider,官方建议直接使用 prometheus 输入插件 抓取
http://<ip>:7000/metrics端点,而不是本插件。两者取其一即可,避免重复采集。
配置说明
完整示例如下(与 sample.conf 一致):
# Reads 'mntr' stats from one or many zookeeper servers
[[inputs.zookeeper]]
## An array of address to gather stats about. Specify an ip or hostname
## with port. ie localhost:2181, 10.0.0.1:2181, etc.
## If no servers are specified, then localhost is used as the host.
## If no port is specified, 2181 is used
servers = [":2181"]
## Timeout for metric collections from all servers. Minimum timeout is "1s".
# timeout = "5s"
## Float Parsing - the initial implementation forced any value unable to be
## parsed as an int to be a string. Setting this to "float" will attempt to
## parse float values as floats and not strings. This would break existing
## metrics and may cause issues if a value switches between a float and int.
# parse_floats = "string"
## Optional TLS Config
## Set to true/false to enforce TLS being enabled/disabled. If not set,
## enable TLS only if any of the other options are specified.
# tls_enable =
## Trusted root certificates for server
# tls_ca = "/path/to/cafile"
## Used for TLS client certificate authentication
# tls_cert = "/path/to/certfile"
## Used for TLS client certificate authentication
# tls_key = "/path/to/keyfile"
## Password for the key file if it is encrypted
# tls_key_pwd = ""
## Send the specified TLS server name via SNI
# tls_server_name = "kubernetes.example.com"
## Minimal TLS version to accept by the client
# tls_min_version = "TLS12"
## List of ciphers to accept, by default all secure ciphers will be accepted
## Use "all", "secure" and "insecure" to add all support ciphers, secure
## suites or insecure suites respectively.
# tls_cipher_suites = ["secure"]
## Renegotiation method, "never", "once" or "freely"
# tls_renegotiation_method = "never"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
servers:采集目标地址
- 类型为字符串数组,元素为
host:port,如localhost:2181、10.0.0.1:2181; - 省略
servers时,Init() 中默认填充[":2181"](即本机 2181 端口); - 地址中省略端口时,
gatherServer会自动追加:2181; - 多个服务器在同一个采集周期内逐个拨号,单个服务器的失败只会通过
acc.AddError记录错误,不影响其他服务器的采集。
timeout:采集超时
- 作用于“所有服务器的指标采集”整体流程:
Gather创建一个带超时的context,拨号与读写均受该 deadline 约束; - 源码中存在一个容易忽略的细节:若配置值小于 1 秒,
Init()会将其重置为 5 秒(源码注释中声明的最小值为"1s",默认值为"5s")。因此配置timeout = "500ms"不会得到 500ms 超时,而是会得到 5s。
parse_floats:浮点值的类型策略
这是本插件历史上最重要的兼容性开关,源码中的解析顺序是:先尝试 ParseInt;若失败且 parse_floats = "float",再尝试 ParseFloat;最后回退为字符串。
"string"(默认):任何无法解析为整数的值都存为字符串。例如新版 ZooKeeper 的zk_avg_latency输出为0.0这类浮点格式时,avg_latency字段将是字符串"0.0";"float":会额外尝试按浮点数解析,avg_latency变为 float 字段。
README 明确警告:该开关会改变既有指标的类型,若某个值在 float 与 int 之间切换还可能导致数据类型不一致问题,已有下游消费(如 InfluxQL 类型推断)时应谨慎切换。测试用例 zookeeper_test.go 正是用真实 ZooKeeper 容器验证了这一点:默认模式下断言 avg_latency 为字符串字段,ParseFloats: "float" 时断言为 float 字段。
TLS 选项
该插件内嵌了 Telegraf 通用的 common_tls.ClientConfig,因此支持完整的客户端 TLS 配置:
tls_enable:显式强制启用/禁用 TLS。不设置时,只要配置了任一其他 TLS 选项(如证书)即自动启用;tls_ca/tls_cert/tls_key/tls_key_pwd:CA、客户端证书与私钥路径,私钥可带加密密码;tls_server_name:SNI 中发送的服务端名称;tls_min_version:客户端接受的最低 TLS 版本(如TLS12);tls_cipher_suites:可用all、secure、insecure宏批量启用,也可指定具体算法套件;tls_renegotiation_method:never(默认)/once/freely,取值非法时 TLSConfig() 会返回错误使插件初始化失败;insecure_skip_verify:跳过证书链与主机名校验,仅建议调试使用。
注意:TLS 是针对客户端拨号链路的传输加密(4lw 命令直连场景),并非 ZooKeeper 客户端协议层(clientCnxnSocket 的 SASL/TLS)——本插件只发四字母命令,不走 ZooKeeper 客户端 API。
前置条件:mntr 命令必须在白名单中
四字母命令(4lw commands)自 ZooKeeper 3.5 起默认被禁用,必须在服务端开启白名单,否则 mntr 无响应。仓库中的集成测试 zookeeper_test.go 就通过容器环境变量显式开启了它:
Env: map[string]string{
"ZOO_4LW_COMMANDS_WHITELIST": "mntr",
},
对应到实际部署,即 ZooKeeper 的 zoo.cfg / 容器环境变量中需要:
zookeeper.4lw.commands.whitelist=mntr
这是本插件最常见的“采不到数据”原因,排查时应优先确认。
排障:用 netcat 直接验证 mntr 输出
官方 README 给出的排障手段是绕开 Telegraf、直接对 ZooKeeper 端口发命令:
$ echo mntr | nc localhost 2181
zk_version 3.4.9-3--1, built on Thu, 01 Jun 2017 16:26:44 -0700
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 8
zk_packets_sent 7
zk_num_alive_connections 1
zk_outstanding_requests 0
zk_server_state standalone
zk_znode_count 129
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 10044
zk_open_file_descriptor_count 44
zk_max_file_descriptor_count 4096
根据 zookeeper.go 的解析逻辑,可以进一步推断两类典型故障的表象:
- 连接建立但读取为空:通常是
mntr未加入白名单,或防火墙只放行部分四字母命令; unexpected line in mntr response: "..."错误:某一行不符合zk_字段名 值的格式(例如输出被其他日志污染),该行会直接导致该服务器的本次采集报错——这也能提醒:不要在同一端口上混入其他会打印日志的服务。
此外,源码中对 zk_server_state 的处理意味着:即使所有数值字段正常,若缺少 zk_server_state 行,state 标签会为空字符串,监控告警中若按 state=standalone 过滤会匹配不到数据。
仓库还附带了本地开发调试环境 dev/docker-compose.yml 与 dev/telegraf.conf,用 zookeeper 官方镜像 + 每秒采集间隔、输出到 stdout 的 outputs.file,适合快速验证插件行为:
services:
zoo:
image: zookeeper
telegraf:
image: glinton/scratch
volumes:
- ./telegraf.conf:/telegraf.conf
- ../../../../telegraf:/telegraf
depends_on:
- zoo
entrypoint:
- /telegraf
- --config
- /telegraf.conf
network_mode: service:zoo
指标结构与输出示例
字段名直接来自 ZooKeeper 的 mntr 响应,会随版本、平台与配置不同而变化。完整字段清单如下(来自 README):
- 指标名:
zookeeper - 标签:
server(主机名,缺省为localhost)port(端口)state(来自zk_server_state,如standalone)
- 字段:
approximate_data_size(integer)avg_latency(integer)ephemerals_count(integer)max_file_descriptor_count(integer)max_latency(integer)min_latency(integer)num_alive_connections(integer)open_file_descriptor_count(integer)outstanding_requests(integer)packets_received(integer)packets_sent(integer)version(string)watch_count(integer)znode_count(integer)followers(integer, 仅 leader 输出)synced_followers(integer, 仅 leader 输出)pending_syncs(integer, 仅 leader 输出)
Line 协议格式的输出示例:
zookeeper,server=localhost,port=2181,state=standalone ephemerals_count=0i,approximate_data_size=10044i,open_file_descriptor_count=44i,max_latency=0i,packets_received=7i,outstanding_requests=0i,znode_count=129i,max_file_descriptor_count=4096i,version="3.4.9-3--1",avg_latency=0i,packets_sent=6i,num_alive_connections=1i,watch_count=0i,min_latency=0i 1522351112000000000
两个使用注意点:
- 字段类型:上例中
avg_latency为 integer 是因为该示例来自整数值;若服务端返回0.0且未设置parse_floats = "float",该字段实际会是字符串(见“配置说明”一节)。做类型敏感的下游查询前,建议先确认实际字段类型; - leader 专属字段:
followers、synced_followers、pending_syncs只出现在 leader 节点上,follower 的mntr响应中不存在这些键。因此按字段做告警时要意识到 follower 节点永远没有该字段,应结合state标签区分角色。
全局配置能力
与其他输入插件一致,<a href="https://link.gitcode.com/i/eab17efdb1982bc5e94cef55d05833ae" target="_blank">[inputs.zookeeper]] 还支持 Telegraf 的全局插件配置能力:字段/标签过滤(namepass/nameprefix/fieldpass 等)、插件别名、排序、自定义 tags 等。详见 [CONFIGURATION.md 中的插件通用配置章节。
小结
inputs.zookeeper 插件以极小的开销提供了 ZooKeeper 集群的可观测性基线:一个四字母命令换回十余个健康字段,配合 state/server/port 标签即可对多节点集群做延迟、连接数与文件描述符水位的持续监控。落地时的检查清单是:确认服务端 zookeeper.4lw.commands.whitelist 包含 mntr、确认 servers 与 timeout 配置、按下游需求决定 parse_floats、需要跨网络加密时启用内置 TLS 选项,并牢记若已启用 Prometheus provider 则优先使用 prometheus 插件。
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