必须用prometheus/client_golang而非手写/metrics:因手写易踩content-type错误、不支持accept协商、忽略head请求三坑;正确做法是http.handle("/metrics", promhttp.handler())。

能直接监控 Go 微服务的工具不止一个,但真正能落地、可维护、有生态支撑的,就三个核心组件:Prometheus(指标采集)、OpenTelemetry(链路追踪)、Grafana(可视化)。其他所谓“监控工具”要么是包装层(如 Datadog Agent 本质还是拉 Prometheus 格式),要么缺关键能力(比如只做日志不支持 metric 下钻)。
为什么必须用 prometheus/client_golang 而不是自己拼 metrics
自己写 http.HandleFunc("/metrics", ...) 输出文本,大概率会踩三个坑:
- Content-Type 错——Prometheus 只认
text/plain; version=0.0.4或application/openmetrics-text,手写容易漏 header 或写错 - 不支持
Accept协商——当 Prometheus 加了Accept: application/openmetrics-text; version=1.0.0,你的 handler 返回 406 - 没处理 HEAD 请求——
promhttp.Handler()内置支持,自己写容易忽略,导致 scrape 失败但无明显报错
正确做法永远是:http.Handle("/metrics", promhttp.Handler()),或更稳妥的 http.Handle("/metrics", promhttp.HandlerFor(reg, opts))(尤其当你用了自定义 registry)。
Grafana 里 rate(http_requests_total[5m]) 返回空?先查指标类型和标签
常见现象:Prometheus 查询 rate(http_requests_total[5m]) 没数据,但 http_requests_total 在 /metrics 里明明存在。原因几乎总是以下之一:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 指标注册时用了
prometheus.NewGaugeVec却命名为http_requests_total——Gauge 不支持rate(),会静默返回空 - 标签维度不一致——比如某次调用用
.WithLabelValues("GET", "/api/v1/user", "200"),另一次漏传 status,导致 series 不匹配,rate()无法聚合 - 抓取间隔 > 采样间隔——Prometheus 默认 scrape_interval 是 15s,而你每 20s 才 Inc() 一次,中间没变化,rate 就算不出斜率
验证方法:在 Prometheus 表达式浏览器里直接查 http_requests_total,看返回的 series 列表是否带全标签、是否有增量。
OpenTelemetry 和 prometheus/client_golang 能一起用吗
能,而且必须一起用——它们解决的是不同层次的问题:
-
prometheus/client_golang暴露的是「服务级」聚合指标(如 P99 延迟、错误率),适合告警和容量评估 -
go.opentelemetry.io/otel上报的是「请求级」trace 数据(span 链路、SQL 耗时、RPC 跳转),适合根因分析 - 两者共用同一个 context,但 metric 和 trace 的 exporter 完全独立——metric 走 /metrics HTTP 拉取,trace 走 OTLP gRPC 推送
注意别混淆:OTel 的 otelmetric SDK 是用来替代 prometheus/client_golang 的(不推荐),生产环境仍建议用原生 client_golang + OTel trace,分工明确、成熟稳定。
最易被忽略的一点:所有指标注册(MustRegister)必须发生在 HTTP server ListenAndServe 之前;一旦 server 启动,再注册指标会导致 panic 或指标不可见——这不是并发问题,而是 promhttp.Handler 初始化时已绑定 registry 快照。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










