/metrics 返回空或404因未显式注册handler,需用http.Handle(“/metrics”, promhttp.Handler())或框架对应中间件,并确保注册早于http.ListenAndServe且路由未被覆盖。
用 prometheus/client_golang 暴露指标时,为什么 /metrics 返回空或 404?
默认情况下,prometheus/client_golang 不自动注册 HTTP handler,必须显式挂载。常见错误是只调用了 promhttp.Handler() 却没绑定到路由。
- 确保使用
http.Handle("/metrics", promhttp.Handler())(Go 1.22+ 推荐用http.HandleFunc+promhttp.Handler().ServeHTTP) - 若用
gin或echo等框架,需用对应中间件包装,例如gin.WrapH(promhttp.Handler()) - 检查是否在
http.ListenAndServe前执行了注册——顺序错会导致 handler 未生效 - 确认没有其他路由覆盖
/metrics,比如/*path兜底路由会拦截它
在 Kubernetes 中部署 Go 应用时,如何让 Prometheus 自动发现并抓取指标?
Prometheus 依赖 ServiceMonitor 或 PodMonitor(取决于 Operator 版本)来动态发现目标。单纯暴露 /metrics 端点并不足以被采集。
- Service 必须带
prometheus.io/scrape: "true"标签(适用于 vanilla Prometheus),或更推荐:用ServiceMonitorCRD 显式声明目标 - Service 的
ports[]需明确指定targetPort对应 Go 应用监听的端口(如8080),且该端口要与Pod容器端口一致 - 若指标端口不是主服务端口(比如另开
9091专用于 metrics),需在Service中单独定义该 port,并在ServiceMonitor的endpoints[].port中引用其名称 - 注意
namespace作用域:ServiceMonitor 默认只监控同 namespace,跨 namespace 需设置namespaceSelector
Counter 和 Gauge 选错会导致什么监控误判?
类型误用是 Go 监控中最隐蔽的问题之一,直接影响告警逻辑和趋势分析。