iris框架默认日志仅输出到终端,不自动写入文件;需手动替换logger.new()的writer为文件句柄实现落盘,结构化日志须弃用内置logger改用logrus等第三方库。

Iris 框架默认不自动写入文件日志,所有日志都输出到终端(stdout/stderr),必须手动配置才能落盘或结构化。
iris.Logger() 默认行为与常见误判
很多人以为 app.Logger().SetLevel("debug") 就开启了文件日志,其实它只控制日志级别和终端输出内容。Iris 的 Logger() 是一个内存中的日志实例,不带任何持久化能力 —— 它不会创建文件、不轮转、不压缩、也不支持 JSON 格式输出。
- 调用
app.Logger().Infof("hello")仅打印到控制台,进程重启后日志即丢失 - 即使加了
logger.New()中间件,也只是把 HTTP 请求日志格式化后输出到终端,不是写文件 - 没有内置 Hook 机制(不像 Logrus),无法直接挂载文件写入逻辑
用 iris/middleware/logger + 自定义 io.Writer 写文件
要真正落地日志,得把 logger.New() 的输出目标从默认的 os.Stdout 替换为文件句柄。关键不是“配 logger”,而是“换 writer”。
- 先创建带行缓冲的文件:
f, _ := os.OpenFile("access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) - 再包装成
io.Writer并传给中间件:logger.New(logger.Config{Writer: f}) - 注意:
logger.New()不接受logrus.Logger或其他第三方日志对象,只能接原生io.Writer - 别忘了在程序退出前
f.Close(),否则最后一批日志可能因缓冲未刷而丢失
package main
import (
"os"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/logger"
)
func main() {
f, _ := os.OpenFile("access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
defer f.Close()
app := iris.New()
app.Use(logger.New(logger.Config{Writer: f}))
app.Get("/ping", func(ctx iris.Context) { ctx.WriteString("pong") })
app.Run(iris.Addr(":8080"))
}
结构化日志需绕过内置 logger,改用第三方库
Iris 内置日志是纯文本、无字段、不可扩展的。如果需要记录 user_id、request_id、status_code 等结构化字段,必须弃用 logger.New(),改用 logrus 或 zerolog 等库,并在中间件里手动注入上下文。
- 在请求中间件中用
ctx.Values().Set("request_id", uuid.New().String())存 ID - 在响应后(用
ctx.Next()后)读取状态码、耗时等,构造logrus.Fields - 避免在每个 handler 里重复写日志,统一收口到 recover + response 写入逻辑中
- 不要试图把
logrus.Entry塞进iris.Context,它不是线程安全的;每次用logrus.WithFields()新建即可
最易被忽略的一点:Iris 的 logger.New() 中间件只记录请求开始到响应头写出前的日志,不包含响应体大小、真实耗时(受网络延迟影响)、或 panic 后的堆栈 —— 这些必须靠自定义中间件补全。文件日志若没加锁或没用缓冲 writer,在高并发下会丢行或错乱。











