启用Iris内置请求日志中间件需调用app.Use(iris.Logger),且必须置于所有路由注册之前;它线程安全、自动记录方法、路径、状态码、时长和字节数,但不支持自定义格式或输出目标。

如何启用Iris内置请求日志中间件
Iris自带iris.Logger中间件,开箱即用,但默认不启用。它比手写fmt.Printf更可靠,能自动记录方法、路径、状态码、响应时长和字节数,且线程安全。
直接在app.Use(iris.Logger)后调用即可,注意它必须放在所有路由注册之前(否则部分请求可能漏记),但可放在app.Use()链的任意位置——它不改变流程,只追加日志。
- 别把它塞进某个
Party里,除非你只想记录子路径;全局日志就该挂到根app - 若同时用了自定义日志中间件(如写文件),
iris.Logger的输出会混在其中,建议二选一,避免重复 - 本地开发可放心用,生产环境若QPS高,需确认日志IO是否成瓶颈;此时可考虑异步写或降级为采样日志
自定义日志格式与输出目标
iris.Logger默认输出到os.Stdout,格式固定。如需写入文件、添加traceID或调整字段顺序,得自己实现一个中间件,核心是读取ctx.Recorder().StatusCode()、ctx.Recorder().BodyLength()和ctx.GetDuration()。
关键点:必须在ctx.Next()之后读取响应信息,否则StatusCode()还是0,BodyLength()为-1。
- 示例片段:
func customLogger() iris.Handler { return func(ctx iris.Context) { start := time.Now() ctx.Next() // 必须先放行 status := ctx.Recorder().StatusCode() bodyLen := ctx.Recorder().BodyLength() duration := time.Since(start).Microseconds() log.Printf("[%s] %s %s %d %dμs %d", time.Now().Format("2006-01-02T15:04:05"), ctx.Method(), ctx.Path(), status, duration, bodyLen) } } - 别用
ctx.Request().URL.String()取完整URL——它不含Host,且query参数未标准化;用ctx.FullRequestURI()更准 - 如果用了
ctx.StopExecution()(如OPTIONS预检),BodyLength()恒为0,但StatusCode()仍有效
过滤日志:跳过健康检查与静态资源
全量记录会导致日志爆炸,尤其/health、/metrics、/favicon.ico这类高频请求。Iris不提供内置白名单,必须在中间件内手动判断并跳过。
重点不是“不记录”,而是“不打日志但继续执行”——所以不能return,而要调ctx.Next()后直接返回。
- 路径判断用
ctx.Path(),不是ctx.Request().URL.Path;前者已去除查询参数且标准化,后者可能含未解码字符 - 常见漏判:
/healthz、/readyz、/ping,建议用strings.HasPrefix(ctx.Path(), "/health") || ctx.Path() == "/ping"覆盖 - 静态资源如
/static/或/assets/,若用app.HandleDir托管,其请求也会进中间件,需一并过滤
生产环境日志注意事项
线上服务对日志有更高要求:结构化、可检索、低干扰。Iris本身不绑定任何日志库(如zap或zerolog),需自行桥接。
最简做法是把log.Printf换成结构化日志实例的Info方法,但要注意:日志字段值必须在ctx.Next()后获取,否则全是零值。
- 别在中间件开头就提取
ctx.Params().Get("id")并打日志——路径参数可能根本不存在,返回空字符串,掩盖真实问题 - 敏感字段(如
Authorization头、password参数)必须显式脱敏,Iris不自动过滤 - 若启用了
iris.Compression中间件,BodyLength()是压缩后大小,和原始响应体不一致,监控带宽需另计
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











