grafana需依赖prometheus采集go服务的/metrics数据,而go服务暴露该接口须满足三条件:路径严格为/metrics、指标必须用prometheus.mustregister()注册、不能被中间件拦截;counter需递增打点,histogram需observe()并设buckets;prometheus targets须真实可达且状态为up;查询直方图分位数须带_bucket和by(le)。

Grafana 本身不采集数据,你配再复杂的面板也看不到指标——必须先让 Go 服务暴露 /metrics,Prometheus 成功抓到,Grafana 才有东西可画。
Go 服务暴露 /metrics 接口必须满足三个硬条件
缺一不可,否则 curl http://localhost:8080/metrics 要么 404,要么返回空、HTML 或格式错误:
-
promhttp.Handler()必须在http.ListenAndServe()之前注册,且路径严格为/metrics(不是/metrics/或/monitor/metrics) - 所有自定义指标(如
http_requests_total)必须调用prometheus.MustRegister(),否则不会出现在输出里 - 不能被中间件拦截:JWT 鉴权、CORS、日志中间件如果对
/metrics路径生效,Prometheus 抓取会直接失败(返回 401/403 或超时)
Counter 和 Histogram 的注册与打点方式完全不同
类型选错或打点位置不对,会导致 PromQL 查询始终无数据:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 计数器
Counter(如http_requests_total)只允许递增,必须在请求进入 handler 时就.Inc()或.Add(1);延迟类指标绝不能用 Counter - 直方图
Histogram(如http_request_duration_seconds)需配合prometheus.NewTimer()或手动.Observe(time.Since(start).Seconds()),且必须传入Buckets(推荐[0.1, 0.3, 0.5, 1.0, 3.0]) - 标签必须用
.WithLabelValues("GET", "200"),别用.With(map[string]string{...})—— 后者容易因 key 顺序或拼写不一致造成 series 爆炸
Prometheus 配置里 targets 写错,Grafana 就是摆设
Grafana 连的是 Prometheus,不是你的 Go 服务。Prometheus 抓不到,Grafana 查 rate(http_requests_total[5m]) 就永远是空:
-
scrape_configs中的targets必须写 Go 服务**真实可达的地址**:Docker 容器里跑 Prometheus,就不能写localhost:8080,得写宿主机 IP 或容器网络别名 - 确保
job_name唯一,且没和其他 job 冲突(比如两个 job 都叫go-app,后者会覆盖前者) - 检查 Prometheus UI 的
Status → Targets页面,目标状态必须是UP,且Last Scrape时间距现在不超过 scrape_interval(默认 15s)
Grafana 查询时最常忽略的两个细节
即使数据已进 Prometheus,查出来还是空,大概率卡在这两处:
- 直方图分位数查询必须带
_bucket后缀和le标签聚合:histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)),漏掉by (le)或写成_sum都会返回空 - 业务指标命名建议加前缀(如
myapp_http_requests_total),避免和 Go 运行时指标(go_goroutines)混淆,也防止团队内不同服务指标名冲突
真正卡住人的往往不是语法,而是 Prometheus 没拉到数据却去调 Grafana 面板,或是 Histogram 打点漏了 Observe() 却反复检查 PromQL——先盯死 Status → Targets 和 /metrics 原始输出,比改面板快十倍。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










