prometheus采集插件
确认服务是否暴露了prometheus格式的接口
prometheus格式指标示例如下:
# HELP nginx_vts_info Nginx info
# TYPE nginx_vts_info gauge
nginx_vts_info{hostname="vm1",module_version="v0.2.1",version="1.20.2"} 1
# HELP nginx_vts_start_time_seconds Nginx start time
# TYPE nginx_vts_start_time_seconds gauge
nginx_vts_start_time_seconds 1680155881.518
...
prometheus 插件
注意 prometheus插件是直接采集prometheus协议数据的插件. 这个插件支持的自动发现能力没有prometheus-agent mode广泛.
prometheus 插件的作用,就是抓取 /metrics 接口的数据,上报给服务端。通过,各类 exporter 会暴露 /metrics 接口数据,越来越多的开源组件也会内置 prometheus SDK,吐出 prometheus 格式的监控数据,比如 rabbitmq 插件,其 README 中就有介绍。
这个插件 fork 自 telegraf/prometheus,做了一些删减改造,仍然支持通过 consul 做服务发现,管理所有的目标地址,删掉了 Kubernetes 部分,Kubernetes 部分放到prometheus agent中实现了。
增加了两个配置:url_label_key 和 url_label_value。为了标识监控数据是从哪个 scrape url 拉取的,会为监控数据附一个标签来标识这个 url,默认的标签 KEY 是用 instance,当然,也可以改成别的,不过不建议。url_label_value 是标签值,支持 go template 语法,如果为空,就是整个 url 的内容,也可以通过模板变量只取一部分,比如 http://localhost:9104/metrics 只想取 IP 和端口部分,就可以写成:
配置
一份最简单的配置示例如下:
[[instances]]
urls = [
"http://localhost:9104/metrics",
"http://localhost:9105/metrics",
]
url_label_key = "instance"
url_label_value = "{{.Host}}"
从url中提取单个变量标签(老版本)
url_label_key = "instance"
url_label_value = "{{.Host}}"
- 这样采集
http://localhost:9104/metrics的指标中会附加一个instance=localhost:9104的标签 - 这样采集
http://localhost:9105/metrics的指标中会附加一个instance=localhost:9105的标签
如果 scheme 部分和 path 部分都想取,可以这么写:
url_label_key = "instance"
url_label_value = "{{.Scheme}}://{{.Host}}{{.Path}}"
- 这样采集
http://localhost:9104/metrics的指标中会附加一个instance=http://localhost:9104/metrics的标签 - 这样采集
http://localhost:9105/metrics的指标中会附加一个instance=http://localhost:9105/metrics的标签
相关变量是用这个方法生成的,供大家参考:
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
}
以 http://1.2.3.4:8080/search?q=keyword#results 为例, 变量及其值如下:
| variable | value |
|---|---|
| {{.Scheme}} | http |
| {{.Host}} | 1.2.3.4:8080 |
| {{.Hostname}} | 1.2.3.4 |
| {{.Port}} | 8080 |
| {{.Path}} | search |
| {{.Query}} | q=keyword |
| {{.Fragment}} | results |
从url中提取多个变量作为标签(新版本 推荐)
从categraf 0.3.28 开始,支持从url中提取多个变量作为标签,比如
url_label_pair = {hostname="{{.Hostname}}", port="{{.Port}}"}
最终生成的label 会包含hostname=1.2.3.4 和 port=8080两个标签
采集示例
比如采集 Nginx vts 的指标, 配置 conf/input.prometheus/nginx.toml 内容如下
[[instances]]
urls = [
"http://192.168.11.201/vts_status/format/prometheus",
]
url_label_key = "instance"
url_label_value = "{{.Host}}"
nginx 从编译到采集, 参考
注 如果你的url path为空,插件会自动补 /metrics, 比如是http://127.0.0.1:8080, 插件会自动补全为http://127.0.0.1:8080/metrics,
这个时候url可以写作http://127.0.0.1:8080/ 就可以避免自动添加 /metrics
consul 服务发现
[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}}"
-
enable: 是否开启consul服务发现 -
agent:consul的地址 -
query_interval: 查询consul的间隔
其中query定义查询consul的条件
-
name: 从consul查询的服务名, 注意 这里不是服务id -
tag: 从consul查询的标签名 -
url: 采集地址模板,其中hostname 部分会被替换为服务发现的ip和port -
query.tags: 指定从consul中发现,需要额外附加到指标的tag