応答本文をginのミドルウェアに記録する必要がありますが、応答本文を取得する方法がわかりません。誰か助けてもらえますか?
私はこのようなミドルウェアを使用しています:
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
}
}
}
私の質問は、ミドルウェアのコンテキストから応答本文を取得する方法ですか?
応答の書き込みを傍受し、最初にどこかに保存する必要があります。その後、ログに記録できます。そのためには、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)
Ginは静的ファイルにc.Writerを使用していないようであるため、このシルは静的ファイルでは機能しないことに注意してください。しかし、ほとんどの場合、それはあなたがとにかく欲しいものです。
すべてのファイルをインターセプトする場合は、もう少し複雑な方法を使用する必要があります。ミドルウェアの代わりに、gin.Engineをラップし、上記と同じアプローチを使用してhttp.ResponseWriterに書き込まれたものをインターセプトしてログに記録するラッパーhttp.Handlerを実装する必要があります。次に、次のように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}
ご参考までに
注:レスポンス本文の記述にWriteString()
を使用する場合は、c.String()
を実装します
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 (w bodyLogWriter) WriteString(s string) (int, error) {
w.body.WriteString(s)
return w.ResponseWriter.WriteString(s)
}
func ginBodyLogMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
c.Writer = blw
c.Next()
fmt.Println("Response body: " + blw.body.String())
}
}
...
// register
router := r.Group("/", ginBodyLogMiddleware())