Golang 开发Prometheus 自定义 Exporter
目录
- Exporter 定义
- Exporter 运行方式
- Exporter 数据规范
- 常见指标类型说明
- 核心数据格式规则
- Golang语言开发自定义exporter
- 详细步骤
- 开发环境准备
- 定义和注册指标
- 运行和测试
平时运维工作中,遇到官方exporter不包含的指标,比如企业内部服务等,如何监控这些指标呢。
我们可以考虑编写自己的exporter将这些指标监控起来。下面讲解下Golang语言编写Exporter的步骤。后续我们将继续完善这部分内容。
Exporter 定义
Exporter 的核心功能是数据采集、格式转换、指标暴露,这三个功能构成其核心工作流。
- 数据采集
从目标对象(如服务器、数据库、应用程序)获取原始监控数据。支持多种采集方式,比如主动拉取(Polling)或被动接收(Push)。 - 格式转换
将采集到的异构原始数据,统一转换为标准化的指标格式。最常见的标准是 Prometheus 的指标格式,确保数据可被监控系统识别。 - 指标暴露
通过 HTTP 接口(通常是 /metrics 端点)将标准化指标对外暴露。供监控系统(如 Prometheus)定期抓取,完成数据的后续存储和分析。
Exporter 运行方式
从Exporter的运行方式上来讲,又可以分为:
-
独立使用的
以我们已经使用过的Node Exporter为例,由于操作系统本身并不直接支持Prometheus,同时用户也无法通过直接从操作系统层面上提供对Prometheus的支持。因此,用户只能通过独立运行一个程序的方式,通过操作系统提供的相关接口,将系统的运行状态数据转换为可供Prometheus读取的监控数据。 除了Node Exporter以外,比如MySQL Exporter、Redis Exporter等都是通过这种方式实现的。 这些Exporter程序扮演了一个中间代理人的角色。 -
集成到应用中的
为了能够更好的监控系统的内部运行状态,有些开源项目如Kubernetes,ETCD等直接在代码中使用了Prometheus的Client Library,提供了对Prometheus的直接支持。这种方式打破的监控的界限,让应用程序可以直接将内部的运行状态暴露给Prometheus,适合于一些需要更多自定义监控指标需求的项目。
Exporter 数据规范
Prometheus Exporter 的核心数据格式是文本格式,遵循 Prometheus 的指标规范,结构简洁且易解析。
常见指标类型说明
- Counter:累计型指标(只增不减,如请求总数、错误数)。
- Gauge:瞬时值指标(可增可减,如内存使用率、当前连接数)。
- Histogram:直方图指标(统计数值分布,如请求延迟分布)。
- Summary:摘要指标(统计分位数,如 P95/P99 延迟)。
核心数据格式规则
- 注释行(可选):以 # 开头,分两种类型
- 帮助注释:# HELP 指标名 指标描述,说明指标含义。
- 类型注释:# TYPE 指标名 指标类型,指定指标类型(counter/gauge/histogram/summary)。
- 指标行(核心):格式为 指标名{标签键=“标签值”,…} 指标值 时间戳(可选)
- 指标名:符合正则 [a-zA-Z_:][a-zA-Z0-9_:]*,推荐小写 + 下划线命名。
- 标签:键值对格式,用于区分指标维度(如实例、模块)。
- 指标值:支持整数、浮点数(如 10、0.5)。
- 时间戳:Unix 时间戳(毫秒级),省略时默认取采集时间。
实际示例(以 HTTP 请求数指标为例)
# HELP http_requests_total 已处理的HTTP请求总数
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200"} 156 1699999999000
http_requests_total{method="POST",status="200"} 89
http_requests_total{method="GET",status="404"} 23
Golang语言开发自定义exporter
详细步骤
开发环境准备
首先,确保你安装了Go语言环境。然后,创建一个新的Go项目文件夹,初始化Go模块:
mkdir diy_exporter
cd diy_exporter
go mod init diy_exporter
安装依赖:
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp
定义和注册指标
创建一个main.go文件
package mainimport ("net/http""github.com/prometheus/client_golang/prometheus""github.com/prometheus/client_golang/prometheus/promhttp"
)func main() {// 1. 创建一个最简单的计数器(无标签)visitCounter := prometheus.NewCounter(prometheus.CounterOpts{Name: "page_visit_total", // 指标名:页面访问总数Help: "Total number of page visits",})// 2. 注册指标prometheus.MustRegister(visitCounter)// 3. 简单接口:每次访问就计数+1http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {visitCounter.Inc() // 计数器+1w.Write([]byte("Hello, Counter!"))})// 4. 暴露指标端点http.Handle("/metrics", promhttp.Handler())// 5. 启动服务http.ListenAndServe(":8182", nil)
}
这个例子简化到了极致,只做 4 件事:
- 定义一个名为page_visit_total的计数器(无任何标签)
- 注册指标
- 每次访问根路径/时,计数器 + 1
- 通过/metrics端点暴露这个计数器的值
运行和测试
运行程序:
go run main.go
访问 http://192.168.37.100:8182/ (根据自己运行exporter地址填)
访问 http://192.168.37.100:8182/metrics
# HELP page_visit_total Total number of page visits
# TYPE page_visit_total counter
page_visit_total 5 # 数字会随访问次数增加

