猿问

访问没有 http.Request 的上下文

我X-Request-Id在context中间件中进行设置(如下所示),以便我可以在有*http.Request结构的地方使用它 - 例如req.Context().Value(middleware.ReqIdKey)。但是,我的代码库中的某些地方无法访问*http.Requeststruct,因此我无法使用contextfetch X-Request-Id。Go 有办法还是我试图做一些根本错误的事情?


内部/中间件/requestid.go


X-Request-Id这是我设置in的中间件context。http.ListenAndServe(":8080", middleware.RequestId(SomeHandler))目前在我的“服务器”包中称为。


package middleware


import (

    "context"

    "github.com/google/uuid"

    "net/http"

)


type val string

const ReqIdKey val = "X-Request-Id"


func RequestId(handler http.Handler) http.Handler {

    return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {

        val := req.Header.Get("X-Request-Id")

        if val == "" {

            val = uuid.New().String()

        }


        ctx1 := context.WithValue(req.Context(), ReqIdKey, val)

        ctx2 := req.WithContext(ctx1)


        handler.ServeHTTP(res, ctx2)

    })

}

内部/logger/logger.go


这是我需要访问context或只是X-Request-Id值的另一个包。顺便说一句,调用logger.Config是在启动服务器之前进行的。


package logger


import (

    "github.com/sirupsen/logrus"

    "os"

)


var Log *logrus.Entry


func Config() {

    logrus.SetLevel(logrus.InfoLevel)

    logrus.SetOutput(os.Stdout)

    logrus.SetFormatter(&logrus.JSONFormatter{})


    Log = logrus.WithFields(logrus.Fields{

        "request_id": ..., // I need X-Request-Id value to go here so that all logs have it

    })

}


GCT1015
浏览 110回答 2
2回答

慕少森

如果您有 http.Request,您可以访问其中的上下文和值。如果您没有请求但需要上下文:获取上下文并将其作为显式参数传递到您的调用树(按照惯例,它是第一个参数)。(Go 中没有魔法,任何没有直接或间接传递到函数中的东西都不存在。)

慕侠2389804

首先,您应该将上下文传递到需要的地方。如果您的Config()函数中需要它,请将其传递到那里:func Config(ctx context.Context) {  /* ... * /}但是您可能会Config()在启动时调用一次,而不是根据请求调用一次,这导致了我的第二点:您不应该将上下文或一般请求范围的数据传递给配置函数。这完全是本末倒置。相反,您应该将记录器传递到处理程序/中间件中,并让它记录请求数据:func handleSomePath(logger *logrus.Entry) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        /* do something */        logger.WithFields(logrus.Fields{            "request_id": /* ... */        })    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答