2 回答

TA貢獻1789條經(jīng)驗 獲得超8個贊
默認情況下,gorilla/handlers庫不提供執(zhí)行此操作的方法:那里的日志記錄功能以 Apache 格式登錄,而 Apache 格式不提供此功能。
也請記住,“線程ID”沒有意義在這里-你想有一個請求,即與相關(guān)的ID *http.Request。
您可以編寫自己的 RequestID 中間件,該中間件創(chuàng)建一個 ID 并將其存儲在請求上下文中,以便其他中間件/處理程序根據(jù)需要檢索:
package main
import (
"crypto/rand"
"encoding/base64"
"net/http"
"github.com/gorilla/context"
)
const ReqID string = "gorilla.RequestID"
// RequestID wraps handlers and makes a unique (32-byte) request ID available in
// the request context.
// Example:
// http.Handle("/", RequestID(LoggingHandler(YourHandler)))
//
// func LoggingHandler(h http.Handler) http.Handler {
// fn := func(w http.ResponseWriter, r *http.Request) {
// h.ServeHTTP(w, r)
//
// id := GetRequestID(r)
// log.Printf("%s | %s", id, r.RemoteAddr)
// }
//
// return http.HandlerFunc(fn)
// }
func RequestID(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
b := make([]byte, 8)
_, err = rand.Read(&b)
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
base64ID := base64.URLEncoding.EncodeToString(b)
context.Set(r, ReqID, base64ID)
h.ServeHTTP(w, r)
// Clear the context at the end of the request lifetime
context.Clear(r)
}
return http.HandlerFunc(fn)
}
func GetRequestID(r *http.Request) string {
if v, ok := context.GetOK(r, ReqID); ok {
if id, ok := v.(string); ok {
return id
}
}
return ""
}
請記住,上面的代碼沒有經(jīng)過測試。在操場上寫下了我的頭頂,所以如果有錯誤,請告訴我。
除了這個基本示例之外,您還可以考慮改進:
用主機名前綴 ID - 如果您從多個進程/機器聚合日志很有幫助)
提供時間戳或遞增整數(shù)作為最終 ID 的一部分,以幫助跟蹤一段時間內(nèi)的請求
對其進行基準測試。
請注意,在極高的負載下(例如,數(shù)以萬計的請求/秒 - 每天數(shù)以百萬計的點擊),這可能不是高性能的,但不太可能成為 > 99% 用戶的瓶頸。
PS:我可能會考慮在某個時候handlers.RequestID
在 gorilla/handlers 庫中提供一個實現(xiàn)——如果你想看到它,在 repo 上提出一個問題,我會看看我是否能找到時間來實現(xiàn)一個更完整的實現(xiàn)在上面。

TA貢獻1895條經(jīng)驗 獲得超3個贊
基于https://groups.google.com/forum/#!searchin/golang-nuts/Logging $20http$20thread/golang-nuts/vDNEH3_vMXQ/uyqGEwdchzgJ,ThreadLocal
Go 無法實現(xiàn)概念。
每個需要記錄的地方,都需要傳入 httpRequest
實例,以便可以檢索與請求關(guān)聯(lián)的上下文,并且可以從該上下文中獲取請求的唯一 ID。但是將 Request 實例傳遞給所有層/方法是不切實際的。
- 2 回答
- 0 關(guān)注
- 250 瀏覽
添加回答
舉報