Telegraf Nagios 数据格式解析器(Nagios Parser)使用指南:采集监控插件输出与性能数据
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
nagios是 Telegraf 内置的一种输入数据格式(data format),用于直接解析 Nagios 监控插件的标准输出,包括服务状态文本(service output)与管道符(|)分隔的性能数据(performance data)。本文以 plugins/parsers/nagios/README.md 为骨架,结合仓库内 parser.go 源码与 parser_test.go 测试用例,完整讲解配置方式、输出格式规范、生成度量结构、阈值解析规则以及退出码状态映射,帮助你在一套监控体系内直接复用海量现成的 Nagios 插件。
一、Nagios 数据格式是什么
Nagios 插件遵循一套统一的命令行输出约定(即 Nagios Plugin API):插件以人类可读文本汇报服务状态,并通过管道符|之后追加机器可读的性能数据。Telegraf 的nagios解析器正是读取这段输出,将其中的性能数据转换成时序度量(metrics),并把状态文本与退出码映射成一条名为nagios_state的状态度量。
该解析器在仓库中注册名称为nagios,注册逻辑位于 parser.go:
func init() { // Register parser parsers.Add("nagios", func(defaultMetricName string) telegraf.Parser { return &Parser{metricName: defaultMetricName} }, ) }在标准构建中,它通过 plugins/parsers/all/nagios.go 被默认注册(使用自定义构建时可用parsers.nagios标签按需引入)。
二、配置方法:结合 inputs.exec 使用
Nagios 插件本质上是可执行程序,因此 Telegraf 中最典型的接入方式是配合inputs.exec插件调用,并把data_format设为nagios。原文档给出了完整的最小配置:
[[inputs.exec]] ## Commands array commands = ["/usr/lib/nagios/plugins/check_load -w 5,6,7 -c 7,8,9"] ## Data format to consume. ## Each data format has its own unique set of configuration options, read ## more about them here: ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md data_format = "nagios"inputs.exec会周期性执行commands中列出的命令,并把标准输出交给nagios解析器处理。结合 exec.go 的源码可以看到,当 exec 插件检测到解析器是*nagios.Parser时,会额外挂载一个退出码处理钩子:
func (e *Exec) SetParser(parser telegraf.Parser) { e.parser = parser unwrapped, ok := parser.(*models.RunningParser) if ok { if _, ok := unwrapped.Parser.(*nagios.Parser); ok { e.exitCodeHandler = func(metrics []telegraf.Metric, err error, msg []byte) []telegraf.Metric { return nagios.AddState(err, msg, metrics) } e.parseDespiteError = true } } }这意味着两点:
- 即使插件以非零退出码结束,exec 也会继续解析其输出(
parseDespiteError = true),而不是直接丢弃; - 命令的退出码会被
nagios.AddState转换成nagios_state度量中的state字段(详见下文第六节)。
三、Nagios 插件输出格式规范
要正确使用该解析器,需要了解 Nagios 插件的标准输出结构。其单行输出格式为:
TEXT_OUTPUT|PERFDATA- 管道符左侧是服务状态文本(如
PING OK - Packet loss = 0%, RTA = 0.30 ms); - 管道符右侧是零个或多个性能数据项,各项之间用空格分隔,每项形如:
'label'=value[UOM];[warn];[crit];[min];[max]以check_disk类插件的典型输出为例(该样例同时出现在 parser_test.go 中):
DISK OK - free space: / 3326 MB (56%); | /=2643MB;5948;5958;0;5968 / 15272 MB (77%); /boot 68 MB (69%); /home 69357 MB (27%); /var/log 819 MB (84%); | /boot=68MB;88;93;0;98 /home=69357MB;253404;253409;0;253414 /var/log=818MB;970;975;0;980该样例展示了 Nagios 输出的另外两个特性:
- 多行长输出(long output):状态文本之后可跟多行详细说明,解析器会将其合并到
long_service_output字段; - 额外的性能数据区:长输出结束后可再次出现
|,其后的内容同样作为性能数据解析。
解析器通过两个正则表达式完成切分与字段提取(见 parser.go):
perfSplitRegExp = regexp.MustCompile(`([^=]+=\S+)`) nagiosRegExp = regexp.MustCompile( `^([^=]+)=([\d\.\-\+eE]+)([\w\/%]*);?([\d\.\-\+eE:~@]+)?;?([\d\.\-\+eE:~@]+)?;?([\d\.\-\+eE]+)?;?([\d\.\-\+eE]+)?;?\s*`, )perfSplitRegExp负责把整段性能数据按label=value...拆分成独立项;nagiosRegExp负责从每个项中依次提取:标签(组1)、数值(组2)、单位 UOM(组3)、警告阈值(组4)、严重阈值(组5)、最小值(组6)、最大值(组7)。
四、解析生成的度量结构与字段
对于每个性能数据项,解析器会生成一条名为nagios的度量;对于整段插件输出,则额外生成一条名为nagios_state的状态度量。
性能度量nagios
由 parsePerfData 生成,字段结构如下:
| 类别 | 键 | 说明 |
|---|---|---|
| 标签 | perfdata | 性能数据标签(如rta、pl、load1),会去除两侧单引号 |
| 标签 | unit | 单位(如ms、%、MB),无单位时该标签不存在 |
| 字段 | value | 解析出的数值(浮点数) |
| 字段 | warning_lt/warning_gt | 普通警告阈值解析出的下界/上界 |
| 字段 | warning_le/warning_ge | @语义(区间内告警)的警告阈值 |
| 字段 | critical_lt/critical_gt | 普通严重阈值解析出的下界/上界 |
| 字段 | critical_le/critical_ge | @语义的严重阈值 |
| 字段 | min/max | 性能数据中的最小/最大值 |
以测试用例 valid output 1 中的rta项为例:
rta=0.298000ms;4000.000000;6000.000000;0.000000生成的度量等价于:
nagios,perfdata=rta,unit=ms value=0.298,warning_lt=0,warning_gt=4000,critical_lt=0,critical_gt=6000,min=0几点细节值得注意:
- 若性能值本身为
U(undetermined,未确定),解析会直接返回错误"value undetermined"(parser.go); - 格式损坏的性能项会被静默跳过(仅记录日志),不会导致整条输出解析失败——测试用例
malformed perf data验证了这一点(parser_test.go); - 标签中的单引号会被去除,例如
'load1'=0.00解析出的perfdata标签值为load1(见 valid output 4)。
状态度量nagios_state
由Parse主流程(parser.go)生成,字段如下:
| 字段 | 说明 |
|---|---|
service_output | 管道符左侧的状态文本(去除首尾空白) |
long_service_output | 多行长输出的合并文本(多行之间用换行符连接,仅当存在长输出时才出现) |
state | 插件退出码映射的状态值(0~3),由 exec 插件的退出码处理钩子补充 |
例如PING OK样例生成的状态度量:
nagios_state service_output="PING OK - Packet loss = 0%, RTA = 0.30 ms",long_service_output="This is a long output\nwith three lines"五、阈值格式解析规则
Nagios 插件的阈值支持多种格式(对应 nagios-plugins.org 的 Threshold format 规范),parseThreshold 完整实现了这些情况,并返回(vmin, vmax)一对边界值:
| 阈值写法 | 含义 | 解析结果 |
|---|---|---|
10 | 只有上界,下界隐含为 0 | (0, 10) |
10: | 下界为 10,上界无限制 | (10, MaxFloat64) |
~:10 | 下界无限制(~代表负无穷),上界为 10 | (MinFloat64, 10) |
10:20 | 完整区间 | (10, 20) |
10:20:30 | 非法格式(含两个冒号) | 返回ErrBadThresholdFormat |
其中MaxFloat64与MinFloat64在源码中以常量形式定义(parser.go),用于表示无限边界。对应的单测 TestParseThreshold 覆盖了上述全部情况。
此外,阈值中带@前缀时表示"反向"区间语义(落在区间内才告警),解析器会据此将阈值写入*_le/*_ge字段;普通阈值则写入*_lt/*_gt字段。valid output 4中的'load1'=0.00;~:4;@0:6;0;即为典型示例(parser_test.go):
load1: warning_lt=MinFloat64, warning_gt=4, critical_le=0, critical_ge=6, min=0六、退出码与 state 状态字段
Nagios 插件通过退出码表达服务状态,标准定义如下(来源:Nagios Plugin API "Plugin Return Codes"):
| 退出码 | 状态 | 含义 |
|---|---|---|
| 0 | OK | 正常 |
| 1 | WARNING | 警告 |
| 2 | CRITICAL | 严重 |
| 3 | UNKNOWN | 未知 |
Telegraf 将这一语义落到nagios_state度量的state字段上。实现位于 AddState 与 getExitCode:
- 命令正常结束(无错误)时
state = 0; - 命令以非零码退出时,从
*exec.ExitError中取出真正的进程退出码(通过syscall.WaitStatus的ExitStatus()); - 任何异常情况(错误类型不对、退出码越界、解析不出退出码)都会回退为 UNKNOWN,即
state = 3; - 当状态为 UNKNOWN 时,错误信息会被写入
service_output字段(若原输出为空),确保度量本身包含了可排障的信息。
源码注释特别说明:这里"不抛出错误"是有意设计——错误信息会随service_output输出,用户可在查询结果中直接看到失败原因。
exec插件在 processCommand 中调用该钩子:即使命令失败也解析输出,随后用exitCodeHandler补齐state字段。相关行为在 TestTryAddState 中被验证,例如"非可解析错误 → state=3 且 service_output 为错误文本"、"正常执行 → state=0 追加到已有度量"等场景。
七、完整解析流程与多行处理
从源码主流程(Parse)可以梳理出完整的解析步骤:
- 逐行扫描输出,取第一行按
|切分; - 若存在性能数据部分,调用
parsePerfData生成nagios度量; - 将管道符左侧内容存入
service_output; - 继续读取后续行作为长输出,合并到
long_service_output; - 若长输出中再次出现
|,其右侧内容也按性能数据解析(对应check_disk的多段 perfdata 场景); - 最后生成
nagios_state度量,并追加到结果尾部; - 所有度量的时间戳统一取解析时刻(
timeFunc().UTC(),默认time.Now)。
若第一行同时包含多于一个|,则视为非法输出,返回错误"illegal output format"。
八、验证与调试
仓库自带完善的测试套件,可直接运行验证解析行为:
go test ./plugins/parsers/nagios/...测试文件 parser_test.go 覆盖了:
- 多种真实插件输出(PING、TCP、负载、磁盘空间)的解析结果断言;
- 无性能数据、畸形性能数据、UNKNOWN 状态的容错处理;
- 阈值格式各分支;
- 基准测试
BenchmarkParsing,用于评估解析性能。
如果你希望亲手验证,也可以直接把 Nagios 插件的输出用 Telegraf 跑一遍,例如:
[[inputs.exec]] commands = ["/usr/lib/nagios/plugins/check_ping -H 127.0.0.1 -w 100,20% -c 200,50%"] data_format = "nagios"配置完成后用telegraf --test --config 你的配置.conf查看实时解析结果。
九、适用前提与注意事项
- 适用于标准 Nagios 插件输出:解析器针对 Nagios Plugin API 约定设计,非标准格式(如普通命令的任意文本输出)应改用
influx、json、value等其它数据格式; - 退出码语义依赖 exec 插件:
state字段由inputs.exec与nagios解析器协同产生,若通过其它输入插件(如execd)使用该解析器,需自行确认退出码处理路径; - UNKNOWN 兜底:任何解析异常都会以
state=3呈现,并尽量保留错误信息到service_output,监控告警时建议将该状态一并纳入判断; - 完整的输入数据格式清单参见 docs/DATA_FORMATS_INPUT.md,其中已收录 Nagios 条目。
十、小结
Telegraf 的nagios数据格式解析器让用户可以零改造地接入 Nagios 生态中成千上万的现成监控插件:inputs.exec负责执行、nagios解析器负责把状态文本、性能数据、阈值和退出码完整映射为结构化时序度量。从配置一行data_format = "nagios",到通过nagios/nagios_state两类度量在 InfluxDB、Prometheus 等时序库中建图与告警,整个过程已在 parser.go 与 parser_test.go 中被实现和验证,可作为直接落地的可靠参考。
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考