Nightingale 集成指南:Categraf Prometheus 输入插件详解——用 url_label 与 Consul 服务发现统一采集 /metrics 监控数据
本指南以 Nightingale 开源仓库中 integrations/Prometheus/markdown/README.md 为核心,系统讲解用于采集 Prometheus 格式监控数据的输入插件:它的工作原理、与 telegraf/prometheus 的渊源、Consul 服务发现能力,以及新增的 url_label_key / url_label_value 标签增强特性。读完本文,你将能独立编写 conf/input.prometheus/*.toml 配置,把各类 exporter 与内置 Prometheus SDK 的组件(如 RabbitMQ、AutoMQ)接入 Nightingale,并通过模板标签准确标识每个监控数据的来源 URL。
插件定位:把 /metrics 变成 Nightingale 的监控数据源
Prometheus 插件的作用非常纯粹:抓取目标服务 /metrics 接口暴露的指标数据,解析后上报给服务端。在云原生生态中,这几乎是所有监控采集的"通用协议":
- 各类 exporter(如 MySQL exporter、Node exporter)都会暴露
/metrics接口; - 越来越多的开源组件直接内置 Prometheus SDK,原生吐出 Prometheus 格式的监控数据。
例如本仓库 integrations/RabbitMQ/markdown/README.md 就明确说明:RabbitMQ 3.8 及以上版本内置 Prometheus 插件,官方推荐直接使用 Prometheus 输入插件采集,只需执行 rabbitmq-plugins enable rabbitmq_prometheus 开启插件,其 /metrics 数据即可通过本插件抓取。这一模式正是本插件在 Nightingale 生态中的典型应用场景。
与 telegraf/prometheus 的关系:删减与改造
该插件 fork 自 telegraf/prometheus,在此基础上做了一些删减和改造,核心变化可以归纳为两点:
- 保留 Consul 服务发现:仍然支持通过 Consul 做服务发现,从而集中管理所有需要抓取的目标地址(scrape targets),适合目标地址动态变化、数量较多的场景。
- 删除 Kubernetes 部分:Kubernetes 相关的服务发现与抓取逻辑被移除,官方计划将其放到其他插件中实现,使本插件职责更聚焦于"静态地址 + Consul 服务发现"两类抓取场景。
从源码结构看,该插件的采集逻辑以"实例(instances)"为基本单位组织配置,每个实例对应一组抓取 URL,这与 telegraf 的插件风格一脉相承。
核心增强:url_label_key 与 url_label_value
为了标识监控数据是从哪个 scrape URL 拉取下来的,插件为监控数据附加一个标签(label)来标识该 URL。这一能力通过两个新增配置项实现:
| 配置项 | 作用 | 默认值 |
|---|---|---|
url_label_key |
标签的 KEY(标签名) | instance(不建议改成别的) |
url_label_value |
标签的 VALUE(标签值),支持 Go template 语法 | 为空时使用完整 URL 字符串 |
标签值模板:只取 URL 的一部分
url_label_value 为空时,标签值就是整个 URL 的内容。但在很多场景下,我们希望标签更简洁——例如多个端口对应同一台主机时,只保留主机名即可让标签维度更聚合。此时可以利用 Go template 语法做裁剪。
以 http://localhost:9104/metrics 为例,如果只想取 IP 和端口部分,可配置:
url_label_value = "{{.Host}}"
如果 HTTP scheme 部分和 /metrics Path 部分都想保留,可以这样写:
url_label_value = "{{.Scheme}}://{{.Host}}{{.Path}}"
两条模板会分别生成 localhost:9104 与 http://localhost:9104/metrics 这样的标签值。
模板变量表
文档给出的生成逻辑中,可供模板使用的变量由 url.URL 结构体映射而来,完整变量如下:
| 模板变量 | 对应字段 | 示例值(http://localhost:9104/metrics) |
|---|---|---|
{{.Scheme}} |
u.Scheme |
http |
{{.Host}} |
u.Host |
localhost:9104 |
{{.Hostname}} |
u.Hostname() |
localhost |
{{.Port}} |
u.Port() |
9104 |
{{.Path}} |
u.Path |
/metrics |
{{.Query}} |
u.RawQuery |
空 |
{{.Fragment}} |
u.Fragment |
空 |
注意 Host 与 Hostname/Port 的区别:Host 是"主机:端口"的完整组合,而 Hostname 与 Port 是拆分后的独立字段,这在按主机聚合或按端口区分的场景下非常实用。
标签生成的底层实现
原文档给出了标签生成的参考实现(GenerateLabel 方法),它完整展示了模板执行的流程:先判断 LabelValue 是否为空,为空则直接返回 (LabelKey, u.String());否则构造 dict 字典并执行 LabelValueTpl.Execute,最终返回 (LabelKey, 渲染结果):
func (ul *UrlLabel) GenerateLabel(u *url.URL) (string, string, error) {
if ul.LabelValue == "" {
return ul.LabelKey, u.String(), nil
}
dict := map[string]string{
"Scheme": u.Scheme,
"Host": u.Host,
"Hostname": u.Hostname(),
"Port": u.Port(),
"Path": u.Path,
"Query": u.RawQuery,
"Fragment": u.Fragment,
}
var buffer bytes.Buffer
err := ul.LabelValueTpl.Execute(&buffer, dict)
if err != nil {
return "", "", err
}
return ul.LabelKey, buffer.String(), nil
}
从实现可以推断:模板渲染发生在每个抓取 URL 被处理时,因此即便多个 URL 共用同一个实例配置,也能通过标签区分数据来源;若模板渲染失败(如模板语法错误),则会返回错误,配置阶段即应排查。这也解释了为何文档建议保留默认的 instance 作为标签 KEY——它与 Prometheus 生态中"instance 标识抓取目标"的语义天然一致,便于跨系统对齐标签口径。
完整配置示例逐项解读
插件配套的默认配置文件位于 integrations/Prometheus/collect/prometheus/prometheus.toml,以下是完整内容及各配置项说明:
# # collect interval
# interval = 15
[[instances]]
urls = [
# "http://localhost:19000/metrics"
]
url_label_key = "instance"
url_label_value = "{{.Host}}"
## Scrape Services available in Consul Catalog
# [instances.consul]
# enabled = false
# agent = "http://localhost:8500"
# query_interval = "5m"
# [[instances.consul.query]]
# name = "a service name"
# tag = "a service tag"
# url = 'http://{{if ne .ServiceAddress ""}}{{.ServiceAddress}}{{else}}{{.Address}}{{end}}:{{.ServicePort}}/{{with .ServiceMeta.metrics_path}}{{.}}{{else}}metrics{{end}}'
# [instances.consul.query.tags]
# host = "{{.Node}}"
# bearer_token_string = ""
# e.g. /run/secrets/kubernetes.io/serviceaccount/token
# bearer_token_file = ""
# # basic auth
# username = ""
# password = ""
# headers = ["X-From", "categraf"]
# # interval = global.interval * interval_times
# interval_times = 1
# labels = {}
# support glob
# ignore_metrics = [ "go_*" ]
# support glob
# ignore_label_keys = []
# timeout for every url
# timeout = "3s"
## Optional TLS Config
# use_tls = false
# tls_min_version = "1.2"
# tls_ca = "/etc/categraf/ca.pem"
# tls_cert = "/etc/categraf/cert.pem"
# tls_key = "/etc/categraf/key.pem"
## Use TLS but skip chain & host verification
# insecure_skip_verify = true
各配置项的作用如下:
interval:整个实例的采集间隔(秒)。不设置时使用全局采集间隔。urls:要抓取的/metrics地址列表,可配置多个 URL,每个地址都会被逐一抓取并打上来源标签。url_label_key/url_label_value:上文所述的来源标签键与模板化标签值。[instances.consul]:Consul 服务发现段。enabled开启后,从agent指定的 Consul 地址查询服务,query_interval控制查询频率;[[instances.consul.query]]用于声明要发现的服务(name/tag),url支持 Go template 动态拼出抓取地址(可基于.ServiceAddress、.Address、.ServicePort、.ServiceMeta.metrics_path等字段),[instances.consul.query.tags]则可以为动态发现的目标附加额外标签(如host = "{{.Node}}")。bearer_token_string/bearer_token_file:Bearer Token 认证,后者从文件读取令牌(如 Kubernetes service account token)。username/password:Basic Auth 认证。headers:附加自定义请求头,例如["X-From", "categraf"]。interval_times:实例采集间隔倍数,实际间隔 = 全局间隔 ×interval_times。labels:为该实例所有指标附加的固定标签,如labels = { job = "rabbitmq" }。ignore_metrics:忽略指定指标,支持 glob 通配,如[ "go_*" ]可过滤掉 Go runtime 指标。ignore_label_keys:忽略指定标签键,同样支持 glob。timeout:每个 URL 的抓取超时时间,如"3s"。- TLS 相关:
use_tls、tls_min_version(如1.2)、tls_ca/tls_cert/tls_key(证书路径)、insecure_skip_verify(跳过链与主机校验)——用于以 HTTPS 方式抓取受保护的目标。
实战:把 RabbitMQ 与 AutoMQ 的 /metrics 接入 Nightingale
RabbitMQ:一行命令开启,一个文件接入
RabbitMQ 3.8+ 内置 Prometheus 插件,开启后默认监听 15692 端口。先验证数据可达:
rabbitmq-plugins enable rabbitmq_prometheus
curl -fsS http://127.0.0.1:15692/metrics | grep rabbitmq_build_info
然后按 integrations/RabbitMQ/markdown/README.md 的推荐,新建 conf/input.prometheus/rabbitmq.toml:
interval = 15
[[instances]]
urls = ["http://127.0.0.1:15692/metrics"]
url_label_key = "instance"
url_label_value = "{{.Host}}"
labels = { job = "rabbitmq" }
这里 url_label_value = "{{.Host}}" 把来源标签收敛为主机名,labels 再补一个 job 固定标签用于标识业务归属。集成目录中的模板按内置 Prometheus 指标验证过,需要创建真实的 exchange、queue 并执行 publish/consume,才能在面板上看到吞吐、积压和确认相关数据。注意:RabbitMQ 低于 3.8 时没有内置 Prometheus 端点,应改用 rabbitmq_management 插件 + 访问 15672 管理端口,且该链路的指标名与 3.8+ Prometheus 模板并不完全相同,需选择对应的旧版模板。
AutoMQ:注意不要覆盖已有标签
integrations/AutoMQ/markdown/README.en_US.md 给出了一条与本插件配合的实践,其中有一条重要提醒:AutoMQ 自身已经会输出 instance 标签,因此不要再把 url_label_key 设为 instance,否则会覆盖原始标签。同时也不要覆盖原有的 job 标签,因为面板的集群、节点、active-controller 变量都依赖这些标签。推荐的配置:
interval = 15
[[instances]]
urls = [
"http://<automq-or-otel-collector>:8890/metrics"
]
url_label_key = "otel_collector"
url_label_value = "{{.Host}}"
labels = { source = "automq" }
验证抓取结果可用:
curl -fsS http://<automq-or-otel-collector>:8890/metrics \
| grep -E 'process_runtime_jvm_cpu_utilization_ratio|kafka_request_count_total' \
| head
./categraf --test --inputs prometheus
categraf --test --inputs prometheus 是本地调试的利器,可以直接看到解析结果,确认标签渲染是否符合预期。这个"目标自身可能已带同名校标签"的冲突问题同样适用于其他组件,配置 url_label_key 前应先检查目标指标的原始标签集合。
使用建议与最佳实践
- 保留默认的
instance标签键:它与 Prometheus 生态语义一致,便于与job标签配合进行告警与面板分组;随意改名会导致指标维度口径不一致。 - 优先用模板收敛标签值:多端口同主机场景下,
{{.Hostname}}或{{.Host}}比完整 URL 更利于按主机聚合;需要区分端口时再用{{.Host}}。 - 静态目标与动态目标分层管理:地址固定的 exporter 直接写在
urls中;地址频繁变动的服务使用[instances.consul]服务发现,并利用 query 模板动态生成抓取地址。 - 抓取前先验证再上线:先用
curl确认/metrics可访问、指标名正确,再用./categraf --test --inputs prometheus本地验证解析结果,最后才正式部署采集。 - 注意标签冲突:接入自带
instance/job标签的组件(如 AutoMQ)时,避免url_label_key与其冲突,必要时使用ignore_label_keys或改用其他标签键。
小结
Nightingale 集成中的 Prometheus 输入插件,以"抓取 /metrics → 打来源标签 → 上报服务端"这一简洁链路,把整个 Prometheus exporter 生态无缝接入统一监控平台。它保留了 telegraf/prometheus 的 Consul 服务发现能力,删除了 Kubernetes 相关逻辑,并通过 url_label_key / url_label_value 提供了可模板化的来源标识方案。实际接入时,参考本仓库 integrations/Prometheus/collect/prometheus/prometheus.toml 的完整示例,结合 RabbitMQ、AutoMQ 等集成的实践模板,即可快速、规范地将各类 Prometheus 格式数据源纳入 Nightingale 的指标采集体系。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.25 K640- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python830
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#591
Agent-Reach给你的 AI Agent 一键装上互联网能力。13 个平台(网页/GitHub/YouTube/小红书/B站/Twitter/Reddit 等)多后端路由,当下最稳的接入方式替你选好、装好、体检好。GitHub 主仓库同步镜像。Python1284
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go23245
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java37351