我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 關注
- 148 瀏覽
添加回答
舉報
0/150
提交
取消