Telegraf parser 处理器(processors.parser)实战指南:解析字段与标签生成新指标
Telegraf parser 处理器processors.parser实战指南解析字段与标签生成新指标【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegrafparser 是 Telegraf 中的一个转换类transformation处理器插件自 v1.8.0 起提供适用于所有平台用于把指标metric中指定字段或标签里携带的序列化数据按照某种输入数据格式解析成全新的指标并注入数据管道。本文围绕其配置项、五种 merge 合并策略、典型使用场景与源码实现展开读完即可掌握从 syslog、JSON、logfmt 等内嵌数据中二次提炼指标的完整方案。插件定位与工作原理在 Telegraf 的处理链中[[processors.parser]]属于处理器processor而非输入插件它不负责采集数据而是对上游输入插件如 syslog、tail、kafka_consumer、execd 等产出的指标做再加工读取指标中某个字段或标签的值将该值交给 Telegraf 的解析器parser按指定数据格式解析最终把解析出来的新指标追加到结果集中。一个典型场景是syslog 输入插件把一整条结构化日志塞进message字段而日志正文本身又包含lvlinfo、msgExecuting query这类 logfmt 键值对。用 parser 处理器就可以把这段正文拆解成独立的字段便于后续按日志级别、查询语句等维度做筛选与聚合。该插件通过SetParser接口注入实际使用的解析器见 config/config.go 中addParser与SetParser的装配逻辑因此它的解析能力与 Telegraf 的输入数据格式体系完全打通。目前可用的数据格式清单见 输入数据格式文档包括 InfluxDB Line Protocol、JSON、JSON v2、Grok、logfmt、CSV、Value、Binary、Graphite、Wavefront、OpenTSDB、XPath 等。完整配置与参数说明插件对应的示例配置文件为 sample.conf完整配置如下# Parse a value in a specified field(s)/tag(s) and add the result in a new metric [[processors.parser]] ## The name of the fields whose value will be parsed. parse_fields [message] ## Fields to base64 decode. ## These fields do not need to be specified in parse_fields. ## Fields specified here will have base64 decode applied to them. # parse_fields_base64 [] ## The name of the tags whose value will be parsed. # parse_tags [] ## If true, incoming metrics are not emitted. # drop_original false ## Merge Behavior ## Possible options are: ## - none: keep the newly parsed metrics as-is ## - override: emit a single metric with all tags and fields of newly parsed ## merged but retaining the first timestamp. If drop_original is ## false, all metrics are merged into the original metric ## NOTE: Existing field or tag values will be overridden. ## - override-with-timestamp: same as override, but the timestamp is set ## based on the new metrics if present ## - parent: emit one metric per newly parsed metric with each newly parsed ## metric is merged individually into the parent metric keeping the parent ## timestamp ## - parent-with-timestamp: same as parent, but the timestamp is set ## based on the new metric if present # merge none ## The dataformat to be read from files ## 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 influx各参数含义与底层行为如下配置项默认值说明parse_fields[]需要解析的字段名列表字段值将按data_format解析成新指标。必填示例中的核心项实际使用时至少配置parse_fields与parse_tags之一parse_tags[]需要解析的标签名列表逻辑与parse_fields相同但读取的是标签值parse_fields_base64[]需要先做 base64 解码再解析的字段名列表。无需重复列入parse_fields若某字段同时出现在parse_fields与parse_fields_base64插件会记录错误日志并跳过该字段见源码parser.go中plain b64分支drop_originalfalse为true时丢弃原始指标只输出解析后的新指标为false时原始指标与解析出的新指标一起输出mergenone解析出多条新指标时的合并策略可选none/override/override-with-timestamp/parent/parent-with-timestamp详见下文data_formatinflux解析所用数据格式与各格式配套的专属配置项如 JSON 的tag_keys、Grok 的patterns等均在此处理器配置块内声明解析范围与取值细节从源码 parser.go 的Apply方法可以确认以下几点行为字段遍历插件遍历metric.FieldList()凡是命中parse_fields或parse_fields_base64的字段都会参与解析解析失败格式不匹配的字段会被跳过并输出错误日志不影响其余字段。非字符串字段字段值不一定是字符串。若值为字符串直接使用否则通过toBytes按主机字节序HostEndianness编码为字节流后交给解析器见 parser.go因此 Binary 解析器可以直接对uint8等数值字段进行位级解析。度量名回退解析器在 processor 场景下默认以父插件名作为测量名因此当解析结果未提供名称或名称为parser时插件会把原始指标的度量名写回新指标见 parser.go 与 parser.go保证解析前后的度量名语义连续。这一行为对应测试用例parser without metric name (issue #12115)。标签解析parse_tags的处理与字段基本一致只是取值来源是metric.GetTag(key)命中后才解析。合并策略Merge Strategies当一个字段或标签解析出多条新指标时merge参数决定如何组合它们。五种策略在Apply末尾的 switch 分支中对应实现override/override-with-timestamp走mergeAllparent/parent-with-timestamp走mergeIndividual见 parser.go。注意合并仅针对一次解析产出的多条新指标且顺序遵循解析结果顺序——同名冲突时后出现的值覆盖先出现的值重要。以下示例沿用官方文档的输入父指标test,sourcefoo message...,additionaltrue 1773258782000000000在message字段中按 InfluxDB Line Protocol 解析出四条指标metric,statusok value11i 1773239679000000000 metric,statuswarn value223i 1773239679100000000 metric,statusok value319i 1773239679200000000 metric,statusfault value442i 1773239679300000000override将所有解析出的指标合并为单条指标输出其全部字段与标签的并集时间戳保留父指标最早的时间戳。drop_original false时父指标自身也会一并并入该结果。drop_original true时结果metric,statusfault value11i,value223i,value319i,value442i 1773258782000000000drop_original false时结果父指标打上sourcefoo、additionaltruemetric,sourcefoo,statusfault value11i,value223i,value319i,value442i,additionaltrue 1773258782000000000⚠️重要当多条指标中存在同名字段或标签时它们会互相覆盖最终只保留最后一次出现的值示例中status标签被最后一条fault覆盖。这是mergeAll顺序写入base的结果。override-with-timestamp行为与override完全一致唯一区别是如果解析出的指标自带时间戳则用其中最新一条的时间戳覆盖父指标时间戳若解析结果不含时间戳则保留原始指标时间戳。相关测试用例override with timestamp与override with timestamp no inner time分别验证了这两种分支。parent将每条解析出的新指标分别与父指标合并即每个解析指标 父指标字段标签的并集输出一条父指标时间戳不变同时保留原始父指标当drop_original false。结果drop_original true时无最后一条metric,sourcefoo,statusok value11i,additionaltrue 1773258782000000000 metric,sourcefoo,statuswarn value223i,additionaltrue 1773258782000000000 metric,sourcefoo,statusok value319i,additionaltrue 1773258782000000000 metric,sourcefoo,statusfault value442i,additionaltrue 1773258782000000000⚠️重要若某条新指标与父指标存在同名字段或标签新解析出的值覆盖父指标的值见mergeIndividual中先base.Copy()再写字段/标签的实现。parent-with-timestamp行为与parent一致区别是解析指标自带时间戳时以该解析指标的时间戳覆盖合并结果的时间戳解析指标无时间戳则保留父指标时间戳。测试用例parent with timestamp/parent with timestamp no inner timestamp覆盖了这两种情况。策略选型建议需要把多条解析结果摊平成单条聚合指标如一次性告警位图、多路状态汇总→override。需要保留每条解析结果独立、同时携带父级上下文 →parent。数据本身携带权威时间戳如日志内嵌时间→ 选择带-with-timestamp后缀的变体。关于时间戳还有一点源码细节Init()对*-with-timestamp模式会把解析器的默认时间函数设为零值时间确保数据内无时间戳时解析结果不伪造时间见 parser.go若所用解析器未实现ParserTimeFuncPlugin接口例如 OpenTSDB 解析器插件会输出告警Parser will always create a timestamp in merge-mode ...——对应测试TestNoTimeFuncParser。实战示例logfmt 日志字段拆分官方文档给出一个完整可运行的 logfmt 示例。配置[[processors.parser]] parse_fields [message] merge override data_format logfmt输入syslog 采集的 InfluxDB 日志message字段内含 logfmt 键值对syslog,appnameinfluxd,facilitydaemon,hostnamehttp://influxdb.example.org\ (influxdb.example.org),severityinfo facility_code3i,message ts2018-08-09T21:01:48.137963Z lvlinfo msg\Executing query\ log_id09p7QbOG000 servicequery query\SHOW DATABASES\,procid6629,severity_code6i,timestamp1533848508138040000i,version1i输出logfmt 键ts、lvl、msg、log_id、service、query被提升为独立字段merge override使原始 syslog 字段与解析结果合并为一条指标syslog,appnameinfluxd,facilitydaemon,hostnamehttp://influxdb.example.org\ (influxdb.example.org),severityinfo facility_code3i,log_id09p7QbOG000,lvlinfo,message ts2018-08-09T21:01:48.137963Z lvlinfo msg\Executing query\ log_id09p7QbOG000 servicequery query\SHOW DATABASES\,msgExecuting query,procid6629,querySHOW DATABASES,servicequery,severity_code6i,timestamp1533848508138040000i,ts2018-08-09T21:01:48.137963Z,version1i深入源码一次 Apply 的完整处理链Apply方法parser.go是插件的核心处理顺序为预处理原始指标drop_original false时先把原始指标加入结果集否则调用metric.Drop()丢弃。解析字段遍历FieldList()判定字段属于parse_fields明文还是parse_fields_base64base64 解码使用标准 base64 编码表两者都命中则报错跳过随后把值转成字节流并调用p.parser.Parse(value)。修正度量名解析结果名称为空或为parser时回填原始指标名。解析标签遍历parse_tags命中后对标签值走同样的parseValue流程。合并按merge选择mergeAlloverride 系单条输出或mergeIndividualparent 系逐条输出默认直接追加全部新指标。从配置装配层面看处理器在 config/config.go 中被检测为telegraf.ParserPlugin实现了SetParser时会调用addParser(processors, ...)依据data_format构建对应解析器并通过t.SetParser(parser)注入——这就是本插件可以复用全部输入数据格式的根本原因。边界与错误处理字段缺失parse_fields指定的字段在指标中不存在时原始指标原样通过不报错对应测试field not found。类型不匹配字段值为非字符串且无法编码为字节流时记录错误并跳过该字段。base64 解码失败字段值不是合法 base64 时记录错误并跳过对应测试TestBase64FieldValidation同时验证了同一字段重复出现在两组列表会触发错误日志。非法 merge 值Init()遇到merge无法识别的取值时直接返回unrecognized merge value: ...错误插件启动失败测试TestInvalidMerge。追踪指标drop_original只影响输出数量不影响上游投递确认TestTracking用例验证了原始指标与解析指标都能正确送达见 parser_test.go。此外插件的默认构造processors.Add(parser, ...)中DropOriginal显式初始化为false即未配置时保留原始指标。与其他处理器协同parser 处理器可以出现在任意处理器链位置顺序由 CONFIGURATION.md 中的插件排序规则决定。常见组合包括在 parser 之后接regex处理器对解析出的字段再做清洗或在 parser 之前接converter统一字段类型。解析出的新指标与原始指标遵循相同的度量名回退与时间戳规则可平滑衔接后续的聚合器aggregator与输出插件。如需查阅插件在配置中的装载、处理器排序及全局配置name_prefix、name_override、字段/标签过滤等可参考 CONFIGURATION.md各数据格式的完整专属参数见 输入数据格式文档。相关实现与测试代码位于 parser.go、parser_test.go 与 sample.conf。【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考