中间件函数签名必须是func(ctx iris.Context),不能少参数或多返回值,否则panic;本质是iris.Handler类型,需通过app.Use、Party.Use或路由末尾传入注册,且必须调用ctx.Next()触发后续处理器执行。

中间件函数签名必须返回 iris.Handler
Iris 的中间件本质是 iris.Handler 类型的函数,签名必须是 func(ctx iris.Context),不能少参数、不能多返回值。写成 func() error 或 func(ctx iris.Context) (int, error) 都会 panic,错误信息通常是 cannot use ... as iris.Handler。
日志中间件最简结构如下:
func loggingMiddleware() iris.Handler {
return func(ctx iris.Context) {
start := time.Now()
ctx.Next() // 执行后续处理器(含路由处理函数)
duration := time.Since(start)
fmt.Printf("[%s] %s %s %v\n",
ctx.RemoteAddr(),
ctx.Method(),
ctx.Request().URL.Path,
duration,
)
}
}
注意:ctx.Next() 是关键——它触发链式调用,缺了这句,后续 handler 完全不会执行。
注册位置决定作用范围:全局 / 路由组 / 单个路由
中间件生效范围完全取决于你把它传给哪个方法:
- 全局生效:用
app.Use(loggingMiddleware())—— 所有匹配路由(包括静态文件)都会走它 - 某组路由生效:用
adminGroup.Use(loggingMiddleware())—— 仅该Party下注册的路由触发 - 单个路由生效:在
Get/Post等方法末尾追加,如app.Get("/api/user", handler, loggingMiddleware())
常见误操作:把中间件当普通函数调用,比如 loggingMiddleware() 直接写在 Use 外面却不传入,导致日志只在启动时打一次。
避免阻塞和 panic:别在中间件里读取 ctx.Request().Body
Iris 的 ctx.Request().Body 是单次可读流,中间件里若调用 ioutil.ReadAll 或 ctx.PostValue 等依赖 body 解析的方法,会导致后续 handler 拿不到原始 body,引发空数据或 http: read on closed response body 错误。
如果真要记录请求体内容,必须先用 ctx.RecordRequestBody(true) 开启记录,再通过 ctx.RequestBody() 获取副本:
func loggingWithBody() iris.Handler {
return func(ctx iris.Context) {
ctx.RecordRequestBody(true) // 必须提前开启
ctx.Next()
body, _ := ctx.RequestBody()
fmt.Printf("body: %s\n", string(body))
}
}
但要注意:开启 RecordRequestBody 会增加内存开销,生产环境不建议对所有请求启用。
结合 ctx.Values() 传递上下文信息更安全
想在日志中加入 traceID、用户 ID 等字段?别靠闭包变量或全局 map,容易并发冲突。正确做法是用 ctx.Values().Set() 存,ctx.Values().Get() 取:
func traceIDMiddleware() iris.Handler {
return func(ctx iris.Context) {
traceID := uuid.NewString()
ctx.Values().Set("trace_id", traceID)
ctx.Next()
// 日志里可安全使用
fmt.Printf("[trace:%s] %s %s\n", traceID, ctx.Method(), ctx.Path())
}
}
多个中间件之间可通过 Values() 共享数据,且天然线程安全。比自定义 context.WithValue 更轻量,也比往 ctx.Request().Context() 塞东西更符合 Iris 设计习惯。
真正麻烦的是格式化输出和异步写入——标准 fmt.Printf 在高并发下会争抢 stdout,线上务必换成带缓冲的 logger(如 zerolog + os.Stdout),并且注意日志字段顺序和 JSON 化是否影响下游采集工具解析。


















