错误率监控必须用 Prometheus + fiber/middleware/metrics 实现,而非仅依赖 logger;需显式调用 app.Use(metrics.New()) 并置于 status 修改中间件之后,配合分母过滤的告警规则(如错误率>0.5%且请求量>10次/分钟)才有效。

错误率统计不能只靠 logger 中间件
logger 中间件只负责打印,不收集、不聚合、不暴露指标。直接用 logger.New() 或自定义日志中间件,哪怕每行都带 status code,也无法算出「/api/users 的 5xx 错误率是 2.3%」—— 缺少计数器、时间窗口、路径维度聚合能力。
用 Prometheus + fiber/middleware/metrics 实现真实错误率监控
官方 metrics 中间件才是专为可观测性设计的入口,它自动按状态码、HTTP 方法、路径标签打点,配合 Prometheus 抓取即可计算错误率。关键不是“记日志”,而是“暴露可查询指标”。
-
metrics.New()默认启用status_code、method、path三重 label,错误率公式直接写成:rate(fiber_http_requests_total{status_code=~"5.."}[5m]) / rate(fiber_http_requests_total[5m]) - 必须显式调用
app.Use(metrics.New()),且要放在所有可能修改 status 的中间件之后(比如 auth、limiter),否则 401/429 不会被计入status_code标签 - 若需区分内部错误(500)和客户端错误(4xx),不要合并匹配 ——
status_code=~"5.."和status_code=~"4.."应分开查,避免把 404 当作服务异常 - 默认 metrics 路径是
/metrics,若已存在同名路由,需用metrics.Config{Endpoint: "/admin/metrics"}改写,否则被覆盖
自定义错误计数器要注意 ctx.IsAborted() 和 panic 场景
如果不用 Prometheus,而是在内存里自己累加错误数(比如调试期快速看趋势),必须覆盖两类失败:显式返回错误的 handler,以及 panic 导致的未捕获崩溃。
- 在中间件末尾判断:
if err != nil || ctx.Response().StatusCode() >= 400—— 但注意,ctx.Response().StatusCode()在 handler panic 后可能仍是 0,得靠 recover 捕获 - 正确姿势是包一层
defer+recover(),并在 recover 块里手动 incr 错误计数器,同时 log.Panicf 记录堆栈 - 别用
sync.Map存路径级计数器 —— 高并发下LoadOrStore仍可能丢更新;改用atomic.Int64配合路径哈希(如fnv32a(c.Path()))做分片计数 - 计数器变量不能挂
c.Locals()—— 它只存活单次请求,无法跨请求累积
错误率告警阈值必须结合路径热度才有效
单独看「错误率 > 5%」没意义:一个每天 2 次请求的管理接口,1 次 500 就是 50%;而核心支付接口 0.1% 错误率可能已影响千人。真正可用的告警规则得加请求量过滤。
- Prometheus 推荐写法:
100 * (rate(fiber_http_requests_total{status_code=~"5.."}[5m]) / rate(fiber_http_requests_total[5m])) > 0.5 AND rate(fiber_http_requests_total[5m]) > 10,即「错误率超 0.5%,且每分钟请求超 10 次」才触发 - 若用内存计数器,别直接除 —— 分母为 0 会 panic;先判断
total.Load() == 0,再算比率 - 路径通配会影响统计精度:注册了
app.Get("/api/v1/:id", h),metrics 默认把所有/api/v1/123、/api/v1/456归为同一 path label;如需按 ID 维度细分,得手动重写Config: metrics.Config{Path: func(c *fiber.Ctx) string { return c.Route().Path }}
Fiber 的错误率监控容易卡在「以为打了日志就算监控了」,其实真正的瓶颈在指标可聚合性、panic 捕获完整性、以及告警规则是否排除低频噪声 —— 这三点漏掉任一,看到的数字就只是安慰剂。


















