Go Web日志中间件通过包装http.Handler拦截请求,记录方法、路径、状态码、耗时、客户端IP等;需自定义ResponseWriter捕获状态码和响应字节数,建议结构化输出并过滤敏感信息。

在 Go Web 开发中,用中间件记录请求日志是最常用、最轻量也最可控的方式。核心思路是:在 HTTP 处理链的入口处拦截请求,记录方法、路径、状态码、耗时、客户端 IP 等关键信息,再交给后续 handler 处理。
定义日志中间件函数
中间件本质是一个接收 http.Handler 并返回新 http.Handler 的函数。它包装原始 handler,在执行前后插入日志逻辑:
- 使用
time.Now()记录开始时间,time.Since()计算耗时 - 从
req.RemoteAddr或X-Forwarded-For头提取真实客户端 IP - 创建自定义
ResponseWriter包装器,捕获写入时的状态码和响应字节数 - 日志建议用结构化格式(如 JSON)或标准字段对齐的文本,方便后续解析
捕获响应状态码和字节数
Go 的 http.ResponseWriter 默认不暴露状态码和写入长度,需自行封装:
- 定义一个结构体,内嵌
http.ResponseWriter,并添加status和written字段 - 重写
WriteHeader(statusCode int)方法,保存状态码 - 重写
Write(p []byte) (int, error)方法,累加写入字节数,并在首次写入时补调WriteHeader(http.StatusOK) - 这样就能在 defer 的日志语句中准确拿到最终状态码和响应体大小
集成到 HTTP 路由中
以 net/http 为例,直接用 http.Handle 或 http.HandleFunc 套一层中间件即可:
立即学习“go语言免费学习笔记(深入)”;
http.Handle("/api/", loggingMiddleware(http.StripPrefix("/api", apiHandler)))- 若用 Gin,可用
router.Use(Logger());Echo 则是e.Use(middleware.Logger())(内置) - 生产环境建议搭配日志库如
zap或zerolog,支持异步写入、滚动切割、JSON 输出等 - 避免在日志中打印敏感内容(如 Authorization、密码、身份证号),可对 Header 或 Query 做白名单过滤
基本上就这些。不复杂但容易忽略细节——尤其是状态码捕获和 client IP 的正确提取。写一次,所有路由自动受益。










