资讯动态

Telegraf Template Processor 完全指南:用 Go Template 动态生成 Tag 实现指标路由

发布时间:2026/9/14 15:37:46 来源:尧图企业网站定制
Telegraf Template Processor 完全指南用 Go Template 动态生成 Tag 实现指标路由【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf本文面向 Telegraf 用户系统讲解processors.template处理器自 Telegraf v1.14.0 起提供的配置语法、模板语言上下文与底层实现原理。通过本文你将掌握如何基于测量名measurement name、标签、字段与时间戳用 Go Template 语法动态生成新标签为多输出动态路由、字段转标签、时间维度拆分等场景构建可落地的配置方案。一、插件定位与典型应用场景Template Processor 的核心能力是对指标应用模板生成一个新的 Tag既有 Tag 名、又有 Tag 值都可以由模板动态计算。该插件的首要设计用途是创建可用于多输出插件动态路由的标签或者配合输出插件特定的路由选项使用——例如按hostname、level等标签拼接出topic让不同来源的指标落到不同的 Kafka Topic、MQTT 主题或 InfluxDB 存储桶。模板中可以访问每一条指标的全部要素可访问数据说明测量名measurement name例如cpu、mem标签tags指标的全部键值对标签字段fields指标的全部字段及其值时间戳timestamp指标采集时间可参与格式化模板遵循 Go Template 语法标准库text/template并内置了 Sprig 函数库sprig.TxtFuncMap()因此可以使用default、lower、upper、trim、join等大量实用函数对模板结果做二次加工。二、快速开始完整配置解析插件只需两个配置项完整样例见 sample.conf# Uses a Go template to create a new tag [[processors.template]] ## Go template used to create the tag name of the output. In order to ## ease TOML escaping requirements, you should use single quotes around ## the template string. tag topic ## Go template used to create the tag value of the output. In order to ## ease TOML escaping requirements, you should use single quotes around ## the template string. template {{ .Tag hostname }}.{{ .Tag level }}两个参数的核心要点tag输出标签的名称。它本身也是一个 Go 模板——静态字符串如topic或动态表达式如{{ .Field type }}均可详见下文“字段值作为标签名”示例。template输出标签的值模板。两个参数都支持模板语法因此“标签名”和“标签值”都可以完全动态生成。文档与样例都特别建议使用单引号包裹模板字符串以规避 TOML 对反斜杠、花括号等字符的转义负担单引号字符串在 TOML 中为字面量不做转义处理。从源码 template.go 可以看出插件结构体只保存Tag、Template两个toml字段与上述配置一一对应。三、模板上下文TemplateMetric 接口全解模板的执行对象不是原始指标对象本身而是 Telegraf 专门为模板场景暴露的TemplateMetric接口。该接口定义在仓库根目录 metric.go// TemplateMetric is an interface to use in templates (e.g text/template) // to generate complex strings from metric properties // e.g. {{.Name}}-{{.Tag foo}}-{{.Field bar}} type TemplateMetric interface { Name() string Field(key string) interface{} Fields() map[string]interface{} Tag(key string) string Tags() map[string]string Time() time.Time String() string }模板中可直接调用的方法方法返回类型作用模板写法示例Name()string测量名{{ .Name }}Tag(key)string取指定标签值{{ .Tag hostname }}Tags()map[string]string全部标签的 map{{ .Tags }}Field(key)interface{}取指定字段值{{ .Field temperature }}Fields()map[string]interface{}全部字段的 map{{ .Fields }}Time()time.Time指标时间戳Go 的time.Time可继续链式调用UTC()、Year()、Format等{{ .Time.UTC.Year }}String()string指标的整体字符串表示{{ . }}接口的默认实现位于 metric/metric.go。例如String()的实现为fmt.Sprintf(%s %v %v %d, name, tags, fields, timeUnixNano)这也是下文{{.}}示例输出格式的来源Time()直接返回内部time.Time因此{{.Time.UTC.Year}}这样的链式调用在 Go 模板中是合法的。从源码看处理器在Apply中会先尝试对指标调用Unwrap()处理跟踪指标包装再断言为TemplateMetric后执行模板——这保证了该插件对普通指标和跟踪型指标都能正常工作。四、实战示例全解以下示例完整继承自插件官方文档 README.md并辅以源码与测试佐证。4.1 合并多个标签生成单一标签动态路由首选[[processors.template]] tag topic template {{ .Tag hostname }}.{{ .Tag level }}处理前后对比- cpu,leveldebug,hostnamelocalhost time_idle42 cpu,leveldebug,hostnamelocalhost,topiclocalhost.debug time_idle42这正是 README 中“为多输出动态路由创建标签”这一首要用例的标准形态。对应单元测试见 template_test.go 的TestTagTemplateConcatenate输入带hostnamelocalhost、leveldebug标签的指标断言输出新增topiclocalhost.debug。4.2 使用字段值作为标签名动态标签名[[processors.template]] tag {{ .Field type }} template {{ .Name }}处理前后对比- cpu,leveldebug,hostnamelocalhost time_idle42,typesensor cpu,leveldebug,hostnamelocalhost,sensorcpu time_idle42,typesensortag参数本身是模板的体现标签名来自字段type的值sensor标签值来自测量名cpu。对应测试为 template_test.go 的TestNameTemplate。4.3 将测量名添加为标签[[processors.template]] tag measurement template {{ .Name }}处理前后对比- cpu,hostnamelocalhost time_idle42 cpu,hostnamelocalhost,measurementcpu time_idle42把测量名显式沉淀为标签便于在 InfluxDB、Prometheus 等时序存储中按测量名做统一的标签维度查询。对应测试TestName见 template_test.go。4.4 添加年份标签类似 date 处理器的用法[[processors.template]] tag year template {{.Time.UTC.Year}}利用Time()返回的time.Time进行链式调用UTC()转为 UTC 时区、Year()取年份即可为每条指标打上采集年份标签可用于数据按时间分桶或归档。4.5 将全部字段打包为单个标签消息型输出场景当需要把全部字段连同值拼进一条消息转发给 Syslog、GroundWork 等监控系统时可直接使用.Fields或.Tags输出 map 的字符串表示[[processors.template]] tag message template Message about {{.Name}} fields: {{.Fields}}处理前后对比- cpu,hostnamelocalhost time_idle42 cpu,hostnamelocalhost,messageMessage\ about\ cpu\ fields:\ map[time_idle:42] time_idle42更高级的写法——用range逐字段迭代并换行格式化得到多行消息[[processors.template]] tag message template Message about {{.Name}} fields: {{ range $field, $value : .Fields -}} {{$field}}:{{$value}} {{ end }}处理前后对比- cpu,hostnamelocalhost time_idle42 cpu,hostnamelocalhost,messageMessage\ about\ cpu\ fields:\ntime_idle:42\n time_idle42注意这里使用了 TOML 的三引号包裹多行模板range循环后的-用于去除相邻空白这是 Go 模板控制流的常用写法。4.6 将完整指标作为标签调试与原始数据透传[[processors.template]] tag metric template {{.}}处理前后对比- cpu,hostnamelocalhost time_idle42 cpu,hostnamelocalhost,metriccpu\ map[hostname:localhost]\ map[time_idle:42]\ 1257894000000000000 time_idle42{{.}}输出TemplateMetric.String()的结果格式为“测量名 标签 map 字段 map UnixNano 时间戳”。测试TestString、TestDot验证了该行为见 template_test.go输出形如test1 map[tag1:value1] map[value:1.23] 1257894000000000000。五、源码级实现原理插件核心实现在 template.go处理流程可分为两个阶段5.1 Init 阶段模板预编译func (r *Template) Init() error { r.tmplTag, err template.New(tag template).Funcs(sprig.TxtFuncMap()).Parse(r.Tag) ... r.tmplValue, err template.New(value template).Funcs(sprig.TxtFuncMap()).Parse(r.Template) ... }两个模板标签名模板、标签值模板在Init()中一次性解析并注册 Sprig 函数库解析失败会直接返回错误例如模板语法错误插件无法启动。这意味着模板的合法性检查发生在启动阶段而非运行阶段符合 Telegraf 插件Init() - Apply()的生命周期约定。5.2 Apply 阶段逐指标执行func (r *Template) Apply(in ...telegraf.Metric) []telegraf.Metric { for _, raw : range in { m : raw if wm, ok : raw.(telegraf.UnwrappableMetric); ok { m wm.Unwrap() } tm, ok : m.(telegraf.TemplateMetric) if !ok { r.Log.Errorf(metric of type %T is not a template metric, raw) continue } ... raw.AddTag(tag, value) } return in }值得注意的工程细节指标不丢失即使某条指标模板执行失败如引用了不存在的标签导致空值拼接插件也只是记录错误日志并跳过该条绝不会丢弃或吞掉指标。测试TestMetricMissingTagsIsNotLost见 template_test.go专门断言了“输入条数 输出条数”这一不变量。Unwrap()兼容对实现了UnwrappableMetric的跟踪型指标先解包再断言为TemplateMetric确保与 Telegraf 的指标跟踪机制metric/tracking.go协同工作测试TestTracking验证了带投递通知的指标经模板处理后仍能正确触发Accept()回调。模板结果直接落标签标签名、标签值两个模板执行结果拼接后通过raw.AddTag(tag, value)写入原指标因此处理器输出的是在原始指标上新增标签的新指标测量名、字段、时间戳均保持不变。5.3 Sprig 函数加持由于Init()中注入了sprig.TxtFuncMap()模板可以自由调用 Sprig 提供的字符串、列表、数学等函数。测试TestSprig见 template_test.go展示了典型组合[[processors.template]] tag {{ .Tag foo | lower }} template {{ .Name | upper }}即标签名先取foo标签值再转小写标签值取测量名转大写——|管道是 Go 模板的标准用法。六、处理器顺序与全局配置Template Processor 同样支持 Telegraf 的全局/插件级配置能力例如通过namepass、namedrop、tagexclude等过滤器限定其作用范围或通过order指定与其它处理器的执行先后。完整说明参见 CONFIGURATION.md。在处理器编排上需注意模板处理器读取的是到达它时指标已有的标签与字段。若需要先由其它处理器如 rename、regex整理标签再基于整理结果做模板拼接应合理设置order隐式顺序按配置文件中[[processors.template]]出现的位置显式顺序可用order指定。从源码结构看处理器经由 processors 注册机制 注册为template名称。七、延伸同一模板引擎在其它组件中的应用TemplateMetric与 Go 模板 Sprig 的组合并非 template 处理器独有。仓库中的 template 序列化器 使用了完全相同的机制在Init()中解析模板并注入sprig.TxtFuncMap()在序列化时对指标执行同样的Unwrap()与TemplateMetric断言支持单指标模板与批量模板batch_template。两者的差异在于处理器把模板结果写入标签序列化器把模板结果作为输出数据的正文。这意味着你在此处学到的全部模板写法都可以直接复用到输出序列化场景而当需要把模板结果用于动态路由时优先选择 processor 方案因为路由标签必须附着在指标上随指标流转。八、排查与使用建议模板执行失败不会丢指标只会输出错误日志failed to execute tag name template/failed to execute value template可通过 Telegraf 日志定位问题参考 LOGGING.md。单引号优先模板字符串在 TOML 中尽量使用单引号或三引号避免转义错误。注意拼接空值{{ .Tag xxx }}在标签不存在时返回空字符串拼接出的标签值可能形如.debug前导点可用 Sprig 的default函数兜底例如{{ .Tag hostname | default unknown }}.{{ .Tag level }}。标签值长度与基数生成的标签会成为时序数据的维度注意控制其基数cardinality避免因拼接时间戳等高频变化值造成存储膨胀。版本前提本插件自 Telegraf v1.14.0 引入TemplateMetric接口、UnwrappableMetric解包逻辑均以当前仓库源码为准。参考文件索引官方插件文档plugins/processors/template/README.md插件源码plugins/processors/template/template.go样例配置plugins/processors/template/sample.conf单元测试plugins/processors/template/template_test.goTemplateMetric接口定义metric.go默认实现metric/metric.go同引擎序列化器plugins/serializers/template/template.go【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价