prom.Handler()必须在路由注册前调用,否则/metrics返回404或空响应;需先app.Use(prom.Handler()),再注册业务路由和/app.Get("/metrics", prom.Handler()),避免被静态路由或通配路由拦截。

prom.Handler() 必须在路由注册前调用
这是最常踩的坑:指标采集失效、/metrics 返回空或 404,八成是因为 app.Use(prom.Handler()) 放错了位置。Fiber 中间件执行顺序严格按代码调用顺序,一旦某个中间件提前 ctx.SendStatus(401).Send() 或直接 return,后续所有中间件(包括指标收集)都会被跳过。
正确顺序是:
-
prom := prometheus.New()初始化后,立刻调用app.Use(prom.Handler()) - 再注册所有业务路由,比如
app.Get("/api/users", handler) - 最后才注册
app.Get("/metrics", prom.Handler())(仅用于显式暴露端点,非必须)
特别注意:不要把 prom.Handler() 放在 app.Static()、app.All("/*", ...) 或权限中间件之后——这些会拦截 /metrics 请求,导致指标漏采。
为什么 /metrics 路径返回 404 或 Content-Type 错误
不是代码写错了,而是匹配逻辑被覆盖了。Fiber 的 app.All("/*", ...) 这类通配路由会优先匹配所有路径(包括 /metrics),如果它出现在 app.Get("/metrics", ...) 之前,后者根本不会被执行。
验证方法:
- 用
curl -v http://localhost:3000/metrics检查响应状态码是否为200 OK - 确认响应头中
Content-Type是text/plain; version=0.0.4,不是text/html或空 - 检查日志里有没有
GET /metrics 404记录,如果有,说明路由没注册上或被吞了
临时调试技巧:把 app.Get("/metrics", ...) 改成 app.Get("/debug/metrics", ...) 绕过通配路由,确认指标能出来,再回头调整中间件顺序。
如何加 DB 查询耗时这类自定义指标
fiber/prometheus 只覆盖 HTTP 层(请求计数、延迟直方图、状态码),DB、Redis、外部 API 等耗时必须手动打点。关键原则是:指标对象必须在启动时创建一次,不能在每个请求里 new。
示例(使用 promauto):
dbLatency := promauto.With(reg).NewHistogram(prometheus.HistogramOpts{
Name: "db_query_duration_seconds",
Help: "Database query latency in seconds",
Labels: map[string]string{"db": "primary"},
})
在 DAO 方法中记录:
start := time.Now()
// 执行查询
defer dbLatency.WithLabelValues("users").Observe(time.Since(start).Seconds())
注意:
- 标签值(如
"users")要是有限集合,不能拼接用户输入(比如req.Query("id")),否则会导致高基数(cardinality explosion) - 避免用动态 key 命名指标,比如
"db_query_duration_seconds_" + tableName—— Prometheus 不允许重复注册同名指标 - 如果用了多个数据库实例,用不同标签区分,而不是新建指标名
Prometheus 抓不到指标的常见配置盲区
Flask 或 Spring MVC 项目常因路径/地址不一致失败,Fiber 同样适用。问题往往不在 Fiber 侧,而在 Prometheus 配置里。
检查这三项:
-
targets必须可从 Prometheus 容器/进程直接访问:本地开发用localhost:3000,Docker 部署时改用服务名(如fiber-app:3000),别写host.docker.internal(某些 Docker 版本不支持) -
metrics_path显式写成/metrics,虽然默认就是它,但写明更可靠 -
scrape_interval别设太小(如1s),Fiber 应用扛不住高频抓取;生产建议15s–30s
最后提醒一句:指标本身不带告警逻辑。http_requests_total 和 http_request_duration_seconds 这些数据要真正起作用,得靠 Prometheus 配 alert_rules,再连 Alertmanager 推送——暴露指标只是第一步,后面才是监控闭环的关键环节。


















