15

ジンのミドルウェアに応答本文を記録する必要がありますが、応答本文を取得する方法がわかりません。誰でも助けることができますか?

次のようなミドルウェアを使用しています。

func Logger() gin.HandlerFunc {

    return func(c *gin.Context) {

        c.Next()

        statusCode := c.Writer.Status()
        if statusCode >= 400 {
            //ok this is an request with error, let's make a record for it
            //log body here
        }
    }
}

私の質問は、ミドルウェアの Context から応答本文を取得する方法ですか?

4

2 に答える 2

30

応答の書き込みを傍受し、最初にどこかに保存する必要があります。その後、ログに記録できます。そのためには、Write() 呼び出しをインターセプトする独自の Writer を実装する必要があります。

たとえば、次のようになります。

type bodyLogWriter struct {
    gin.ResponseWriter
    body *bytes.Buffer
}

func (w bodyLogWriter) Write(b []byte) (int, error) {
    w.body.Write(b)
    return w.ResponseWriter.Write(b)
}

func ginBodyLogMiddleware(c *gin.Context) {
    blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
    c.Writer = blw
    c.Next()
    statusCode := c.Writer.Status()
    if statusCode >= 400 {
        //ok this is an request with error, let's make a record for it
        // now print body (or log in your preferred way)
        fmt.Println("Response body: " + blw.body.String())
    }
}

次に、このミドルウェアを次のように使用します。

router.Use(ginBodyLogMiddleware)

ジンは c.Writer を使用していないように見えるため、この敷居は静的ファイルでは機能しないことに注意してください。しかし、ほとんどの場合、とにかくそれが必要です。

すべてのファイルをインターセプトする場合は、もう少し複雑な方法を使用する必要があります。ミドルウェアの代わりに、gin.Engine をラップするラッパー http.Handler を実装する必要があり、上記と同じアプローチを使用して、http.ResponseWriter に書き込まれたものをインターセプトしてログに記録します。次に、次のように gin サーバーを実行します。

ginRouter := gin.New()
// configure your middleware and routes as required

// Run http server as follows, where bodyLogHandler is your wrapper handler
http.ListenAndServe(bindAddress, &bodyLogHandler{wrappedHandler: ginRouter}
于 2016-07-24T03:48:31.937 に答える