直接用 lumberjack.logger 替换 os.file 即可实现 gin 日志轮转,它实现了 io.writecloser,可直接赋值给 gin.defaultwriter;需避免混用 os.create 和 lumberjack,filename 用绝对路径或确保权限的相对路径,maxsize(mb)、maxbackups(保留数)、maxage(天)需合理配置;gin.logger() 不支持直接传入 zap/logrus 实例,仅可通过替换 gin.defaultwriter 或重写中间件接管日志;启用 multiwriter 时须提前调用 gin.disableconsolecolor() 防止 ansi 转义序列污染文件;高频健康检查路径如 /healthz 必须通过 loggerwithconfig.skippaths 过滤,否则因高频率短日志导致轮转过快。

直接用 lumberjack.Logger 替换 os.File 就能轮转
Gin 默认日志输出只支持 *os.File,但轮转必须用支持切割的句柄。lumberjack.Logger 是最轻量、最稳定的选择,它本身就是一个实现了 io.WriteCloser 的结构体,可直接赋值给 gin.DefaultWriter 或传入 io.MultiWriter。
常见错误是试图把 lumberjack.Logger 和普通文件混用:比如先 os.Create("app.log") 再套一层 lumberjack —— 这会导致双写或权限冲突。正确做法是跳过 os.Create,直接初始化 lumberjack.Logger:
-
Filename必须是绝对路径或确保进程有写权限的相对路径(推荐用filepath.Join(logDir, "access.log")) -
MaxSize单位是 MB,设为10表示单文件超 10MB 就切新文件 -
MaxBackups控制保留几个旧文件,设为0表示不保留(慎用),5是较安全的默认值 -
MaxAge单位是天,设为7表示 7 天前的归档自动删除
gin.Logger() 中间件不能直接接收 zap 或 logrus 实例
很多人误以为只要把 logrus.Logger 或 zap.Logger 传进 gin.Logger() 就能接管日志 —— 实际上 gin.Logger() 是个固定实现,只依赖 gin.DefaultWriter 和内置格式,它不接受任何第三方 logger 实例。
真正可行的路径只有两条:
- 用
gin.New()初始化引擎,然后自己重写Logger()中间件(例如基于logrus或zap构造一个符合gin.HandlerFunc签名的函数) - 保持使用
gin.Default(),但只替换底层输出目标(即改gin.DefaultWriter),让原有Logger()中间件继续工作,只是把输出重定向到lumberjack或MultiWriter
后者更轻量、兼容性更好,适合快速落地;前者灵活但需自行处理请求耗时、状态码、响应体长度等字段拼接逻辑。
控制台和文件同时输出时,gin.DisableConsoleColor() 必须提前调用
如果启用 io.MultiWriter(file, os.Stdout),又没禁用颜色,日志文件里会塞满类似 \x1b[36m 这类 ANSI 转义序列,grep 查找、ELK 解析、甚至 vim 打开都会乱码。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
这个调用顺序不能错:
- 必须在设置
gin.DefaultWriter之前执行gin.DisableConsoleColor() - 不能放在
main()末尾,也不能放在路由注册之后 - 若项目用了多个 logger(比如单独的 error 日志),也要对对应 writer 单独处理颜色问题
注意:DisableConsoleColor() 只影响 gin.Logger() 输出,不影响你手动调用的 fmt.Println 或其他库的日志。
高频健康检查路径必须用 SkipPaths 过滤,否则轮转失效
轮转不是万能的。如果服务暴露了 /healthz 或 /metrics,且每秒被调用几十次,即使设置了 MaxSize: 10,也可能几分钟就切出一个新文件 —— 不是因为日志量大,而是因为每条日志都极短但频次太高,IO 次数爆炸。
gin.LoggerWithConfig 提供了 SkipPaths 字段,它是字符串切片,填入要跳过的路径即可:
- 写成
[]string{"/healthz", "/readyz", "/metrics"},注意开头的/ - 匹配是精确路径匹配,不支持通配符或正则
- 该过滤只作用于
gin.Logger()中间件,不影响你自定义的其他日志逻辑
漏掉这一步,磁盘空间消耗速度可能远超预期,尤其在容器环境里容易触发 OOM 或 volume 满。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










