夜莺-Nightingale
夜莺V6
项目介绍 架构介绍
快速开始
黄埔营
安装部署
升级
采集器
使用手册
API
数据库表结构
FAQ
夜莺专业版
开源生态
Prometheus
版权声明
第1章:天降奇兵
第2章:探索PromQL
第3章:Prometheus告警处理
第4章:Exporter详解
第5章:数据与可视化
第6章:集群与高可用
第7章:Prometheus服务发现
第8章:监控Kubernetes
第9章:Prometheus Operator
参考资料

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广泛.

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

开源版
Flashcat
Flashduty