How to register response body in gin

I need to write the response body to the gin middleware, but I cannot find how to get the response body. Can anyone help?

I use this middleware:

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 make a record for it
            //log body here
        }
    }
}

My question is: how do I get the response body from context in middleware?

+10
source share
2 answers

You need to intercept the response record and first save it somewhere. Then you can register it. And for this you need to implement your own Writer that intercepts Write () calls.

For example, as follows:

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 make a record for it
        // now print body (or log in your preferred way)
        fmt.Println("Response body: " + blw.body.String())
    }
}

Then use this middleware as follows:

router.Use(ginBodyLogMiddleware)

, , , , c.Writer . , .

, . http.Handler, gin.Engine , , , 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}
+15

FYI

: 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())
0

Source: https://habr.com/ru/post/1648632/


All Articles