Telegraf Converter 处理器插件:标签与字段的类型转换、测量名与时间戳重塑实战指南
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
导读
Telegraf 的 Converter 处理器插件(processors.converter,自 v1.7.0 起提供)是一个专注于"重塑指标结构"的转换工具:它可以把标签(tags)转换为字段(fields)或测量名(measurement name)、把字段转换为标签或测量名、把标签/字段提升为指标时间戳,并在任意方向之间切换字段的数据类型。本文以 converter 插件官方文档 为骨架,结合 converter.go 的实现与 converter_test.go 的测试用例,系统讲解全部配置参数、转换规则、边界行为与实战示例,帮助你在数据管线中准确运用这一转换利器。
插件定位与适用场景
Converter 属于 Telegraf 的"transformation"类别处理器,可以在所有平台(all)上运行。它在数据采集(inputs)与数据输出(outputs)之间对指标做结构性整形,常见场景包括:
- 把 tag 变为 field:例如将 HTTP 端口等低基数标识从标签降级为字段,缩小序列基数,让每个序列更稳定;
- 把 field 变为 tag:例如将业务字段提升为标签,便于在时序数据库里按维度聚合查询;
- 改变字段类型:例如把整数字段转成浮点、把字符串数字转成整数、把数值转成布尔等,统一下游 schema;
- 用标签/字段值重命名 measurement:例如把 MQTT topic 提升为测量名;
- 用标签/字段值设置指标时间戳:例如数据源自带时间戳时,用它覆盖采集时间。
由于转换后系列(series)的标识会变化,插件文档在开头特别强调了一个重要注意事项:
将标签转换为字段时,请务必确保序列仍然可以唯一标识。具有相同 series key(measurement + tags)的字段会相互覆盖。
这一点在写入 InfluxDB 这类按"measurement + tags"唯一标识序列的时序库时尤为关键,详见后文"高基数与系列唯一性风险"一节。
全局配置选项
与其他插件一样,Converter 支持 Telegraf 的通用全局配置,例如namepass、namedrop、tagexclude、alias以及处理器执行顺序配置等,详见 docs/CONFIGURATION.md。[[processors.converter]]作为处理器数组的一个元素,与其它处理器(如 processors.starlark)按配置顺序依次作用于每一条指标。
配置参数全解
完整配置模板可直接参考 sample.conf。核心思路是两张表:[processors.converter.tags]与[processors.converter.fields]。每张表的键(key)代表目标类型,值(value)是需要转换的键名数组,数组元素支持 glob 通配符,语法形式为<target-type> = [<key>...]。
tags 表:标签的目标去向
[[processors.converter]] [processors.converter.tags] measurement = [] string = [] integer = [] unsigned = [] boolean = [] float = [] ## 可选:用作指标时间戳的标签 # timestamp = [] ## 上述时间戳标签的解析格式,可取 "unix"、"unix_ms"、"unix_us"、"unix_ns" ## 或任意合法的 Golang 时间格式;使用 timestamp 选项时必须配置 # timestamp_format = ""各目标类型的语义:
| 目标类型 | 效果 |
|---|---|
measurement | 用该标签的值重命名测量名,原标签被移除 |
string/integer/unsigned/boolean/float | 把标签转换为对应类型的字段,原标签被移除 |
timestamp | 用该标签值设置指标时间戳,原标签被移除,需配合timestamp_format |
fields 表:字段的目标去向
[processors.converter.fields] measurement = [] tag = [] string = [] integer = [] unsigned = [] boolean = [] float = [] ## 可选:将 Base64 编码的 IEEE 754 Float32 值解码为 float32 字段 ## (例如 openconfig 遥测数据中形如 ## data_json_content_state_openconfig-platform-psu:output-power":"RKeAAA==" 的数值, ## 解码后得到 float32 值 1340) # base64_ieee_float32 = [] ## 可选:用作指标时间戳的字段 # timestamp = [] ## 同 tags 表,timestamp_format 在使用 timestamp 时必须配置 # timestamp_format = ""| 目标类型 | 效果 |
|---|---|
measurement | 把字段值转为字符串后重命名测量名,原字段被移除 |
tag | 把字段值转为字符串后提升为标签,原字段被移除 |
string/integer/unsigned/boolean/float | 把字段转换为对应类型(同类型转换视为"规范化") |
base64_ieee_float32 | 将 Base64 字符串按 IEEE 754 位模式解码为float32字段 |
timestamp | 用字段值设置指标时间戳,成功后原字段被移除 |
类型转换的通用约束
文档明确了三条全局规则,均可从源码与测试中得到印证:
- 转换失败的值会被丢弃。对于 tags 表,转换失败只记录错误日志并跳过(
convertTags中continue);对于 fields 表,转换失败不仅记录日志,还会主动移除该字段(converter.go)。测试用例from string field unconvertible、from tag unconvertible均验证了这一点。 - 字符串转数字时可能损失精度。插件支持的最大数值类型是
float64;当字符串数字超出float64能精确表示的范围时,精度会丢失。转换实现经由 internal/type_conversions.go 的ToFloat64等函数完成,内部使用strconv.ParseFloat/ParseInt等标准库解析。 - 数组顺序不保证。可以同时配置多个标签或字段作为测量名来源或时间戳来源,但数组内匹配顺序不保证——当多个候选键同时存在时,最终生效的是哪一个不做确定性承诺(测试
TestMultipleTimestamps也表明配置多个时间戳源是被允许的)。
从零配置实战示例
以下四个示例完整来自插件官方文档,均经过测试用例验证,可以直接复制到 Telegraf 配置中。
示例一:把 port 标签转换为字符串字段
[[processors.converter]] [processors.converter.tags] string = ["port"]转换前后对比(Influx 行协议):
- apache,port=80,server=debian-stretch-apache BusyWorkers=1,BytesPerReq=0 + apache,server=debian-stretch-apache port="80",BusyWorkers=1,BytesPerReq=0可以看到port从标签(series 的一部分)变成了字段(port="80"),系列基数因此下降。注意这里port被转成字符串字段,这是文档示例的行为;如需数值字段,应配置float = ["port"]或integer = ["port"]。
示例二:用 glob 批量转换字段类型
[[processors.converter]] [processors.converter.fields] integer = ["scboard_*"]转换前后对比:
- apache scboard_closing=0,scboard_dnslookup=0,scboard_finishing=0,scboard_idle_cleanup=0,scboard_keepalive=0,scboard_logging=0,scboard_open=100,scboard_reading=0,scboard_sending=1,scboard_starting=0,scboard_waiting=49 + apache scboard_closing=0i,scboard_dnslookup=0i,scboard_finishing=0i,scboard_idle_cleanup=0i,scboard_keepalive=0i,scboard_logging=0i,scboard_open=100i,scboard_reading=0i,scboard_sending=1i,scboard_starting=0i,scboard_waiting=49iGlob 匹配由 filter/filter.go 的Compile实现(底层使用github.com/gobwas/glob),支持*、?、{}、[]、!等通配符。测试用例globbing用integer: ["int_*"]验证了int_a、int_b被批量转为int64,而float_a保持不变。
示例三:用标签值重命名测量名
[[processors.converter]] [processors.converter.tags] measurement = ["topic"]转换前后对比:
- mqtt_consumer,topic=sensor temp=42 + sensor temp=42这是 MQTT 等多主题输入的经典用法:将每个消息携带的 topic 标签提升为测量名,让不同主题的数据进入不同的 measurement。源码中convertTags对命中的键执行metric.SetName(value),随后metric.RemoveTag(key)(converter.go)。测试用例measurement from tag验证了用filepath标签的值/var/log/syslog重命名测量名的行为。
示例四:用标签设置指标时间戳
[[processors.converter]] [processors.converter.tags] timestamp = ["time"] timestamp_format = "unix"转换前后对比:
- metric,time="1677610769" temp=42 + metric temp=42 1677610769时间戳解析由internal.ParseTimestamp完成(internal/internal.go):unix系列格式支持整数、浮点数或字符串输入,unix/unix_ms/unix_us/unix_ns分别对应秒、毫秒、微秒、纳秒精度;其余情况视为 Go 标准时间格式字符串(如rfc3339、2006-01-02 15:04:05 MST),此时输入必须是字符串。测试覆盖了unix(整型字段1111111111)、rfc3339("2009-02-13T23:31:30Z"→1234567890)以及自定义 Go 时间格式等多种情况,也验证了时间戳格式非法时转换被跳过、原数据保持不动(invalid timestamp format用例)。
同样的功能也完全可以通过 fields 表实现(把time字段提升为时间戳),用法一致:
[[processors.converter]] [processors.converter.fields] timestamp = ["time"] timestamp_format = "unix"字段转标签:提升维度
与示例一相反,把字段提升为标签是提升可查询性的常用手段。配置:
[[processors.converter]] [processors.converter.fields] tag = ["f"]测试用例from string field中,字段f: "foo"被转换为标签f=foo并从字段中移除。convertFields的实现使用internal.ToString把字段值转成字符串,再metric.AddTag(key, v),最后metric.RemoveField(key)(converter.go)。注意:ToString对nil会返回空字符串,对不支持的类型返回错误,转换失败时该字段同样被丢弃。
转换规则深入:数值、布尔、十六进制与浮点边界
从源码的辅助函数(converter.go)和internal包的类型转换函数(internal/type_conversions.go)可以总结出精确的转换语义:
整数 / 无符号整数(toInteger / toUnsigned)
- 字符串解析优先走
internal.ToInt64/ToUint64,支持十进制、0x十六进制前缀(测试用例from string field hexadecimal验证"0x11826c"→1147500); - 若字符串解析失败,回退到浮点解析再取整;
- 浮点转整数采用四舍五入(
math.Round):"42.2"→42,"42.5"→43(见测试from string field的b1/b2); - 越界被钳制而非报错:超过
int64范围取math.MaxInt64/math.MinInt64,超过uint64范围取math.MaxUint64,负数转 unsigned 取0(测试out of range for unsigned、from float field、from unsigned field均有对应断言); - 布尔转整数时
true→1、false→0。
布尔(internal.ToBool)
支持标准strconv.ParseBool的字符串形式(1/t/T/TRUE/true/True/0/f/F/FALSE/false/False),数字0→false、非零 →true。测试用例from integer field验证int64(42)→true、int64(0)→false。
浮点(toFloat)
- 字符串以
0x开头时,先解析为任意精度整数(math/big),再转为float64——因此可以处理超过float64整数表示范围的十六进制大数(测试from string field hexadecimal中"0x2139d19bb1c580ebe0"→612908836750534700000); - 其余情况走
internal.ToFloat64。
Base64 编码的 IEEE 754 Float32(base64ToFloat32)
这是一个面向特定数据源的专有能力:某些遥测协议(如 openconfig 的 gNMI 数据)会把 float32 的位模式编码为 Base64 字符串(文档示例"RKeAAA=="解码为1340)。base64ToFloat32的实现流程是:Base64 解码 → 校验字节长度必须为 4 → 拼出 32 位二进制串 →strconv.ParseUint→math.Float32frombits(converter.go)。测试用例float32 from ieee754 float32 encoded as base64验证"QlAAAA=="→float32(52)、"QlgAAA=="→float32(54)。解码失败(非法 Base64 或长度不是 4 字节)时字段被移除。
内部工作原理:过滤器编译与处理流程
从源码结构看,插件的运行可分为两个阶段:
- 初始化阶段(Init/compile):
compile()分别把tags、fields两张配置表编译成conversionFilter结构体——每个目标类型对应一个filter.Filter(converter.go)。filter.Compile对空数组返回nil过滤器;若两张表最终都没有任何有效过滤器,Init会直接报错"no filters found"(测试TestEmptyConfigInitError验证了空配置启动失败)。 - 处理阶段(Apply):对每条指标依次执行
convertTags(metric)与convertFields(metric)(converter.go)。convertTags遍历metric.Tags(),命中即转换并RemoveTag;convertFields遍历metric.Fields(),命中即转换(失败则移除字段)。
插件通过processors.Add("converter", ...)注册(converter.go),因此配置表中统一使用[[processors.converter]]小节。此外它实现了 Telegraf 的跟踪指标(tracking metric)接口,测试TestTracking验证了转换后指标在输出确认(Accept)时投递通知能正确送达。
高基数与系列唯一性风险
回到文档开头的关键警告:标签属于 series key(measurement + tags),字段不属于。当你把标签转成字段、或把不同标签值映射到同一测量名时,多个输入系列可能坍缩成同一个系列键,后续写入时字段会相互覆盖。典型风险场景:
- 把唯一性强的标签(如
host、instance)转成字段,若两个来源的 host 值相同,数据会被覆盖; - 用
measurement = ["topic"]时,若不同消息的 topic 相同但期望保留其他标签,需确认剩余标签组合仍然唯一。
设计转换规则时,应先用telegraf --test或telegraf --config <file> --test观察转换后的行协议输出,确认系列键符合预期后再部署到生产环境。
常见配置问题与排错
| 问题现象 | 排查方向 |
|---|---|
| 转换后字段消失 | 值无法解析为目标类型,字段被丢弃——检查源值格式与目标类型是否匹配 |
配置了timestamp但时间戳没生效 | timestamp_format缺失或非法;对 Go 格式字符串,输入必须是字符串类型 |
| 浮点转整数结果"多了 1" | 转换采用四舍五入(math.Round),42.5会变成43 |
| 大整数精度异常 | 字符串数字超出float64精确表示范围,精度丢失是预期行为 |
启动报no filters found | tags和fields都没有配置任何目标类型,至少需要一个非空数组 |
| 多个候选键不确定谁生效 | 数组匹配顺序不保证,避免同时配置多个测量名/时间戳来源 |
结语
Converter 是 Telegraf 数据整形工具箱中的基础件:一张tags表、一张fields表,配上measurement、tag、string、integer、unsigned、boolean、float、timestamp以及base64_ieee_float32等目标类型,即可完成标签/字段/测量名/时间戳之间的任意重塑。理解其"失败即丢弃(字段)"、四舍五入取整、越界钳制、顺序不保证等边界行为,配合测试用例验证过的示例配置,可以让你的数据管线在采集与输出之间拥有一道可靠的结构转换闸门。如需进一步了解处理器在管线中的位置与全局选项,可参阅 docs/CONFIGURATION.md 与 docs/PROCESSORS.md。
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考