grafana不嵌入go工程,而是独立运行并查询prometheus;go只需正确暴露/metrics接口,prometheus抓取后供grafana可视化。常见卡点:/metrics路径404或为空、注册顺序错误、监听地址用localhost导致docker/k8s中抓取失败、指标未实际打点、histogram buckets未配置、prometheus targets显示down、grafana数据源误填go服务地址。

Grafana 本身不部署在 Go 工程里——它独立运行,只负责查 Prometheus 的数据;Go 工程唯一要做的,是把指标正确暴露给 Prometheus。
很多人卡在“怎么把 Grafana 嵌进 Go 服务”,这是方向性误解。Grafana 是个 Web 应用,和你的 Go 服务无关;你真正要配置的,是 Go 暴露指标、Prometheus 抓取指标、Grafana 连 Prometheus 这三段链路。漏掉任一环,大屏就是空白。
/metrics 接口 404 或返回空内容
这是最常卡住的第一步。没有 /metrics,后面全白搭。
-
http.Handle("/metrics", promhttp.Handler())必须在http.ListenAndServe()之前调用;放错顺序会导致 handler 注册失败,curl 返回 HTTP 200 但 body 为空 - 路径必须严格是
/metrics,不是/metrics/、/monitor/metrics或带前缀的路径;Prometheus 默认只拉/metrics - 如果用了中间件(JWT 鉴权、日志、CORS),必须显式跳过
/metrics路径,否则 Prometheus 抓取会返回 401/403 或超时 - 监听地址不能写
127.0.0.1:8080;Docker/K8s 环境下,Prometheus 容器访问不到 localhost,得用0.0.0.0:8080或宿主机真实 IP
Counter 和 Histogram 打点后 Prometheus 查不到数据
注册了指标,但 http_requests_total 或 http_request_duration_seconds_bucket 在 Prometheus 表达式浏览器里始终无值,问题大概率出在打点逻辑或类型误用上。
- 只调用
MustRegister()不够,必须在业务路径中实际调用.Inc()、.Add(1)或.Observe(duration.Seconds());没打点 = 零值静默 -
Histogram初始化时必须传非空Buckets,例如[]float64{0.05, 0.1, 0.25, 0.5, 1, 2.5};漏掉或传空 slice,_bucket系列指标根本不会生成 - 标签必须用
.WithLabelValues("GET", "/api/user"),别用.With(map[string]string{...});后者因 map key 顺序不可控、拼写易错,极易引发 series 爆炸 - 记录耗时推荐用
prometheus.NewTimer()包裹 handler,比手写start := time.Now(); defer ...更可靠,避免 panic 导致 defer 不执行
Prometheus targets 显示 DOWN,Grafana 面板全空
Grafana 查不到指标?先别动面板,打开 http://<prometheus-host>:9090/targets</prometheus-host> 看状态。
- target 地址必须是 Prometheus **能直接访问到** 的地址:Docker Compose 里填
host.docker.internal:8080(Mac/Win)或宿主机 IP(Linux),绝不能填localhost:8080 - 确认
scrape_configs中 job 的static_configs.targets没写错,且端口与 Go 服务监听端口一致 - 检查 Prometheus 日志里的
Scrape error,常见报错如server returned HTTP status 404 Not Found(路径错)、i/o timeout(网络不通)、text format parsing error(Go 手拼 metrics 格式错误) - Grafana 数据源 URL 填的是 Prometheus 地址(如
http://localhost:9090),不是 Go 服务地址;填错等于连错数据库
Grafana 查询直方图分位数始终为 0
比如 histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) 返回空或 0,通常不是 Grafana 配置问题,而是上游数据缺失或查询语法踩坑。
- 确保
http_request_duration_seconds_bucket有真实数据:先在 Prometheus 表达式浏览器里单独查它,看是否有非零样本 -
rate()函数需要至少两个 scrape 周期的数据才能计算斜率;如果刚启动或抓取间隔太长(如scrape_interval: 60s),[5m]可能覆盖不到足够点 - 直方图查询必须用
_bucket后缀指标,不能用_sum或_count;且histogram_quantile()第二个参数必须是rate(...[Xm]),不能是原始计数 - 如果用了
CounterVec或HistogramVec,PromQL 中 label 过滤要完整匹配,比如http_request_duration_seconds_bucket{job="go-app",method="GET"},漏掉job就查不到
最容易被忽略的点是:所有指标打点都发生在 Go 服务内存里,Prometheus 抓取是 pull 模型,每 15 秒一次;这意味着你改完代码、重启服务后,要等至少一个 scrape 周期(默认 15s),指标才会出现在 Prometheus targets 页面和 Grafana 面板里——别急着刷新 Grafana,先盯住 targets 状态是否变 UP。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











