beego.setlogger 必须在 beego.run() 之前且 beeapp 初始化后调用,否则被默认 logger 覆盖;文件日志需配置轮转参数;多模块日志需用 registerlogger 创建命名 logger;json 日志需自定义 adapter 或绕过 beego logger。

beego.SetLogger 为什么没生效
常见原因是调用时机太晚——beego.SetLogger 必须在 beego.Run() 之前执行,且不能晚于 beego.BeeApp 初始化(即 beego.AppConfig 加载后)。如果放在控制器或中间件里调用,日志配置会被默认的 console logger 覆盖。
实操建议:
- 统一在
main.go的init()或main()函数开头调用beego.SetLogger - 避免在
beego.Router注册之后、或任何beego.Handler执行路径中修改 logger - 确认未同时调用
beego.SetLevel和beego.SetLogPath——它们会触发内部重置 logger 实例
日志输出到文件但不轮转?
Beego 默认的 file 日志 adapter 不带自动轮转能力。直接传入文件路径(如 "logs/app.log")会导致单文件无限追加,磁盘爆满风险高。
正确做法是启用 file adapter 的轮转参数,或改用更可控的 async + file 组合:
- 使用
beego.SetLogger("file", `{"filename":"logs/app.log","maxlines":100000,"maxsize":10485760,"daily":true,"maxdays":7}`) -
maxlines和maxsize任一触发即切文件;daily:true优先级更高,每天零点强制切分 - 确保
logs/目录存在且进程有写权限,否则静默失败(无错误提示,日志直接丢失)
如何让不同模块写入不同日志文件
Beego 的全局 logger 不支持多实例,但可通过 beego.NewLogger() 手动创建独立 logger,并用 beego.RegisterLogger 注册为命名 logger(如 "mysql"、"cache"),再在业务代码中显式调用。
关键步骤:
- 在
main.go初始化阶段调用beego.RegisterLogger("mysql", mysqlLogger),其中mysqlLogger是用beego.NewLogger("file", ...)创建的 - 业务中获取:
l := beego.GetBeeLogger().GetLogger("mysql"),然后l.Info(...) - 注意:这些命名 logger 不受
beego.SetLevel全局控制,需单独设级别,例如mysqlLogger.SetLevel(beego.LevelDebug)
JSON 格式日志怎么输出
Beego 原生不支持 JSON 输出格式,file 和 console adapter 都固定为文本行格式。强行拼接 JSON 字符串会导致时间戳、级别字段重复,且无法被标准日志采集器(如 Filebeat、Loki)正确解析。
可行方案只有两个:
- 自定义 adapter:实现
beego.LoggerInterface,在WriteMsg中构造 JSON 对象(含level、time、msg、file、line等字段),再用beego.SetLogger("custom", ...)注册 - 绕过 Beego logger:直接用
github.com/json-iterator/go+os.OpenFile写入,适合对日志结构强约束的场景(如对接 OpenTelemetry) - 别试图用
fmt.Sprintf把Infof的 msg 参数提前 JSON 化——会破坏 Beego 的字段提取逻辑,且fileadapter 仍会额外添加前缀
最易被忽略的是权限与路径:Beego 日志路径是相对当前工作目录(不是二进制所在目录),go run main.go 和 ./app 启动时的 logs/ 位置可能完全不同。上线前务必用 os.Getwd() 打印一次实际路径。











