zap.newproduction()默认不输出debug日志且以json格式写入os.stderr,无颜色和换行,易被误判为无输出;调试应改用zap.newdevelopment()或显式设置日志等级。

直接用 log.Printf 或全局 log.SetOutput 在框架里打日志,上线后基本等于没日志——字段缺失、级别混乱、并发错行、崩溃前日志丢失,排查时只能靠猜。
zap.NewProduction() 为什么控制台看不到日志?
不是没输出,是它默认只输出 InfoLevel 及以上,且走 os.Stderr + JSON 编码,没有换行和颜色,一整行挤在一起,肉眼根本看不出在动。
- 调试阶段别硬扛,改用
zap.NewDevelopment():自动带颜色、文件行号、允许Debug()输出 - 非得用
NewProduction()?显式放开等级:zap.LevelEnablerFunc(func(lvl zapcore.Level) bool { return lvl >= zapcore.DebugLevel }) -
JSON字段名固定("level"、"ts"、"msg"),别指望它像fmt.Printf那样自由拼字符串
logrus.WithFields 和 zap.SugaredLogger 的字段写法不兼容
混用会丢字段甚至 panic,两边结构化逻辑完全不同。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
logrus.WithFields(logrus.Fields{"user_id": 123, "action": "login"})→ 字段是map[string]interface{} -
zap.Sugar().Infow("user login", "user_id", 123, "action", "login")→ 必须成对传参,数量为偶数,否则 runtime panic - 原生
zap.Logger更严格:logger.Info("msg", zap.Int("user_id", 123), zap.String("action", "login")),类型必须匹配,zap.Int传 string 就崩 - 嵌套结构体:logrus 默认支持;zap 必须显式用
zap.Any("data", obj),且默认只序列化 10 层,过深会被截断
桌面应用或长期运行服务的日志路径和轮转怎么写才不踩坑?
相对路径 "./logs/app.log" 在双击运行的 .exe/.app 里基本失效,工作目录不可控,还可能因权限问题静默失败。
- 路径必须绝对:
exePath, _ := os.Executable()→logDir := filepath.Join(filepath.Dir(exePath), "logs")→os.MkdirAll(logDir, 0755) - 别写死
"C:\Program Files\...",Windows 下优先用os.UserCacheDir()或os.UserConfigDir() - 标准库
log不支持轮转,必须引入lumberjack.Logger:设MaxSize: 10 (10MB)、<code>MaxBackups: 5、LocalTime: true - 高频率写入时,
lumberjack的 Rotate 是同步的,建议前置一个chan string做缓冲,goroutine 消费落地
goroutine 里打日志,进程退出前日志丢了怎么办?
不是日志没记,是缓冲区没 flush 就被 OS 强杀。尤其用 os.Exit(0) 或 panic 后没等 sync,zap 和 logrus 默认都是同步刷盘,但文件写入仍有缓冲。
- 避免
os.Exit(),改用return让defer logger.Sync()生效 - 若必须提前退出,手动调
logger.Sync()(zap)或entry.Logger.Close()(logrus v1.9+) - 更稳妥的是监听
os.Interrupt或syscall.SIGTERM,收到信号后 sync 再 exit - 敏感场景可加内存环形缓冲(如
github.com/cespare/xxhash+ slice),崩溃前最后 100 条日志可导出供用户反馈
真正难的不是选 zap 还是 logrus,而是字段怎么带、路径怎么算、退出前怎么保底、goroutine 之间怎么隔离上下文——这些细节不抠清楚,再 fancy 的日志库也只是一堆无法关联的碎片。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










