
本文详解如何基于 prometheus 官方 go 客户端(client_golang)构建一个可拉取远程 json 接口并暴露为 prometheus 指标的自定义 exporter,涵盖 collector 接口实现、http 服务注册与实际数据解析流程。
本文详解如何基于 prometheus 官方 go 客户端(client_golang)构建一个可拉取远程 json 接口并暴露为 prometheus 指标的自定义 exporter,涵盖 collector 接口实现、http 服务注册与实际数据解析流程。
在 Prometheus 生态中,client_golang 不仅用于 instrumenting 本机应用,更常被用于开发各类 Exporter —— 尤其是当目标服务(如您的服务 ABC)仅提供 HTTP JSON 接口而无原生指标支持时。核心思路是:实现 prometheus.Collector 接口,将外部 JSON 数据按 Prometheus 数据模型动态转换为 Gauge、Counter 等指标,并通过 /metrics 端点暴露。
✅ 关键步骤概览
- 实现
Describe(ch chan:声明指标元信息(名称、标签、Help 文本); - 实现
Collect(ch chan:发起 HTTP 请求 → 解析 JSON → 构建并发送具体指标值; - 在
main()中注册 Collector 并启动 HTTP 服务。
? 示例:采集 JSON 响应中的 uptime_seconds 和 active_connections
假设服务 ABC 的 http://abc-service:8080/health 返回如下 JSON:
{
"uptime_seconds": 12345,
"active_connections": 42,
"status": "healthy",
"region": "us-east-1"
}
对应 Go 实现如下:
package main
import (
"encoding/json"
"io"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// HealthResponse 匹配上游 JSON 结构
type HealthResponse struct {
UptimeSeconds float64 `json:"uptime_seconds"`
ActiveConnections int `json:"active_connections"`
Status string `json:"status"`
Region string `json:"region"`
}
// CustomCollector 实现 prometheus.Collector
type CustomCollector struct {
uptimeDesc *prometheus.Desc
connDesc *prometheus.Desc
statusDesc *prometheus.Desc
baseURL string
httpClient *http.Client
}
func NewCustomCollector(baseURL string) *CustomCollector {
return &CustomCollector{
uptimeDesc: prometheus.NewDesc(
"abc_service_uptime_seconds",
"Uptime of ABC service in seconds",
[]string{"region"}, nil,
),
connDesc: prometheus.NewDesc(
"abc_service_active_connections",
"Number of active connections",
[]string{"region", "status"}, nil,
),
statusDesc: prometheus.NewDesc(
"abc_service_health_status",
"Health status as gauge (1=healthy, 0=unhealthy)",
[]string{"region"}, nil,
),
baseURL: baseURL,
httpClient: &http.Client{
Timeout: 5 * time.Second,
},
}
}
func (c *CustomCollector) Describe(ch chan<h3>⚠️ 注意事项与最佳实践</h3>
-
错误处理必须健壮:
Collect()方法内任何 panic 或未捕获错误都会导致整个/metrics端点失效;建议用defer清理资源,对网络/JSON 错误静默跳过(Prometheus 会标记scrape_failed)。 -
避免阻塞:
Collect()是同步调用,若上游响应慢,会拖慢整个 scrape 周期;可考虑添加超时(如示例中http.Client.Timeout)或异步缓存(需自行管理并发安全)。 -
标签设计要合理:避免高基数标签(如
user_id),优先使用低基数维度(如region,status,env)。 -
注册时机:
MustRegister()应在 HTTP server 启动前完成;重复注册会 panic,建议确保单例。 -
可观测性增强:可额外暴露
abc_service_scrape_duration_seconds(直方图)和abc_service_scrape_errors_total(计数器)以监控 Exporter 自身健康。
通过以上结构,您即可快速构建一个轻量、可靠、符合 Prometheus 最佳实践的 JSON Exporter —— 无需修改上游服务,即可将其指标无缝接入 Prometheus 监控体系。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











