必须使用 fiber-prometheus 中间件而非 promhttp.Handler(),因 Fiber 基于 fasthttp 与 net/http 类型不兼容;需通过 prom.Registry 注册自定义指标,并禁用默认指标避免重复注册 panic。

不能直接用 promhttp.Handler(),Fiber 的 fiber.Ctx 和标准 net/http 接口不兼容——这是集成失败最常卡住的地方。
为什么 promhttp.Handler() 会报错
Fiber 底层用的是 fasthttp,它的请求上下文类型是 *fasthttp.Request,而 promhttp.Handler() 返回的是 http.Handler,要求参数是 *http.Request。Go 类型系统直接拒绝转换。
典型错误信息:
cannot use promhttp.Handler() (type http.Handler) as type fiber.Handler- 调用
c.Request().Header.Get(...)时 panic,因为c.Request()不是*http.Request
必须用 Fiber 原生中间件方式暴露指标,而不是复用标准库 HTTP handler。
用 fiber-prometheus 中间件暴露 /metrics
社区维护的 fiber-prometheus 是目前最稳定的选择,它封装了指标注册、采集和响应格式(纯文本),且适配 fasthttp 生命周期。
实操步骤:
- 安装:
go get github.com/chenzhuoyu/fiber-prometheus - 初始化注册器:
prom := fiberprometheus.New("myapp") - 注册到 Fiber app:
app.Use(prom.Middleware) - 暴露指标端点:
app.Get("/metrics", prom.Handler)
启动后访问 /metrics,返回内容符合 Prometheus 文本格式(以 # HELP 和 # TYPE 开头,含 http_requests_total{method="GET",status="200"} 等标签化指标)。
自定义业务指标要绕开 MeterRegistry 冲突
Fiber 本身不带指标抽象层,所以别试图往 Micrometer 或 Prometheus Go client 的全局 prometheus.DefaultRegisterer 里硬塞;容易和 fiber-prometheus 内部注册器冲突,导致重复注册 panic。
正确做法是复用它提供的 prom.Registry:
- 定义指标时用
prom.Registry.MustRegister(yourCounter) - 计数器示例:
orderCreated := prometheus.NewCounter(prometheus.CounterOpts{Name: "order_created_total"}) - 在业务 handler 中:
orderCreated.Inc()
注意:所有自定义指标必须在 prom.Handler 被调用前完成注册,否则抓取不到。
生产环境要关掉默认指标或重命名避免冲突
fiber-prometheus 默认开启 HTTP 请求指标(http_requests_total、http_request_duration_seconds),但如果你同时用了其他中间件(比如自定义链路追踪埋点),可能造成同名指标多次注册。
安全做法:
- 禁用默认指标:
fiberprometheus.New("myapp", fiberprometheus.WithoutDefaultMetrics()) - 或手动控制命名空间:
fiberprometheus.New("myapp", fiberprometheus.WithNamespace("fiber")) - 检查
/metrics输出中是否出现duplicate metrics collector registration attempted
这个细节在本地跑得通、上 K8s 就崩的场景里最常见——因为 Pod 重启后指标注册逻辑被反复执行,而 fasthttp 实例复用比 net/http 更激进。


















