我在中间件的 context
中设置 X-Request-Id
(如下所示),这样我就可以在那里使用它是 *http.Request
结构 - 例如req.Context().Value(middleware.ReqIdKey)
。但是,在我的代码库中有些地方我无法访问 *http.Request
结构,因此我无法使用 context
来获取 X-Request-Id
。在 Go 中有什么方法还是我试图做一些根本错误的事情?
internal/middleware/requestid.go
这是我在 context
中设置 X-Request-Id
的中间件。目前在我的“服务器”包中称为 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)
})
}
internal/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
})
}
最佳答案
如果您有一个 http.Request,您可以访问其中的 Context 和 Values。如果您没有请求但需要上下文:获取上下文并将其作为显式参数(按照惯例是第一个参数)传递到您的调用树中。
(Go 中没有魔法,任何没有直接或间接传递给函数的东西都不存在。)
关于go - 访问没有 http.Request 的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58011031/