Telegraf Consul 输入插件:采集 Hashicorp Consul 健康检查状态的完整指南
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
导读
Consul 输入插件(inputs.consul)是 Telegraf 内置的采集器,用于通过 Consul 官方 API 收集 Consul 集群中所有已注册健康检查(health checks)的状态。它不采集 Consul 自身的内部遥测指标(telemetry metrics),这些统计可通过 Consul 的 StatsD 协议另行上报。读完本文,你将掌握该插件的全部配置参数、两种 metric_version 的字段映射差异、tag_delimiter 的服务标签拆分机制,以及如何结合源码理解其数据采集与加工流程,从而快速搭建基于 Consul 的服务健康监控链路。
适用说明:该插件从 Telegraf v1.0.0 起内置(⭐ v1.0.0),分类为 server 类型,支持所有平台(💻 all)。本文内容基于当前仓库实现验证。
一、插件能力与工作方式
inputs.consul插件的核心任务只有一个:拉取 Consul 中所有健康检查的状态并转换为 Telegraf 指标。
其工作流程在源码 plugins/inputs/consul/consul.go 中非常清晰:
Init()阶段根据配置构造 Consul API 客户端(含地址、scheme、ACL token、HTTP Basic Auth、TLS 配置);Gather()阶段调用c.client.Health().State("any", nil)拉取所有健康检查状态("any"表示不按状态过滤);gatherHealthCheck()将每条健康检查记录拆分为 Telegraf 的 tags 与 fields,逐条写入 Accumulator。
// plugins/inputs/consul/consul.go func (c *Consul) Gather(acc telegraf.Accumulator) error { checks, _, err := c.client.Health().State("any", nil) if err != nil { return err } c.gatherHealthCheck(acc, checks) return nil }从源码结构可以推断:插件是轮询型(polling)输入,每次Gather都完整请求一次 Consul 的健康状态接口,采集频率由 Telegraf agent 的interval或插件自身的interval覆盖项控制。
需要特别注意的是:插件不会上报 Consul 自身的运行指标(如 Raft 状态、服务发现请求量等)。如果你需要这些数据,应启用 Consul 的 StatsD 遥测输出,再由 Telegraf 的 statsd 输入插件 接收。
二、插件注册与启用
该插件通过inputs.Add("consul", ...)注册到插件注册表(见 consul.go)。在标准构建中,它由 plugins/inputs/all/consul.go 以空导入方式注册进主程序:
//go:build !custom || inputs || inputs.consul import _ "github.com/influxdata/telegraf/plugins/inputs/consul" // register plugin因此你只需在配置文件中加入[[inputs.consul]]段并重启 Telegraf 即可启用;若使用自定义构建(custom builder),则需保留inputs.consul的构建标签。
快速生成配置:
# 生成完整默认配置 telegraf config > telegraf.conf # 仅生成 consul 输入 + influxdb 输出的配置 telegraf config --input-filter consul --output-filter influxdb更详细的做法参见 docs/CONFIGURATION.md。
三、完整配置参数详解
插件示例配置位于 plugins/inputs/consul/sample.conf,同时通过//go:embed sample.conf内嵌到二进制中(consul.go),运行telegraf config时会自动输出该段配置。下面是带完整注释与默认值的配置块:
# Gather health check statuses from services registered in Consul [[inputs.consul]] ## Consul server address # address = "localhost:8500" ## URI scheme for the Consul server, one of "http", "https" # scheme = "http" ## Metric version controls the mapping from Consul metrics into ## Telegraf metrics. Version 2 moved all fields with string values ## to tags. ## ## example: metric_version = 1; deprecated in 1.16 ## metric_version = 2; recommended version # metric_version = 1 ## ACL token used in every request # token = "" ## HTTP Basic Authentication username and password. # username = "" # password = "" ## Data center to query the health checks from # datacenter = "" ## Optional TLS Config # tls_ca = "/etc/telegraf/ca.pem" # tls_cert = "/etc/telegraf/cert.pem" # tls_key = "/etc/telegraf/key.pem" ## Use TLS but skip chain & host verification # insecure_skip_verify = true ## Consul checks' tag splitting # When tags are formatted like "key:value" with ":" as a delimiter then # they will be split and reported as proper key:value in Telegraf # tag_delimiter = ":"各参数的映射关系可直接在源码结构体 Consul 中印证:
| 参数 | TOML 字段(源码) | 默认值 | 说明 |
|---|---|---|---|
address | Address string | localhost:8500 | Consul 服务器地址(host:port),对应 Consul APIDefaultConfig().Address |
scheme | Scheme string | http | URI 协议,仅支持http与https二选一 |
metric_version | MetricVersion int | 1 | 指标版本。2为推荐版本,1自 1.16 起标记废弃,计划在 1.40 移除 |
token | Token string | 空 | Consul ACL token,附加到每个请求 |
username/password | Username/Password string | 空 | HTTP Basic Authentication 凭据 |
datacenter | Datacenter string | 空(默认数据中心) | 指定查询健康检查的数据中心 |
tls_ca/tls_cert/tls_key | tls.ClientConfig内嵌 | 空 | TLS 客户端证书配置,通过 plugins/common/tls 复用 |
insecure_skip_verify | tls.ClientConfig内嵌 | false | 跳过 TLS 证书链与主机名校验(仅测试环境建议开启) |
tag_delimiter | TagDelimiter string | 空(不拆分) | 服务标签拆分分隔符,典型取: |
3.1 连接与认证参数说明
源码 Init() 展示了这些参数如何落到 Consul 官方 Go 客户端上:
address、scheme、datacenter、token直接写入api.DefaultConfig()的对应字段;- 配置了
username时会构造api.HttpBasicAuth结构(仅设置用户名时 Basic Auth 才生效,因此password通常与username成对使用); - TLS 配置统一通过
c.ClientConfig.TLSConfig()生成*tls.Config,再挂载到http.Transport.TLSClientConfig上。这意味着httpsscheme 配合tls_ca/tls_cert/tls_key可实现标准的双向 TLS 认证。
3.2 metric_version 的废弃提示
Init()中有一段关键的废弃提示逻辑:当MetricVersion != 2时,Telegraf 会打印配置项废弃通知,提示用户升级到metric_version = 2,该通知对应Since: 1.16.0、RemovalIn: 1.40.0(见 consul.go):
telegraf_config.PrintOptionValueDeprecationNotice("inputs.consul", "metric_version", 1, telegraf.DeprecationInfo{ Since: "1.16.0", RemovalIn: "1.40.0", Notice: `please update to 'metric_version = 2'`, })实践建议:新环境直接使用metric_version = 2;已有metric_version = 1的存量环境,应规划在 1.40 版本发布前完成迁移,因为届时 v1 映射将被移除。
四、指标(Metrics)结构与两种版本对比
插件输出唯一的测量(measurement)名称consul_health_checks。两种 metric_version 的核心差异在于:字符串型字段在 v2 中全部提升为标签(tags),这与 Telegraf 推荐的“可枚举维度进 tag、数值进 field”最佳实践一致。
4.1 metric_version = 1
consul_health_checks- tags:
node(健康检查/服务注册所在的节点)service_namecheck_id
- fields:
check_nameservice_idstatuspassing(integer)critical(integer)warning(integer)
- tags:
4.2 metric_version = 2(推荐)
consul_health_checks- tags:
nodeservice_namecheck_idcheck_nameservice_idstatus
- fields:
passing(integer)critical(integer)warning(integer)
- tags:
源码 gatherHealthCheck() 中两种版本的映射逻辑一目了然:
if c.MetricVersion == 2 { tags["check_name"] = check.Name tags["service_id"] = check.ServiceID tags["status"] = check.Status } else { record["check_name"] = check.Name record["service_id"] = check.ServiceID record["status"] = check.Status }而三个数值字段在两种版本下行为一致:每条记录都会初始化passing=0, critical=0, warning=0,然后仅把当前状态对应的字段置1:
record["passing"] = 0 record["critical"] = 0 record["warning"] = 0 record[check.Status] = 14.3 状态字段语义
passing、critical、warning是健康检查状态的整数表示:某值为1表示本次采样时健康检查正处在该状态,其余为0。status则是同一状态的字符串表示(passing/critical/warning,以及 Consul 可能返回的其他状态值)。二者配合,既可直接做数值求和/告警阈值,也可按状态分组查询。
五、服务标签拆分:tag_delimiter 详解
Consul 中的服务可以携带多个标签(ServiceTags,如version:v1、env:prod)。默认情况下,这些标签会原样复制为 Telegraf 的 tag(标签名与值相同);而设置tag_delimiter后,形如key:value的标签会被拆分为真正的key=valuetag。
源码逻辑(consul.go):
for _, checkTag := range check.ServiceTags { if c.TagDelimiter != "" { splittedTag := strings.SplitN(checkTag, c.TagDelimiter, 2) if len(splittedTag) == 1 && checkTag != "" { tags[checkTag] = checkTag } else if len(splittedTag) == 2 && splittedTag[1] != "" { tags[splittedTag[0]] = splittedTag[1] } } else if checkTag != "" { tags[checkTag] = checkTag } }需要注意三个细节:
- 使用
SplitN(tag, delimiter, 2)只按第一个分隔符拆分一次,因此值内部可以再含分隔符。例如测试用例中的tagkey:value:stillvalue会被拆成tagkey="value:stillvalue",而不是tagkey="value"(见 consul_test.go); - 若拆分后右侧为空(如标签为
key:),该标签被丢弃; - 若标签中不含分隔符,则保持原样复制(
tags[checkTag] = checkTag)。
5.1 拆分行为对照(来自测试用例)
以测试样例的ServiceTags: ["bar", "env:sandbox", "tagkey:value:stillvalue"]为例(consul_test.go):
| 场景 | 生成的 tags | 测试用例 |
|---|---|---|
未设置tag_delimiter | bar=bar、env:sandbox=env:sandbox、tagkey:value:stillvalue=tagkey:value:stillvalue | TestGatherHealthCheck |
tag_delimiter = ":" | bar=bar、env=sandbox、tagkey=value:stillvalue | TestGatherHealthCheckWithDelimitedTags |
需要特别提醒:健康检查自带的基础标签(
node、service_name、check_id等)是独立于ServiceTags处理的,tag_delimiter只作用于 Consul 服务标签(ServiceTags),不会影响上述基础标签。
六、示例输出解析
README 提供了两行典型输出(时间戳已按 influx line protocol 格式给出):
consul_health_checks,host=wolfpit,node=consul-server-node,check_id="serfHealth" check_name="Serf Health Status",service_id="",status="passing",passing=1i,critical=0i,warning=0i 1464698464486439902 consul_health_checks,host=wolfpit,node=consul-server-node,service_name=www.example.com,check_id="service:www-example-com.test01" check_name="Service 'www.example.com' check",service_id="www-example-com.test01",status="critical",passing=0i,critical=1i,warning=0i 1464698464486519036逐行解读:
- 第一行是节点自身的健康检查(
serfHealth,Consul 内置的节点存活检查):无服务关联(service_id为空),状态为passing,因此passing=1i, critical=0i, warning=0i; - 第二行是注册在
www.example.com服务上的检查(service:www-example-com.test01):服务 ID 为www-example-com.test01,状态为critical,因此passing=0i, critical=1i, warning=0i。
注意第一行没有service_nametag(服务级检查才有),这正是“节点级检查 vs 服务级检查”的区分信号,在做告警分组时值得留意。
七、测试用例:行为即规范
插件的行为边界被四个测试用例完整锁定(plugins/inputs/consul/consul_test.go),是理解插件语义的最佳参考:
| 测试函数 | 验证点 |
|---|---|
TestGatherHealthCheck | v1 下字符串字段进 fields,无分隔符时标签原样复制 |
TestGatherHealthCheckWithDelimitedTags | v1 +tag_delimiter=":"的拆分行为 |
TestGatherHealthCheckV2 | v2 下check_name/service_id/status进入 tags,fields 只剩三个整型 |
TestGatherHealthCheckWithDelimitedTagsV2 | v2 + tag 拆分的组合行为 |
这些测试使用 Telegraf 的 testutil.Accumulator 断言指标内容,例如:
acc.AssertContainsTaggedFields(t, "consul_health_checks", expectedFields, expectedTags)如果你准备为 Consul 插件提交修改(例如新增字段),这些测试就是必须同步维护的行为契约。
八、进阶配置技巧
8.1 搭配全局/通用插件配置
inputs.consul与所有输入插件一样,支持 docs/CONFIGURATION.md 中列出的通用选项:alias、interval、precision、name_override、name_prefix、name_suffix、tags、log_level以及 metric filtering 参数。例如为 Consul 检查单独设置更高的采集频率,并追加环境标签:
[[inputs.consul]] interval = "30s" address = "consul.internal:8500" scheme = "https" metric_version = 2 tag_delimiter = ":" [inputs.consul.tags] env = "production"注意 TOML 中表头顺序:使用
[inputs.consul.tags]表语法时,需将其放在该插件定义的末尾(具体说明见 docs/CONFIGURATION.md)。
8.2 多数据中心 / 多 Consul 集群
由于 Telegraf 允许同一插件定义多次、各实例独立运行,你可以为每个数据中心或集群各定义一个[[inputs.consul]]段,并通过alias区分来源,再借助name_override避免测量名冲突:
[[inputs.consul]] alias = "dc1" address = "consul-dc1:8500" datacenter = "dc1" metric_version = 2 [[inputs.consul]] alias = "dc2" address = "consul-dc2:8500" datacenter = "dc2" metric_version = 28.3 通过环境变量注入敏感信息
ACL token、密码等敏感信息可借助 Telegraf 的环境变量替换机制从配置中剥离(docs/CONFIGURATION.md):
[[inputs.consul]] token = "${CONSUL_ACL_TOKEN}" password = "${CONSUL_PASSWORD}"8.4 与告警联动
由于每个健康检查都输出passing/critical/warning三个整型字段,最直接的告警查询是:统计critical=1的指标。例如在 InfluxDB 中:
SELECT count(*) FROM consul_health_checks WHERE critical = 1 AND time > now() - 1m GROUP BY service_name, check_id九、常见问题(FAQ)
Q1:为什么我采集不到 Consul 自身指标(如 raft、serf 等)?因为该插件只采集健康检查状态。Consul 内部遥测需要你在 Consul 侧开启 StatsD 上报,再通过 Telegraf 的 statsd 输入插件接收。
Q2:metric_version该选哪个?选2。v1 自 Telegraf 1.16 起标记废弃,计划于 1.40 移除(源码中的RemovalIn: "1.40.0")。
Q3:服务标签为什么有的变成了key=value,有的没有?只有标签中包含tag_delimiter指定分隔符的标签才会被拆分,且只按第一个分隔符拆分一次;不含分隔符的标签保持原样(标签名=标签值)。
Q4:scheme 支持哪些值?仅http与https。使用https时可配合tls_ca、tls_cert、tls_key完成 TLS 配置,用insecure_skip_verify控制证书校验。
Q5:tag_delimiter会影响 node/check_id 这些基础 tag 吗?不会。它只作用于 Consul 健康检查返回的ServiceTags(服务标签)列表。
十、相关资源
- 插件文档:plugins/inputs/consul/README.md
- 插件源码:plugins/inputs/consul/consul.go
- 单元测试:plugins/inputs/consul/consul_test.go
- 示例配置:plugins/inputs/consul/sample.conf
- 插件注册:plugins/inputs/all/consul.go
- 通用插件配置:docs/CONFIGURATION.md
- 通用 TLS 配置:plugins/common/tls
- Consul 健康检查 HTTP API 说明见 Consul 官方文档的
health state接口(插件即通过Health().State("any", nil)调用该接口)
通过本文的配置示例与源码级分析,你可以直接投入生产环境,把 Consul 中每一个注册服务的健康状态纳入 Telegraf 的统一指标管线,并与 InfluxDB、告警系统无缝衔接。
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考