基于Gorilla Mux实现通用请求计数的logHandler方法开发咨询
实现通用的Gorilla Mux请求日志处理器
要实现这个能统计所有入站请求的logHandler,核心是要捕获请求的关键元数据(比如方法、路径、状态码、耗时等),其中状态码需要我们自己包装ResponseWriter来获取——因为标准库的http.ResponseWriter并没有暴露这个信息。下面是完整的实现方案:
1. 包装ResponseWriter捕获状态码
首先定义一个自定义的ResponseWriter结构体,用来拦截并记录响应的状态码:
import ( "log" "net/http" "time" ) // loggingResponseWriter 包装标准ResponseWriter,用来捕获响应状态码 type loggingResponseWriter struct { http.ResponseWriter statusCode int } func newLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter { // 默认状态码为200(如果handler没有主动调用WriteHeader的话) return &loggingResponseWriter{w, http.StatusOK} } func (lrw *loggingResponseWriter) WriteHeader(code int) { lrw.statusCode = code lrw.ResponseWriter.WriteHeader(code) }
2. 实现logHandler核心逻辑
现在可以在logHandler里完成请求前的计时、请求后的日志统计逻辑:
func logHandler(fn http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // 1. 记录请求开始时间 start := time.Now() // 2. 包装ResponseWriter以捕获状态码 lrw := newLoggingResponseWriter(w) // 3. 调用实际的业务处理器处理请求 fn(lrw, r) // 4. 计算请求耗时 duration := time.Since(start) // 5. 输出日志(这里用标准log包,你也可以换成结构化日志库) log.Printf( "method=%s path=%s status=%d duration=%s remote_addr=%s", r.Method, r.URL.Path, lrw.statusCode, duration, r.RemoteAddr, ) } }
3. 扩展优化建议
如果需要更丰富的日志维度,可以根据需求添加:
- 记录请求头信息(比如
r.Header.Get("User-Agent")、r.Header.Get("X-Request-ID")) - 按需记录请求体(注意:大请求体会影响性能,建议只在调试环境开启)
- 使用结构化日志库(如Zap、Logrus)输出JSON格式日志,方便后续日志分析系统解析
- 添加请求追踪ID,用于分布式链路追踪场景
你的现有路由集成
你的现有代码已经正确使用了这个handler,保持原样即可:
api.HandleFunc("/foo", logHandler(mypackage.fooHandler)).Methods("GET") api.HandleFunc("/bar", logHandler(mypackage.barHandler)).Methods("GET")
内容的提问来源于stack exchange,提问作者Rogier Lommers
相关产品推荐
相关产品推荐

