curl /metrics 返回200但无内容,最常见原因是promhttp.handler()注册过晚,必须在http.listenandserve()之前调用;若注册顺序错误或被中间件拦截、路径未正确处理head请求,也会导致静默无数据。

curl http://localhost:8080/metrics 能看到指标文本,Prometheus targets 页面显示 UP,Grafana 才可能查到数据;否则所有面板都是空的——这不是 Grafana 的问题,是链路前端断了。
为什么 curl /metrics 返回 200 却没内容?
最常见原因是 promhttp.Handler() 注册太晚:必须在 http.ListenAndServe() 之前调用,否则注册表为空,Handler 只返回 HTTP 头不输出指标。
- 错误写法:
http.ListenAndServe(":8080", nil)放在http.Handle("/metrics", ...)前面 → 启动即静默失败(尤其本地开发容易忽略log.Fatal) - 若用了
gorilla/mux或gin,别写r.GET("/metrics", ...)—— 必须用r.Handle("/metrics", promhttp.Handler())(GET不支持 HEAD,而 Prometheus 抓取会发 HEAD) - 中间件(如 JWT 鉴权、CORS)拦截了
/metrics路径,导致 401/403 或直接跳转 → 检查中间件是否对路径做了白名单放行
http_requests_total 在 Grafana 里始终为 0?
说明业务打点没生效,或标签没传对。默认收集器只暴露 go_* 运行时指标,HTTP 请求量得自己定义、注册、并在请求路径中调用。
- Counter 必须用
.Inc()或.Add(1)显式累加,光注册不打点 = 零值 - 标签键名要统一:比如用
method就全用method,别一会儿http_method一会儿verb,否则 PromQL 查询时匹配不上 - 若用
NewCounterVec,务必复用同一个变量实例,别在 handler 里反复prometheus.NewCounterVec(...)—— 每次新建都会注册新指标,造成 series 爆炸和内存泄漏 - 延迟直方图别漏
Buckets:例如http_request_duration_seconds_bucket{le="0.3"}没数据,大概率是Buckets: []float64{0.1, 0.3, 0.5, 1.0}没设对,或者Observe()传入了负数或 NaN
Prometheus 查得到指标,Grafana 却显示 “No data”?
90% 是 label 过滤或聚合逻辑错位,不是数据源连错了。
- 先确认 Grafana 数据源选的是正确的 Prometheus 实例(不是另一个测试环境)
- 查
http_requests_total时,如果服务部署在 Kubernetes 且用了 job 标签,表达式得写成rate(http_requests_total{job="my-service"}[5m]),漏掉{job="..."}就可能跨服务混算,甚至因 label 不匹配被静默过滤 - P95 延迟要用
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])),不是rate(...)包在外面——顺序反了结果恒为 0 - 避免高基数 label:比如把
user_id当 label,一个用户一个 series,几千用户就上万 series,Prometheus 存储和查询都会崩
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











