日志 http.响应器内容

前提:我发现了类似的问题,但在我的案例中不起作用,所以请不要将其标记为重复。


我在Go中有一个HTTP服务器,我已经创建了一个中间件来记录请求,响应时间,我也想记录响应。


我在包下调用的函数中使用过。如何正确获取响应正文、状态和标头,并将它们与其他数据一起记录?httputil.DumpRequestHTTPRequestlogw http.ResponseWriter


我的问题是:我想截获响应标头,状态和正文,并与请求和响应时间一起记录


代码如下:


log "core/logger"

...

func RequestLoggerMiddleware(next http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        start := time.Now()


        defer func() {

            log.Info(

                fmt.Sprintf(

                    "[Request: %s] [Execution time: %v] [Response: %s]",

                    log.HTTPRequest(r),

                    time.Since(start),

                    // RESPONSE DATA HERE !!!!!!!

                ))

        }()

        next.ServeHTTP(w, r)

    })

}


慕的地6264312
浏览 60回答 2
2回答

达令说

谢谢,@Sivachandran的回应。它几乎是完美的,只是由于指针而没有实现。http.ResponseWriter为了完整起见,我在这里发布了正确的解决方案代码,因为即使这个问题被给予了负分,也很难找到任何关于它的文档。Stackoverflow是一个交换问题的好地方,在我看来,这是一个非常好和困难的问题,无论是对于一个中间杠杆Golang程序员来说,所以它根本不配得负分!这就是解决方案,享受:// RequestLoggerMiddleware is the middleware layer to log all the HTTP requestsfunc RequestLoggerMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        start := time.Now()        rww := NewResponseWriterWrapper(w)        w.Header()        defer func() {            log.Info(                fmt.Sprintf(                    "[Request: %s] [Execution time: %v] [Response: %s]",                    log.HTTPRequest(r),                    time.Since(start),                    rww.String(),                ))        }()        next.ServeHTTP(rww, r)    })}// ResponseWriterWrapper struct is used to log the responsetype ResponseWriterWrapper struct {    w          *http.ResponseWriter    body       *bytes.Buffer    statusCode *int}// NewResponseWriterWrapper static function creates a wrapper for the http.ResponseWriterfunc NewResponseWriterWrapper(w http.ResponseWriter) ResponseWriterWrapper {    var buf bytes.Buffer    var statusCode int = 200    return ResponseWriterWrapper{        w:          &w,        body:       &buf,        statusCode: &statusCode,    }}func (rww ResponseWriterWrapper) Write(buf []byte) (int, error) {    rww.body.Write(buf)    return (*rww.w).Write(buf)}// Header function overwrites the http.ResponseWriter Header() functionfunc (rww ResponseWriterWrapper) Header() http.Header {    return (*rww.w).Header()}// WriteHeader function overwrites the http.ResponseWriter WriteHeader() functionfunc (rww ResponseWriterWrapper) WriteHeader(statusCode int) {    (*rww.statusCode) = statusCode    (*rww.w).WriteHeader(statusCode)}func (rww ResponseWriterWrapper) String() string {    var buf bytes.Buffer    buf.WriteString("Response:")    buf.WriteString("Headers:")    for k, v := range (*rww.w).Header() {        buf.WriteString(fmt.Sprintf("%s: %v", k, v))    }    buf.WriteString(fmt.Sprintf(" Status Code: %d", *(rww.statusCode)))    buf.WriteString("Body")    buf.WriteString(rww.body.String())    return buf.String()}

收到一只叮咚

您需要包装 以捕获响应数据。ResponseWritertype ResponseWriterWrapper struct {  w           http.ResponseWriter  body        bytes.Buffer  statusCode  int}func (i *ResponseWriterWrapper) Write(buf []byte) (int, error) {  i.body.Write(buf)  return i.w.Write(buf)}func (i *ResponseWriterWrapper) WriteHeader(statusCode int) {  i.statusCode = statusCode  i.w.WriteHeader(statusCode)}func (i *ResponseWriterWrapper) String() {  var buf bytes.Buffer  buf.WriteString("Response:")  buf.WriteString("Headers:")  for k, v := range i.w.Header() {    buf.WriteString(fmt.Sprintf("%s: %v", k, v))  }  buf.WriteString(fmt.Sprintf("Status Code: %d", i.statusCode))  buf.WriteString("Body")  buf.WriteString(i.body.String())}将包装器传递到并记录捕获的响应数据。ServeHTTPfunc RequestLoggerMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        start := time.Now()        rww := ResponseWriterWrapper{ w: w }        defer func() {            log.Info(                fmt.Sprintf(                    "[Request: %s] [Execution time: %v] [Response: %s]",                    log.HTTPRequest(r),                    time.Since(start),                    log.Info(rww.String())                ))        }()        next.ServeHTTP(rww, r)    })}
打开App,查看更多内容
随时随地看视频慕课网APP