Prometheus 采集插件

如果服务暴露了 Prometheus 格式的接口,可以使用 Categraf 的 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_keyurl_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.4port=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

一个比较tricky 的配置。 场景:我有10台机器, 每台机器上都开启了prometheus插件采集本地的服务metrics.

[[instances]]
urls = [
    "http://127.0.0.1:9121/metrics"
]
url_label_key = "instance"
url_label_value = "{{.Host}}"

但是我想让指标中instance使用内网IP而不是127.0.0.1, 那可以考虑用下面的配置。

[[instances]]
urls = [
    "http://127.0.0.1:9121/metrics"
]
url_label_key = "instance"
url_label_value = "{{.Host}}"
# url_label_pair={instance="{{.Host}}"}
[[instances.relabel_configs]]
# 将 agent_hostname 和 instance 的值通过 ";" 拼接,如: "my-hostname;127.0.0.1:9121"
source_labels = ["agent_hostname", "instance"]
separator = ";"
# $1 匹配 hostname
# $2 匹配 127.0.0.1 (丢弃不用)
# $3 匹配端口号 9121
regex = "(.*);(.*):(.*)"
# 拼装新的结果,写入回 instance。结果变为 "my-hostname:9121"
replacement = "$1:$3"
target_label = "instance"
action = "replace"

更新时间 2024-09-20

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云