応答の書き込みを傍受し、最初にどこかに保存する必要があります。その後、ログに記録できます。そのためには、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}