审计中间件须从 fiber.New() 开始构建空实例并手动挂载,禁止用 fiber.Default();需对敏感字段脱敏,按操作类型、状态码、路径前缀精准采样,结合1%随机采样与错误强制记录策略。

审计中间件必须手动挂载到 fiber.New() 实例上
用 fiber.Default() 启动服务再加审计逻辑,等于把原始请求头(含 Authorization、Cookie)直接打到日志文件里——密钥、token、session ID 全暴露。审计不是“加个日志”,而是对敏感字段做脱敏或跳过记录。必须从 fiber.New() 开始构建空实例,再按需注册审计中间件,否则所有日志配置都无效。
审计内容要区分读/写操作并控制采样率
全量记录每条请求会拖垮 I/O,尤其高并发时 TTFB 增加 0.3–0.8ms。真实场景中只需审计:POST/PUT/DELETE 路由、状态码 ≥400 的响应、或匹配特定路径前缀(如 /api/admin/)。建议用随机采样(如 1%)+ 错误强制记录双策略:
- 对
c.Method()是"POST"或"PUT"的请求,记录完整请求体(但先调c.Body()前检查c.Get("Content-Type")是否为application/json,避免解析非 JSON 体) - 对
c.Response().StatusCode()≥400 的响应,强制记录c.Path()、c.Method()、耗时、错误信息 - 用
rand.Float64() 控制采样,别用时间戳取模——会导致日志峰谷集中
审计日志不能直接用 fmt.Print 或 fiber.Logger()
fmt.Print() 没有结构化字段,查问题时得 grep 文本;fiber.Logger() 默认输出完整 Authorization 头,且无法关闭敏感字段。正确做法是用 zerolog 或 zap 构造结构化日志,并显式过滤:
- 从
c.Request().Header.Peek("Authorization")拿原始值,用正则替换掉 Bearer 后的 token:regexp.MustCompile(`Bearer\s+[a-zA-Z0-9_\-]+`).ReplaceAllString(val, "Bearer ***") - 记录客户端 IP 时,优先取
c.Get("X-Forwarded-For"), fallback 到c.IP(),但别记录内网地址(如10.0.0.0/8) - 日志写入文件时,按天切分,文件名用
logs/access-+time.Now().Format("2006-01-02")+".log",避免单文件过大
审计中间件里别碰 ctx.Next() 之后的逻辑
常见错误是在审计中间件末尾写 err := c.Next(); log.Info().Str("path", c.Path()).Err(err).Send()——此时响应可能已写出,c.Response().StatusCode() 还是 0,而 err 是 nil。真正能拿到最终状态码和响应体长度的位置,只在 c.Next() 返回后、且未调用任何 c.Send* 方法前:
- 必须在
c.Next()后立刻读c.Response().StatusCode()和c.Response().BodyWriter().Size() - 如果业务 handler 里已经调了
c.Status(401).JSON(...),你再试图读c.Response().Body()会返回空——Fiber 不缓存已写出的响应体 - 审计字段应尽量前置:路径、方法、起始时间、客户端 IP 在进入
c.Next()前就采集,避免后续 handler 修改c.Locals导致覆盖


















