为了账号安全,请及时绑定邮箱和手机立即绑定

日志 http.响应器内容

日志 http.响应器内容

Go
慕的地6264312 2022-08-15 15:50:38
前提:我发现了类似的问题,但在我的案例中不起作用,所以请不要将其标记为重复。我在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)    })}
查看完整描述

2 回答

?
达令说

TA贡献1821条经验 获得超6个赞

谢谢,@Sivachandran的回应。它几乎是完美的,只是由于指针而没有实现。http.ResponseWriter


为了完整起见,我在这里发布了正确的解决方案代码,因为即使这个问题被给予了负分,也很难找到任何关于它的文档。


Stackoverflow是一个交换问题的好地方,在我看来,这是一个非常好和困难的问题,无论是对于一个中间杠杆Golang程序员来说,所以它根本不配得负分!


这就是解决方案,享受:


// RequestLoggerMiddleware is the middleware layer to log all the HTTP requests

func 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 response

type ResponseWriterWrapper struct {

    w          *http.ResponseWriter

    body       *bytes.Buffer

    statusCode *int

}


// NewResponseWriterWrapper static function creates a wrapper for the http.ResponseWriter

func 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() function

func (rww ResponseWriterWrapper) Header() http.Header {

    return (*rww.w).Header()


}


// WriteHeader function overwrites the http.ResponseWriter WriteHeader() function

func (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()

}


查看完整回答
反对 回复 2022-08-15
?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

您需要包装 以捕获响应数据。ResponseWriter


type 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())

}

将包装器传递到并记录捕获的响应数据。ServeHTTP


func 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)

    })

}


查看完整回答
反对 回复 2022-08-15
  • 2 回答
  • 0 关注
  • 56 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信