必须手动注册 Go 运行时指标并调用指标方法才能出现在 /metrics 中,且需检查网络配置、独立监控端口及 label 维度设计与注册时机。

直接暴露 /metrics 端点就能看到 Go 运行时指标,但默认不注册——你得手动加一行 prometheus.MustRegister(prometheus.NewGoCollector()),否则 go_goroutines、go_memstats_alloc_bytes 这类关键指标压根不会出现。
为什么 /metrics 里看不到自己定义的 http_requests_total
不是代码写错了,是指标根本没被“触发”。Counter 不会主动上报零值;刚启动时页面空空如也,完全正常。
- 必须在 handler 或中间件里调用
httpRequestsTotal.WithLabelValues("GET", "/api/v1").Inc()—— 不调用,就不出现在/metrics中 -
label值不能为空字符串或nil,否则 panic - 定义时声明了
[]string{"method", "endpoint"},调用时就得传两个非空字符串,少一个、多一个、顺序错、类型不对(比如传了int),都会导致指标静默丢失 - 别用
NewCounter却调.WithLabelValues()—— 那会直接 panic
为什么 Prometheus 抓不到指标?先查这三处网络和配置
90% 的“抓不到”问题跟 Go 代码无关,卡在目标地址、监听绑定或防火墙上。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
scrape_configs.targets写的是localhost:8080或容器内网 IP?宿主机上的 Prometheus 访问不到,得换成host.docker.internal:8080(Docker Desktop)或真实局域网 IP - Go 服务监听写的是
127.0.0.1:8080?改成:8080(即空字符串),否则外部连不上 - 云服务器或本地防火墙是否放行了目标端口?
curl -v http://your-go-app:8080/metrics在 Prometheus 所在机器上跑一遍,不通就别查 Go 代码了
用独立端口暴露监控,别跟业务混在一起
把 /metrics 挂在业务 HTTP mux(比如 http.DefaultServeMux)下,看似省事,实则埋雷。
立即学习“go语言免费学习笔记(深入)”;
- 业务中间件可能篡改响应头(比如加了
Content-Type: text/html),Prometheus 抓到后报错:expected 'text/plain' response, got 'text/html' - 业务 panic 会导致整个 HTTP server 挂掉,
/metrics一起不可用 —— 监控和被监控同时失联 - 正确做法:起一个独立
http.Server,监听如:9091,只挂promhttp.Handler() - 示例:
http.Handle("/metrics", promhttp.Handler()); http.ListenAndServe(":9091", nil)
最常被忽略的其实是 label 维度设计和注册时机:指标必须在 init() 或 main() 开头注册,不能在 handler 里反复 new;业务指标要用 Vec 版本(如 NewCounterVec),裸 NewCounter 无法区分维度,等于白埋。

















