如何使用 Gin 上下文创建的请求 ID 记录 HTTP 客户端的请求

想法:我想用唯一的请求ID记录传入和传出的请求到我的Gin服务器。另外,我想使用与路由相同的请求ID在我的Gin路由内记录所有HTTP客户端的请求。


所有这些都应该使用中间件在引擎盖下工作。


记录对我的服务器的请求(和响应)

为了记录对服务器的每个请求,我编写了以下中间件:


import (

    "bytes"

    "context"

    "github.com/gin-contrib/requestid"

    "github.com/gin-gonic/gin"

    "github.com/rs/zerolog/log"

    "io/ioutil"

    "net/http"

    "time"

)


type responseBodyWriter struct {

    gin.ResponseWriter

    body *bytes.Buffer

}


func (r responseBodyWriter) Write(b []byte) (int, error) {

    r.body.Write(b)

    return r.ResponseWriter.Write(b)

}


func LoggerMiddleware() gin.HandlerFunc {

    return func(c *gin.Context) {


        start := time.Now()


        w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}

        c.Writer = w


        msg := "Input:"

        path := c.Request.URL.Path

        raw := c.Request.URL.RawQuery

        if raw != "" {

            path = path + "?" + raw

        }


        // Read from body and write here again.

        var bodyBytes []byte

        if c.Request.Body != nil {

            bodyBytes, _ = ioutil.ReadAll(c.Request.Body)

        }

        c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))


        inputLogger := log.With().

            Str("method", c.Request.Method).

            Str("path", path).

            Str("requestId", requestid.Get(c)).

            Logger()


        if len(bodyBytes) > 0 {

            inputLogger.Info().RawJSON("body", bodyBytes).Msg(msg)

        } else {

            inputLogger.Info().Msg(msg)

        }


侃侃无极
浏览 445回答 2
2回答

守着星空守着你

该函数采用一个参数,因此您应该能够通过在处理程序中创建一个请求来传递Gin上下文:Transport.RoundTrip*http.Requestfunc MyHandler(c *gin.Context) {        // passing context to the request        req := http.NewRequestWithContext(c, "GET", "http://localhost:8080", nil)        resp, err := http.DefaultClient.Do(req)}请注意,为了能够在不进行其他初始化的情况下使用您覆盖的默认值,应使用 .RoundTripperhttp.DefaultClient

胡子哥哥

您可以使用以下命令:https://github.com/sumit-tembe/gin-requestidpackage mainimport (    "net/http"    "github.com/gin-gonic/gin"    requestid "github.com/sumit-tembe/gin-requestid")func main() {    // without any middlewares    router := gin.New()    // Middlewares    {        //recovery middleware        router.Use(gin.Recovery())        //middleware which injects a 'RequestID' into the context and header of each request.        router.Use(requestid.RequestID(nil))        //middleware which enhance Gin request logger to include 'RequestID'        router.Use(gin.LoggerWithConfig(requestid.GetLoggerConfig(nil, nil, nil)))    }    router.GET("/", func(c *gin.Context) {        c.String(http.StatusOK, "Hello world!")    })    router.Run(":8080")}输出:[GIN-debug] 2019-12-16T18:50:49+05:30 [bzQg6wTpL4cdZ9bM] - "GET /"[GIN-debug] 2019-12-16T18:50:49+05:30 [bzQg6wTpL4cdZ9bM] - [::1] "GET / HTTP/1.1 200 22.415µs" Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36它还支持自定义请求ID生成器,您可以根据需要进行设计。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go