fiber 默认 logger 无法定制格式,因其源码硬编码日志字符串且无 format 字段;需手写中间件实现字段顺序调整、trace_id 注入、json 输出等,核心是记录起止时间、状态码与耗时,并注意 body 复用与多 writer 安全轮转。

默认 fiber.Logger() 只能控制是否带颜色、是否显示状态码或字节数,不能改字段顺序、加 trace_id、输出 JSON 或删时间戳——这些必须手写中间件。
为什么 fiber.Logger() 配置项里没有 format 字段
因为它的源码里压根没留格式化入口:只接收一个 io.Writer 和几个布尔开关(如 EnableColor),所有日志字符串(比如 "12:34:56 GET /api 200 12ms 132B")都是硬编码拼好的。你传进去的 fiber.Config{Logger: ...} 里根本没有 Format 这个字段,试图加它会静默忽略。
- 想删掉毫秒耗时?不行,它写死在中间件里
- 想把
status改成小写?不行,fmt.Sprintf调用是固定的 - 想加
X-Request-ID头?得自己解析c.Get("X-Request-ID")并拼进去
怎么手写可定制的请求日志中间件
核心就是用 time.Now() 记起点、c.Next() 执行路由、再取响应状态和耗时,最后用 fmt.Sprintf 拼你要的格式。
- 必须在
c.Next()后调c.Response().StatusCode(),否则返回0 - 别用
time.Now().UnixMilli()算耗时,要基于start := time.Now()变量 - 路径含 query?用
c.OriginalURL(),但注意 XSS 风险,建议对特殊字符做简单转义 - 要支持
trace_id?从c.Get("trace-id")或c.Locals("trace_id")读,前提是上游已注入
示例片段:
func LoggerPrint() fiber.Handler {
return func(c *fiber.Ctx) error {
start := time.Now()
err := c.Next()
status := c.Response().StatusCode()
duration := time.Since(start).Milliseconds()
traceID := c.Get("X-Trace-ID")
logLine := fmt.Sprintf("[%s] %s %s %d %.2fms %s\n",
start.Format("2006-01-02 15:04:05"),
strings.ToUpper(c.Method()),
c.OriginalURL(),
status,
duration,
traceID,
)
fmt.Print(logLine)
return err
}
}
如何同时输出到文件和终端且安全轮转
fiber.Logger() 不支持多 writer,也不能自动切日志文件。得靠 io.MultiWriter 拼接,再用 lumberjack.Logger 替代裸 *os.File 来轮转。
- 别在中间件里每次
os.OpenFile(),全局初始化一次lumberjack.Logger实例 - 用
os.O_APPEND | os.O_CREATE | os.O_WRONLY,别用os.Create,否则日志每天被覆盖 - 把
os.Stdout和lumberjack.Logger一起塞进io.MultiWriter,再传给fiber.Config{Logger: ...} - 如果要用结构化日志(比如 JSON),直接跳过
fiber.Logger(),用zerolog.New(mw)构造 logger,然后在中间件里调logger.Info().Str("path", ...).Int("status", ...).Send()
调试时记录请求体和响应体的关键限制
fasthttp 复用 buffer,c.Body() 只能读一次。下游 handler 再读就空了。
- 记录前先调
c.Request().ForceRequestBodyReader(),否则CopyTo可能失败 - 只对
POST/PUT且Content-Type是application/json或application/x-www-form-urlencoded的请求解析 body - 跳过
multipart/form-data,否则干扰文件上传 - body 截断长度建议设为 512 字节,防大 payload 打爆磁盘或内存
- GET/HEAD 请求没有 body,直接跳过解析,否则
c.Body()panic
真正难的不是拼格式,而是 body 复制时机、buffer 复用规则、以及多 writer 生命周期管理——这三个点漏一个,日志就不可靠。











