我X-Request-Id在context中间件中进行设置(如下所示),以便我可以在有*http.Request结构的地方使用它 - 例如req.Context().Value(middleware.ReqIdKey)。但是,我的代码库中的某些地方无法访问*http.Requeststruct,因此我无法使用contextfetch X-Request-Id。Go 有办法还是我试图做一些根本错误的事情?内部/中间件/requestid.goX-Request-Id这是我设置in的中间件context。http.ListenAndServe(":8080", middleware.RequestId(SomeHandler))目前在我的“服务器”包中称为。package middlewareimport ( "context" "github.com/google/uuid" "net/http")type val stringconst 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 loggerimport ( "github.com/sirupsen/logrus" "os")var Log *logrus.Entryfunc 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 })}
2 回答
慕少森
TA贡献2019条经验 获得超9个赞
如果您有 http.Request,您可以访问其中的上下文和值。如果您没有请求但需要上下文:获取上下文并将其作为显式参数传递到您的调用树(按照惯例,它是第一个参数)。
(Go 中没有魔法,任何没有直接或间接传递到函数中的东西都不存在。)
慕侠2389804
TA贡献1719条经验 获得超6个赞
首先,您应该将上下文传递到需要的地方。如果您的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": /* ... */
})
}
}
- 2 回答
- 0 关注
- 109 浏览
添加回答
举报
0/150
提交
取消