Beego 默认日志模块需在 main.go 中 beego.Run() 前调用 logs.SetLogger 启用文件输出,仅改 app.conf 的 loglevel 无效;支持 AdapterFile/Console/Conn,但多次 SetLogger 会覆盖;分模块日志需用 logs.NewLogger() 创建独立实例;自定义格式需 SetLogFuncCall(true) 加手动拼接上下文;生产环境应启用 async 写入、预建日志目录并配合 logrotate 轮转。

Beego 默认日志模块怎么启用和配置
Beego 自带 logs 模块,不需要额外安装依赖,但默认只输出到控制台且级别为 LevelDebug,生产环境必须显式配置输出路径和级别。
关键点是:不调用 logs.SetLogger 就不会写文件,哪怕你改了 conf/app.conf 里的 loglevel 也没用。
- 在
main.go初始化阶段(beego.Run()前)调用logs.SetLogger,例如:logs.SetLogger(logs.AdapterFile, `{"filename":"logs/app.log"}`) -
filename路径建议用绝对路径或相对于可执行文件的相对路径;若用相对路径,确保运行时工作目录正确(常见坑:Docker 或 systemd 启动时工作目录不是项目根目录) - 支持多个日志适配器:
AdapterFile、AdapterConsole、AdapterConn(如 syslog),但不能靠多次调用SetLogger叠加——它会覆盖前一次配置
如何按模块/控制器分文件记录日志
Beego 的 logs.BeeLogger 是全局单例,不原生支持多实例。想实现 user.log、order.log 这类分离,得自己封装一个日志工厂。
核心思路:每个模块初始化自己的 logs.BeeLogger 实例,用 logs.NewLogger() 创建,并单独调用 SetLogger。
- 不要直接用
logs.Info()全局函数,改用自定义 logger 实例:userLogger := logs.NewLogger(1000)<br>userLogger.SetLogger(logs.AdapterFile, `{"filename":"logs/user.log"}`) - 注意缓冲区大小参数(上例中
1000):太小易丢日志,太大占内存;一般 1000–5000 足够 - 避免在 controller 方法里反复新建 logger —— 应在
init()或main()中创建并导出为包级变量
日志格式和字段怎么自定义
Beego 默认日志不带请求 ID、用户 ID、耗时等上下文信息,纯靠 logs.Info("msg") 无法满足追踪需求。
解决方案分两层:基础格式靠 logs.SetLogFuncCall(true) 加入文件行号;业务字段必须手动拼接或借助中间件注入。
- 开启调用栈信息:
logs.SetLogFuncCall(true),会追加类似[asm_amd64.s:1581]的位置标记 - 在
controllers/base.go的基类BaseController的Prepare()方法中生成请求 ID,并存入this.Data["curReqId"];打印时显式带上:this.LogInfo("req_id=%s user_id=%d action=pay", this.Data["curReqId"], userId) - 别依赖
fmt.Sprintf拼接日志字符串——容易 panic;用 logger 的Infof/Warnf等变参方法更安全
线上环境要注意的性能与权限问题
日志写磁盘是同步阻塞操作,高频写入(比如每秒百次)会拖慢接口响应;同时,文件权限配置错误会导致启动失败却无明确报错。
- 使用异步写入:设置
Async参数(仅AdapterFile支持):logs.SetLogger(logs.AdapterFile, `{"filename":"logs/app.log","async":true}`),但注意:崩溃时可能丢失最后几条日志 - 确保日志目录存在且进程有写权限;推荐在启动脚本中提前
mkdir -p logs && chmod 755 logs - 定期轮转不能靠 Beego 内置功能(它不支持按时间/大小自动切分),需配合外部工具(如
logrotate)或升级到logs.AdapterFile的高级配置(v2.0+ 支持maxlines/maxsize,但需确认你用的 Beego 版本)
真正麻烦的是跨服务追踪和结构化日志——Beego 原生日志模块只适合简单场景,一旦需要对接 ELK 或 OpenTelemetry,就得换用 zerolog 或 zap 并绕过 logs 模块。


















