iris 的 setformat() 仅切换预设格式,无法注入 trace_id 等动态字段;需在 app.run() 前用 zerolog.new().with().timestamp() 构造新 logger 并通过 setoutput() 替换底层实例。

直接改 app.Logger().SetFormat() 不起作用——Iris 的日志格式控制权不在这个方法手上,它只管“选预设格式”,真要定制字段和结构,得动底层 zerolog 实例。
为什么 SetFormat("json", " ") 看似生效但加不了 trace_id?
Iris 的 SetFormat 只是快捷调用内置 formatter(比如 golog.JSONFormatter),它不支持动态注入请求上下文字段。你传 "json",日志变 JSON 格式了,但所有字段还是固定那几个:time、level、message,trace_id 或 client_ip 这类变量根本进不去。
-
SetFormat本质是替换整个 formatter 实例,但 Iris 没暴露初始化时的构造参数入口 - 真正可控的时机是
app.Logger().Output()之后、app.Run()之前,用zerolog.ConsoleWriter或自定义LevelWriter重装 logger - 如果你已经调用了
SetFormat,再手动替换底层 zerolog 实例,前者会被后者覆盖
怎么在请求日志里塞 trace_id 和 client_ip?
必须绕过 SetFormat,从零构造一个带上下文字段的 zerolog.Logger,并用 app.Logger().SetOutput() 替换掉默认实例。
- 先从
ctx.GetHeader("X-Request-ID")或生成逻辑取trace_id;client_ip推荐用ctx.RemoteAddr(),若走代理则 fallback 到ctx.GetHeader("X-Forwarded-For")并做基础校验(防伪造) - 不要在中间件里直接调
app.Logger().With().Str("trace_id", ...)—— 那只是临时 clone,不会影响后续请求日志输出 - 正确做法:写个中间件提取字段 → 存到
ctx.Values()→ 在日志 writer 的Write方法里读取并注入zerolog.Event - 更稳妥的是用
zerolog.With().Caller().Timestamp()链式初始化新 logger,再通过app.Logger().SetOutput()绑定
文件输出时颜色和缩进自动失效,怎么保持可读性?
往文件写日志时,Iris 默认禁用颜色和美化缩进,这是 zerolog 的行为,不是 bug。想让文件日志也带结构又易读,得自己包一层。
- 用
zerolog.ConsoleWriter{Out: f, NoColor: true}初始化 writer,它会保留 JSON 字段 + 换行 + 缩进,只是去掉 ANSI 色彩 - 别用
os.Create("iris.log")后直接SetOutput(f)—— 这样连 timestamp 都没有,得先用zerolog.New(f).With().Timestamp()包一层 - 如果坚持用
golog原生能力,SetFormat("json", " ")的第二个参数是缩进字符串,但仅对 JSON 生效,且无法加自定义字段 - 注意文件权限:用
os.OpenFile("iris.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)替代os.Create,避免重启后日志被清空
最易被忽略的一点:Iris 的 Logger() 是全局单例,一旦你在中间件或 handler 里调 ctx.Application().Logger().With().Str(...),那个 With() 返回的是临时 event,不改变底层输出行为——所有定制必须发生在 app.Run() 前,且只做一次替换。











