-
小怪兽爱吃肉
这种方法是可行的。 type loggingResponseWriter struct { http.ResponseWriter statusCode int } func NewLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter { return &loggingResponseWriter{w, http.StatusOK} } func (lrw *loggingResponseWriter) WriteHeader(code int) { lrw.statusCode = code lrw.ResponseWriter.WriteHeader(code) } func wrapHandlerWithLogging(wrappedHandler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { log.Printf("--> %s %s", req.Method, req.URL.Path) lrw := NewLoggingResponseWriter(w) wrappedHandler.ServeHTTP(lrw, req) statusCode := lrw.statusCode log.Printf("<-- %d %s", statusCode, http.StatusText(statusCode)) }) }
-
泛舟湖上清波郎朗
使用内格罗尼。它的工作原理与@huangapple 的答案相同,但处理程序实际上实现了所有接口。import ( "github.com/urfave/negroni")func wrapHandlerWithLogging(wrappedHandler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { log.Printf("--> %s %s", req.Method, req.URL.Path) lrw := negroni.NewResponseWriter(w) wrappedHandler.ServeHTTP(lrw, req) statusCode := lrw.Status() log.Printf("<-- %d %s", statusCode, http.StatusText(statusCode)) })}
-
慕桂英546537
长话短说,您应该自己包装 http.ResponseWriter 或使用库。如果你想自己实现它,你可以从Negroni源代码中找到一些提示
-
精慕HU
在我的例子中,我不使用外部库,我不想包装http.ResponseWriter. 我必须在请求的上下文中添加响应的状态,以便以后在日志记录中使用。所以我创建了一个小帮手来同时在 ResponseWriter 和请求的上下文中写入状态。type AppContext stringvar StatusCode = AppContext("statuCode")func WriteHeaderAndContext(w http.ResponseWriter, statusCode int, r *http.Request) { ctx := context.WithValue(r.Context(), StatusCode, statusCode) *r = *(r.WithContext(ctx)) w.WriteHeader(statusCode)}在日志记录中,我将值检索为r.Context().Value(StatusCode)缺点发生在被叫方,看起来有点不寻常。例如WriteHeaderAndContext(w, http.StatusCreated, r)我们通常做的地方w.WriteHeader(http.StatusCreated)