Telegraf Collectd 解析器实战指南:UDP 二进制网络协议、加密认证与多值拆分
2026/9/14 11:30:26 网站建设 项目流程

Telegraf Collectd 解析器实战指南:UDP 二进制网络协议、加密认证与多值拆分

【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf

collectd 是广泛使用的系统信息采集守护进程,它通过自有的二进制网络协议把指标推送到远程服务器。本篇指南围绕 Telegraf 的 Collectd Parser 插件(仓库路径 plugins/parsers/collectd/README.md)展开,讲解如何在 Telegraf 中直接消费该协议:从零配置socket_listener接收 UDP 数据包,再到签名/加密认证、TypesDB 数据类型加载,以及多值插件的 split/join 两种解析语义。读完本文,你将能够独立搭建一条「collectd → Telegraf → 时序数据库」的安全采集链路,并理解其底层实现机制。

Collectd 解析器是什么

Telegraf 的 Collectd Parser 用于解析collectd 二进制网络协议(binary network protocol)的数据。该协议是 collectd 的network插件在主机之间传输指标时使用的紧凑二进制格式,Telegraf 通过它可以直接接收来自其他 collectd 实例推送的指标,而无须中间转换。

根据 plugins/parsers/collectd/parser.go 的实现,解析器完成两件事:

  1. 调用collectd.org/network包的network.Parse()把二进制报文还原为api.ValueList列表;
  2. 逐个把ValueList转换为 Telegraf 指标。

解析时自动为指标创建hostinstancetypetype_instance四个标签,且所有 collectd 值(Gauge、Derive、Counter)都被统一转成float64 字段。这一点可以从 parser.go 的类型转换代码直接确认。

collectd 解析器属于 Telegraf 通用输入数据格式之一,在 docs/DATA_FORMATS_INPUT.md 的格式列表中有登记,任何带有data_format选项的输入插件都可以选用它;在 Telegraf 中它最常见的宿主是socket_listener输入插件。

快速上手:接收 collectd 推送数据

collectd 网络协议默认通过 UDP 监听25826端口(这也是 collectdnetwork插件的标准端口)。下面是最小可用配置,来自 collectd README:

[[inputs.socket_listener]] service_address = "udp://:25826" ## 要消费的数据格式,每个数据格式有自己独立的配置项, ## 详见 docs/DATA_FORMATS_INPUT.md data_format = "collectd" ## 加密安全级别使用的认证文件 collectd_auth_file = "/etc/collectd/auth_file" ## none(默认)、sign 或 encrypt 三选一 collectd_security_level = "encrypt" ## TypesDB 规范文件的路径 collectd_typesdb = ["/usr/share/collectd/types.db"] ## 多值插件有两种处理方式: ## "split" 把多值插件数据拆分解析为多个独立的 measurement ## "join" 把多值插件数据作为一个含多字段的 measurement ## 为了兼容旧版 influxdb,默认行为是 "split" collectd_parse_multivalue = "split"

socket_listener输入插件(plugins/inputs/socket_listener/README.md)负责监听 TCP/UDP/Unix 套接字并把收到的数据包按data_format交给解析器处理,udp://:25826表示监听本机所有网卡的 25826 端口。当 collectd 发送端把指标推送到该端口后,数据即被解析为 Telegraf 指标进入采集管道。

配置参数详解

Collectd 解析器全部配置项都定义在 parser.go 的Parser结构体中,TOML 标签与配置文件名一一对应:

配置项TOML 键类型默认值说明
数据格式data_formatstring无(必须显式指定为"collectd"在宿主输入插件上选择 collectd 解析器
认证文件collectd_auth_filestring/etc/collectd/auth_file用于签名/加密认证的用户-密码映射文件
安全级别collectd_security_levelstring"none"nonesignencrypt三选一
类型数据库collectd_typesdb[]stringTypesDB 文件路径,可指定多个,多个数据库会被合并
多值处理collectd_parse_multivaluestring"split"split(默认)或join

需要特别说明的默认行为来自源码:

  • 认证文件默认值常量定义在 parser.go:DefaultAuthFile = "/etc/collectd/auth_file"。如果collectd_auth_file未配置,Init()会自动填入该默认路径(parser.go)。
  • 安全级别在Init()中做字符串到枚举的映射,未匹配任何已知值时回落为none(parser.go)。
  • 多值处理如果留空,在解析时同样会回落到"split"(parser.go)。

安全级别与认证文件

collectd 二进制协议支持三种网络安全级别,解析器通过collectd_security_level控制,对应network.Nonenetwork.Signnetwork.Encrypt三种底层模式:

  • none(默认):不校验认证信息,明文数据即可解析;
  • sign:要求数据包附带签名,校验通过才解析;
  • encrypt:要求数据包使用加密,密文通过共享密码解密后解析。

认证文件的格式与仓库测试数据 plugins/parsers/collectd/testdata/authfile 一致,为每行一条用户名: 密码的文本映射,例如:

user0: bar

Init()中通过network.NewAuthFile(p.AuthFile)把该文件装载为密码查找器(parser.go),发送端使用同一用户与密码进行签名或加密,接收端凭文件里的对应关系验证。

测试文件 parser_test.go 用一组对照实验精确刻画了各安全级别的行为边界,非常值得参考:

  • sign级别TestParse_SignSecurityLevel):签名数据、加密数据均可正常解析;明文数据被跳过,解析结果为空指标列表;使用错误密码签名则直接返回错误;
  • encrypt级别TestParse_EncryptSecurityLevel):只有加密数据可解析;签名数据与明文数据都会被跳过;错误密码同样报错。

也就是说,安全级别越高,解析器越严格——配置encrypt后,即使攻击者伪造了带签名的数据也无法进入采集管道。

TypesDB:数据类型的加载与合并

collectd 的类型系统依赖types.db文件,其中定义了每个类型(type)所包含的数据源(data source,DS)的名称、类型与取值范围。解析二进制报文时,必须知道某个 type 对应几个数据源及其含义,才能正确还原字段。

解析器通过collectd_typesdb配置项指定数据库文件路径:

  • LoadTypesDB()打开文件并用api.NewTypesDB(reader)解析(parser.go);
  • Init()遍历所有配置的路径逐个加载,当存在多个数据库时使用Merge()进行合并(parser.go),因此你可以既包含发行版默认的/usr/share/collectd/types.db,又追加自定义类型定义。

如果该配置项留空,popts.TypesDB保持 nil,此时解析器只依赖报文自身携带的信息,可能无法正确还原多数据源类型(这与 parser_test.go 中TestNewCollectdParserTypesDB为 nil 的断言一致)。

多值插件:split 与 join 两种语义

collectd 的一个数据包可以携带多个数据源值(例如 CPU 插件一个值列表中包含 user、system、idle 等),collectd_parse_multivalue决定如何处理这种情况,核心逻辑在unmarshalValueList()(parser.go):

split(默认)模式——每个数据源值生成一条独立指标:

  • 指标名:<plugin>_<DSName>,例如cpu_value
  • 字段:统一为value(float64);
  • 效果:一个含 2 个值的ValueList会被拆成 2 条 measurement。

从 parser_test.go 的TestParseMultiValueSplit可以看到,2 个值的报文在 split 模式下产出 2 条指标;而singleMetric测试用例中,未携带数据源名称的报文拆分后默认名称为<plugin>_value(parser_test.go),对应 README 示例输出里的memory,type=memory,type_instance=buffered value=...

join 模式——整个ValueList合并为一条含多字段的 measurement:

  • 指标名:直接使用plugin
  • 字段:每个数据源值以各自的DSName作为字段名;
  • 效果:一个含 2 个值的ValueList只产出 1 条指标,2 个字段。

对应 parser_test.go 的TestParseMultiValueJoin:join 模式下同样报文只产出 1 条指标。README 中特别注明split 是默认行为,目的是与旧版 influxdb 兼容;如果你的下游存储更擅长处理多字段宽表,可以显式改为join

如果配置了split/join以外的值,解析器不会报错,而是输出一条提示日志「parse-multi-value config can only be 'split' or 'join'」并丢弃该值列表(parser.go)。

指标映射规则

无论 split 还是 join,指标的时间戳都取ValueList时间的 UTC 表示(vl.Time.UTC())。标签映射规则完全一致,只有当对应标识符非空时才添加标签

collectd 标识符Telegraf 标签说明
Hosthost来源主机名
PluginInstanceinstance插件实例(如 CPU 编号)
Typetype指标类型
TypeInstancetype_instance类型实例

字段值方面,Gauge(量规)、Derive(派生计数)、Counter(单调计数器)三种 collectd 值类型都被转换为 float64 写入value字段(split 模式)或对应 DSName 字段(join 模式),相关代码见 parser.go。

另外,SetDefaultTags()Parse()中实现了默认标签注入:当解析器配置了默认标签且指标上不存在同名标签时才会补写(parser.go)。测试TestParse_DefaultTags(parser_test.go)验证了这一点——默认标签foo: bar会被正确附加到解析后的指标上。

示例输出解读

README 给出了真实的解析结果示例([plugins/parsers/collectd/README.md#L48-L59]),格式为 InfluxDB Line Protocol,measurement 为memory

memory,type=memory,type_instance=buffered value=2520051712 1560455990829955922 memory,type=memory,type_instance=used value=3710791680 1560455990829955922 memory,type=memory,type_instance=buffered value=2520047616 1560455980830417318 memory,type=memory,type_instance=cached value=9472626688 1560455980830417318 memory,type=memory,type_instance=slab_recl value=2088894464 1560455980830417318 memory,type=memory,type_instance=slab_unrecl value=146984960 1560455980830417318 memory,type=memory,type_instance=free value=2978258944 1560455980830417318 memory,type=memory,type_instance=used value=3707047936 1560455980830417318

解读要点:

  • measurement 名memory来自 collectd 插件的名称;
  • 标签type=memorytype_instance=buffered/used/cached/...分别映射自协议中的类型与类型实例;
  • 字段value即 collectd 的原始采样值(以字节为单位的内存大小),统一为 float64;
  • 行尾为纳秒精度时间戳;
  • 这是典型的 split 模式输出——同一时刻的多数据源值被拆成了多条独立 measurement,因此相邻行共享同一时间戳、各对应一个type_instance

与 collectd 发送端对接

要让 collectd 主机把数据推送到 Telegraf,只需在 collectd 侧启用其network插件,并把目标服务器指向运行 Telegraf 的主机与25826端口;若在解析器侧配置了signencrypt安全级别,则 collectd 侧还需配置相同的安全级别与认证文件(用户/密码需与 Telegraf 的collectd_auth_file一致),从而构成端到端的加密采集链路。

小结

Collectd 解析器让 Telegraf 能够以原生的方式接入 collectd 二进制网络协议:

  • 通过socket_listener+data_format = "collectd"即可在 UDP 25826 端口接收并解析 collectd 数据;
  • collectd_auth_filecollectd_security_level实现签名/加密认证,encrypt级别只放行加密数据,安全性最高;
  • collectd_typesdb加载并合并多个类型数据库,保证多数据源类型被正确还原;
  • collectd_parse_multivalue在「多指标拆分」与「单指标多字段」两种建模方式之间切换,默认split以兼容旧版 influxdb。

如需深入阅读实现与验证细节,推荐直接查看 parser.go 的解析与指标映射逻辑、parser_test.go 的安全级别与 split/join 行为测试,以及宿主插件 socket_listener 的配置文档。

【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询