Telegraf 插件与配置弃用机制全解析:基于 tsd-001 规范的弃用、通知与移除完整流程
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
导读
Telegraf 的插件生态随着时间不断膨胀,部分插件、插件选项和特性逐渐失去价值或被新方案取代。本文以仓库内 tsd-001-deprecation.md 规范为核心,系统讲解 Telegraf 如何通过**弃用(Deprecation)—警告(Warning)—报错(Error)—移除(Removal)**四个阶段管理插件生命周期,并结合 config/deprecation.go、plugins/inputs/deprecations.go 等源码实现,剖析deprecations.go注册表、结构体deprecated标签、Init()内联告警三种注解方式的底层原理。读完本文,你将能按照官方流程为插件添加弃用声明、配置用户可见的替换提示,并在计划版本中安全移除废弃代码。
规范背景与目标
tsd-001是 Telegraf 仓库 docs/specs 规范系列中的第一份正式规范(tsd即 Telegraf Spec Document),其目标非常明确:
Specifies the process of deprecating and removing plugins, plugin settings including values of those settings or features.
简而言之,该规范定义了**如何弃用并最终移除插件、插件选项(option)以及选项值(option value)**的完整流程,包括:
- 统一的弃用时间线与最小时间窗口;
- 在代码中标注弃用信息的框架(framework);
- 向用户广播弃用信息、引导迁移的通知机制。
规范的关键词是procedure, removal, all plugins,即这是一份面向全部插件类别的通用程序性文档,涵盖 inputs、outputs、processors、aggregators、secretstores 等所有插件注册表。
用户视角:弃用警告如何呈现
启动时的警告信息
在弃用阶段(deprecation phase),Telegraf 会在启动时向用户打印一条警告(warning)。规范给出了标准格式:
Plugin "inputs.logparser" deprecated since version 1.15.0 and will be removed in 1.40.0: use 'inputs.tail' with 'grok' data format instead该信息包含三个关键要素:
since版本:引入弃用(deprecation)的版本,即从哪个版本开始警告;removal版本:计划移除代码的版本;- 替换提示(notice):面向用户的替代方案建议,例如“改用
inputs.tail配合grok数据格式”。
选项和选项值的弃用会打印结构类似的消息。注意:警告阶段 Telegraf 必须照常运行,即使配置中仍在使用被弃用的插件或选项,也不能影响功能,从而给用户留出迁移时间。
到达移除版本后的报错
当版本推进到声明中的移除版本(示例中为v1.40.0)后,警告会升级为错误(error),直接阻止 Telegraf 启动:
- 对已移除的插件:配置中出现即报错,并包含与警告相同的信息(since 版本、removal 版本、替换提示);
- 对已移除的选项/选项值:按“无效配置项”处理,同样必须报错;
- 此时 Telegraf 应停止运行,直到用户从配置文件中删除所有被弃用的内容。
从源码角度看,这一“警告→错误”的升级并非硬编码,而是由 config/deprecation.go 中的determineEscalation()根据当前 Telegraf 版本与RemovalIn/Since版本的比较动态计算日志级别:当前版本 ≥ 移除版本时为telegraf.Error,当前版本 ≥ 引入版本时为telegraf.Warn,否则为telegraf.None。而 config/config.go 中各个插件类别的注册逻辑会在发现inputs.Deprecations[name]等注册表条目时,配合printUserDeprecation()完成提示与报错返回。
时间框架与设计考量
规范对弃用与移除之间的时间窗口提出了明确要求:
- 必须有替代方案:插件、选项或选项值只应在存在合适替代方案时才允许弃用;
- 至少提前一年半:弃用时间应至少早于移除一年半。按当时版本节奏换算,这大约对应六个 minor 版本;
- 特殊情况下可延长:某些场景需要更长的过渡期以确保用户平滑迁移,可适当拉长时间。
两个阶段的行为约束可以概括为下表:
| 阶段 | 时间条件 | 日志级别 | Telegraf 行为 |
|---|---|---|---|
| 弃用阶段 | Since≤ 当前版本 <RemovalIn | Warning | 正常启动运行,打印弃用警告与替换提示 |
| 移除阶段 | 当前版本 ≥RemovalIn | Error | 停止启动,直到配置中移除全部弃用内容 |
一个值得注意的细节是:如果RemovalIn未显式指定,determineEscalation()会默认将移除版本设置为Since的下一个大版本(见 config/deprecation.go),即1.x默认为2.0.0。这在deprecated标签只有两个字段(如"1.11.0;use 'url' instead")时尤为常见。
弃用流程总览
规范给出的完整流程包含三个主要步骤:
- 提交 Issue(File issue):说明要弃用什么、为什么弃用,并确定计划移除的版本;在 Issue 中与维护者达成一致并取得 sign-off 后再继续。
- 提交弃用 PR(Submit deprecation pull-request):在代码中添加弃用信息,并同步更新插件
README.md。PR 合并、Telegraf 发布后,进入等待期,直到目标移除版本到来。 - 提交移除代码的 PR(Submit pull-request for removing code):在
RemovalIn版本(示例中为1.40.0)的所有 scheduled bugfix 发布完成后,正式移除弃用代码。
下面分别展开三种弃用对象的操作细节。
弃用一个插件(Deprecating a plugin)
在 deprecations.go 注册表中登记
每个插件类别(inputs、outputs、processors、aggregators、secretstores、parsers、serializers)目录下都有独立的deprecations.go注册表文件。弃用插件时,需要向对应类别文件添加如下格式的条目:
"<plugin name>": { Since: "<x.y.z format version of the next minor release>", RemovalIn: "<x.y.z format version of the plugin removal>", Notice: "<user-facing hint e.g. on replacements>", },以规范中inputs.logparser为例,写入plugins/inputs/deprecations.go的条目为:
"logparser": { Since: "1.15.0", RemovalIn: "1.40.0", Notice: "use 'inputs.tail' with 'grok' data format instead", },这里注意规范原文示例中RemovalIn行缺少末尾逗号,实际合法的 Go map 条目必须带逗号。注册表背后对应的数据结构定义在 plugin.go:
// DeprecationInfo contains information for marking a plugin deprecated. type DeprecationInfo struct { // Since specifies the version since when the plugin is deprecated Since string // RemovalIn optionally specifies the version when the plugin is scheduled for removal RemovalIn string // Notice for the user on suggested replacements etc. Notice string }完成登记后,从版本1.15.0起用户就会看到包含Notice的弃用警告,插件可在1.40.0正式移除。
仓库中的真实弃用案例
当前仓库 plugins/inputs/deprecations.go 中记录了大量真实弃用条目,例如:
| 插件 | Since | RemovalIn | Notice |
|---|---|---|---|
aerospike | 1.30.0 | 1.40.0 | use 'inputs.prometheus' with the Aerospike Prometheus Exporter instead |
logparser | 1.15.0 | 1.35.0 | use 'inputs.tail' with 'grok' data format instead |
httpjson | 1.6.0 | 1.30.0 | use 'inputs.http' instead |
io | 0.10.0 | 1.30.0 | use 'inputs.diskio' instead |
cassandra | 1.7.0 | 1.30.0 | use 'inputs.jolokia2' with the 'cassandra.conf' example configuration instead |
sflow | 1.31.0 | 1.40.0 | use 'inputs.netflow' instead |
tcp_listener/udp_listener | 1.3.0 | 1.30.0 | use 'inputs.socket_listener' instead |
注意实际仓库中logparser的RemovalIn是1.35.0(而非规范示例中的1.40.0),说明规范文档中的版本仅是演示性占位符,真实移除版本以注册表为准。类似的注册表还存在于 plugins/outputs/deprecations.go、plugins/processors/deprecations.go、plugins/aggregators/deprecations.go、plugins/secretstores/deprecations.go 等文件中。
更新插件 README
除代码注册表外,还必须更新被弃用插件的README.md,添加一段说明:自哪个版本弃用、何时移除、替代方案是什么。规范给出的段落模板:
**Deprecated in version v1.15.0 and scheduled for removal in v1.40.0**: Please use the [tail][] plugin with the [`grok` data format][grok parser] instead!仓库中的弃用插件 README(如migrations目录下inputs_logparser等迁移测试用例)也遵循了这一模式,将弃用提示与推荐替代路径写在文档最显眼处。
查询弃用插件:CLI 支持
除了启动警告,Telegraf 还提供了两个命令行入口帮助用户发现弃用内容:
telegraf --deprecation-list:打印所有被弃用的插件与插件选项列表(见 cmd/telegraf/main.go),实现由PrintDeprecationList完成,输出格式为名称 + 日志级别 + since/removal 版本 + Notice;telegraf plugins <category> --deprecated:仅列出指定类别(inputs、outputs、processors、aggregators 等)中被弃用的插件名(见 cmd/telegraf/cmd_plugins.go)。
此外,telegraf --sample-config生成的示例配置中,被弃用插件会以## DEPRECATED: ...注释块显式标注(见 cmd/telegraf/printer.go)。
弃用一个选项(Deprecating an option)
从 sample.conf 移除并打标签
弃用插件选项时,需要做两件事:
- 从该插件的
sample.conf(示例配置)中删除该选项,避免新用户继续采用; - 在代码结构体字段上添加
deprecated标签,格式为"Since;RemovalIn;Notice"三段,以分号分隔。
规范示例:弃用inputs.example中的ssl_enabled选项,并计划在1.40.0移除:
type Example struct { ... SSLEnabled bool `toml:"ssl_enabled" deprecated:"1.3.0;1.40.0;use 'tls_*' options instead"` }标签的最后一个元素是面向用户的提示(与插件弃用的Notice同义)。省略RemovalIn时(如"1.11.0;use 'url' instead"),会按前面提到的规则默认推导为下一个大版本。
标签的解析与遍历
deprecated标签的解析发生在 config/deprecation.go 的collectDeprecationInfo()中:通过strings.SplitN(field.Tag.Get("deprecated"), ";", 3)拆分三段——第一段为Since,第三段为Notice,第二段(如果存在)为RemovalIn;随后对每个已设置的字段调用determineEscalation()判断日志级别。
结构体字段的遍历由walkPluginStruct()(config/deprecation.go)以**深度优先搜索(DFS)**完成,可以递归进入嵌套结构体、数组/切片和 map 元素,因此deprecated标签同样适用于嵌套的配置子结构。
仓库中的真实选项弃用案例
当前仓库中有大量真实案例,例如:
- config/config.go:
LogTarget string toml:"logtarget" deprecated:"1.32.0;1.40.0;use 'logformat' and 'logfile' instead" - plugins/inputs/mock/mock.go:
Min/Max弃用于1.28.2,1.35.0移除,改用start/step - plugins/inputs/http_response/http_response.go:
bearer_token弃用于1.39.0,1.45.0移除,改用token - plugins/inputs/activemq/activemq.go:
server/port弃用于1.11.0,改用url(未显式指定移除版本) - plugins/common/mqtt/mqtt.go:
client_trace弃用于1.37.0,1.45.0移除,改用log_level 'trace' - plugins/outputs/kafka/kafka.go:
metric_name_header弃用于1.39.0,1.45.0移除,改用headers
这些案例覆盖了“指定移除版本”“不指定移除版本”“提示忽略该选项(如net插件的ignore_protocol_stats标记为 option is ignored)”等不同策略。
弃用一个选项值(Deprecating an option-value)
某些情况下,被弃用的不是整个选项,而是某个特定的取值(例如枚举值被新值取代)。规范的流程是:
- 从
sample.conf中删除该弃用取值; - 如果该值确实会被使用,则在代码中调用
models.PrintOptionDeprecationNotice主动打印告警:
func (e *Example) Init() error { ... if e.Mode == "old" { models.PrintOptionDeprecationNotice(telegraf.Warn, "inputs.example", "mode", telegraf.DeprecationInfo{ Since: "1.23.1", RemovalIn: "1.40.0", Notice: "use 'v1' instead", }) } ... return nil }这段代码通常放在插件的Init()方法中(Init是 plugin.go 定义的Initializer接口,所有插件类型均可选实现,在启动时执行一次性初始化)。当mode取值为"old"时即触发警告。
与之配套的底层函数是 config/deprecation.go 中的PrintOptionValueDeprecationNotice(),其输出格式为:
Value "foobar" for option "option" of plugin "test" deprecated since version 1.25.0 and will be removed in 1.29.0: please check而models.PrintOptionDeprecationNotice则包装了选项层面的提示(见 models/common.go 相关实现),两者的日志级别仍由determineEscalation()依据当前版本动态决定。
移除代码(Removing the code)
移除时机与范围
一旦进入RemovalIn版本(示例中为1.40.0),且该版本之前的所有 scheduled bugfix 发布已完成,就可以提交 PR 正式移除代码。规范强调移除必须彻底,包括:
- 移除插件、插件选项或选项值本身;
- 移除所有引用这些内容的代码;
- 移除插件类别的
all文件(例如plugins/inputs/all/中的注册文件); - 清理测试用例(包括其他插件中引用该插件的测试);
- 更新 README 及其他文档;
- 在
CHANGELOG.md中添加Important Changes章节,描述移除内容并引用对应 PR。
保留弃用信息
特别重要的是:即使插件代码已被移除,也应保留deprecations.go中的弃用信息条目。这样当用户从非常老的版本升级时,仍然可以在注册表中找到该插件曾经的弃用与替换说明,作为迁移参考。从 config/config.go 的处理逻辑看,注册表中仍存在的条目会在配置加载时触发“plugin deprecated”错误,从而让使用旧配置的用户明确得知失败原因。
历史弃用插件的参考实现
仓库 migrations 提供了弃用插件的迁移参考,例如inputs_logparser.go、inputs_io.go、inputs_snmp_legacy.go、outputs_riemann_legacy.go等迁移模块,会在配置加载时自动将旧插件改写为推荐的新插件,进一步降低用户的迁移成本。
测试与验证:deprecation_test.go 如何保障行为
仓库为弃用机制提供了完善的单元测试,位于 config/deprecation_test.go,包含三个核心测试函数:
TestPluginDeprecation:验证插件整体弃用时的警告/错误输出与日志级别;TestPluginOptionDeprecation:验证PrintOptionDeprecationNotice的输出。测试通过伪造 Telegraf 版本号(如1.30.0)并切换日志输出到缓冲区,断言不同Since/RemovalIn组合下分别产生 Error 级别(如since 1.23.0, removal 1.29.0)、Warn 级别(如removal 2.0.0)、默认推导移除版本(无 removal 信息时按2.0.0处理)以及无输出(None)四种结果;TestPluginOptionValueDeprecation:验证PrintOptionValueDeprecationNotice对选项值的告警,输出格式为Value "foobar" for option "option" of plugin "test" ...。
这些测试直接固化了规范中“警告→错误→无提示”的三种状态,保证了后续任何对弃用逻辑的修改都能被 CI 快速发现。此外 cmd/telegraf/main_test.go 的TestDeprecationListFlag验证了--deprecation-list标志的输出。
总结:一条规范的弃用生命周期
综合规范与源码,Telegraf 插件/选项/选项值的弃用生命周期可以归纳为:
- 规划:在 Issue 中说明弃用对象与理由,确定
Since与RemovalIn(间隔至少六个 minor 版本),并确保存在替代方案; - 标注:根据对象类型选择三种机制之一——
deprecations.go注册表(插件)、结构体deprecated标签(选项)、Init()内PrintOptionDeprecationNotice调用(选项值),同时更新 README 与sample.conf; - 等待:弃用阶段打印 Warning,Telegraf 正常运行;用户在此期间迁移配置;
- 移除:到
RemovalIn版本后,Warning 升级为 Error 阻止启动;提交 PR 彻底清理代码,但保留注册表条目作为历史参考,并在 CHANGELOG 记录Important Changes。
这套机制在 config/deprecation.go 中以determineEscalation()版本比较 +collectDeprecationInfo()反射扫描为核心,配合各插件类别的Deprecations注册表与 CLI 的--deprecation-list、plugins --deprecated查询入口,构成了 Telegraf 生态可持续演进、用户可平滑迁移的完整闭环。对于插件作者与维护者而言,遵循 tsd-001 规范即可让每次弃用都有据可依、有迹可循。
延伸阅读
- 规范原文:docs/specs/tsd-001-deprecation.md
- 规范体系总览:docs/specs/README.md
- 弃用核心实现:config/deprecation.go
- 弃用单元测试:config/deprecation_test.go
- 插件弃用注册表:plugins/inputs/deprecations.go、plugins/outputs/deprecations.go、plugins/processors/deprecations.go、plugins/aggregators/deprecations.go
- 弃用信息数据结构:plugin.go
- 弃用配置加载逻辑:config/config.go
- 弃用列表 CLI 入口:cmd/telegraf/main.go
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考