Iris中间件需手动提取请求响应信息:用ctx.Method()、URL.String()、Header遍历(避Cookie)、io.ReadAll读Body后重置Body流,日志须放ctx.Next()后获取真实状态码和响应大小。

中间件里怎么拿到请求和响应的完整信息
Iris 的中间件函数接收 ctx iris.Context,它封装了底层 http.ResponseWriter 和 *http.Request。但直接打印 ctx.Request() 或 ctx.ResponseWriter() 只会输出指针地址,看不到实际内容。
要打印调试日志,得手动提取关键字段:方法、URL、Header、Body(注意 Body 只能读一次)、状态码、耗时。Iris 不提供开箱即用的“全量 dump”工具,必须自己组合。
-
ctx.Method()和ctx.Request().URL.String()是安全的,可直接用 - Header 用
ctx.Request().Header遍历,但别打Cookie字段(敏感) - Body 需先调用
ctx.Request().Body→ioutil.ReadAll(Go 1.19+ 用io.ReadAll),之后要重置ctx.Request().Body,否则后续 handler 读不到 - 响应体无法直接读(
ResponseWriter是写入接口),只能在ctx.StatusCode()和ctx.Response().Size()上做文章
为什么用 ctx.Next() 前后打日志会漏状态码和响应大小
因为 ctx.StatusCode() 在 ctx.Next() 返回前仍是 0,ctx.Response().Size() 同理——Iris 的响应缓冲机制决定了这些值只在写入真正发生后才更新。
正确做法是把日志逻辑放在 ctx.Next() 之后,并确保中间件注册顺序合理(比如你的日志中间件必须在所有业务 handler 之后执行,但仍在 iris.Logger() 之前)。
- 错误写法:
log.Printf("status: %d", ctx.StatusCode())放在ctx.Next()前 → 总是 0 - 正确写法:放在
ctx.Next()后,且中间件注册用app.Use(yourLogger)(不是app.UseRouter) - 注意:如果用了
ctx.StopExecution()或 panic,ctx.Next()后代码不执行,状态码可能还是初始值
Body 读取后怎么避免破坏后续处理
Iris 的 ctx.Request().Body 是单次读取流,读完就 EOF。业务 handler 如果也调 ctx.ReadBody() 或 ctx.PostValue(),会失败或返回空。
必须把读过的 Body 再包回 ctx.Request().Body。Go 标准库提供了 io.NopCloser 和 bytes.NewReader 组合方案:
bodyBytes, _ := io.ReadAll(ctx.Request().Body)
ctx.Request().Body = io.NopCloser(bytes.NewReader(bodyBytes))
// 然后才能安全地 log.Printf("body: %s", bodyBytes)
- 别用
ctx.Request().GetBody():Iris 默认没设置Request.GetBody,调用会 panic - 大 Body(如文件上传)慎用:全部读进内存可能 OOM,调试时建议加长度限制,比如只取前 1KB
- Content-Type 是
application/json时,可以额外json.Unmarshal格式化输出,但非必需
要不要直接用 iris.Logger() 替代自定义中间件
iris.Logger() 打印的是标准访问日志(method、path、status、latency),不包含 Header、Body、Query 参数等调试信息。它轻量、稳定、无副作用,适合生产环境。
自定义中间件适合开发/测试阶段查问题,比如排查前端传参格式错误、鉴权 header 缺失、JSON 解析失败原因。但它有成本:每次请求都序列化 Body、拼接字符串、IO 写日志,压测时会影响 QPS。
- 开发期:用自定义中间件 + 条件开关(如
if iris.IsDevelopment()) - 上线前务必关掉 Body 打印,至少保留 method/path/status/latency
- 线上出问题?优先用
ctx.Application().Logger().Infof()按需打点,而不是全局中间件
Body 和 Header 这类敏感数据,连开发环境都不该无条件全量打印——容易误提交到日志系统或被监控平台采集。



















