亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

日志 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條經驗 獲得超5個贊

您需要包裝 以捕獲響應數據。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 關注
  • 95 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號