在Golang中,我们可以使用标准库"log"或者第三方库(如logrus、zap等)来实现日志记录。为了追踪请求,我们可以在处理请求的函数中记录关键信息,例如请求ID、时间戳、客户端IP等。下面是一个简单的示例,展示了如何使用标准库"log"来追踪请求。
首先,我们需要创建一个中间件来处理请求并记录相关信息:
package main
import (
"log"
"net/http"
"time"
)
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// 记录请求信息
log.Printf("Request: %s %s %s", r.RemoteAddr, r.Method, r.URL.Path)
// 调用下一个处理器
next.ServeHTTP(w, r)
duration := time.Since(start)
log.Printf("Response: %s %s %s %v", r.RemoteAddr, r.Method, r.URL.Path, duration)
})
}
func mainHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
}
func main() {
http.Handle("/", loggingMiddleware(http.HandlerFunc(mainHandler)))
log.Fatal(http.ListenAndServe(":8080", nil))
}
在这个示例中,我们创建了一个名为loggingMiddleware的中间件,它接收一个http.Handler作为参数,并返回一个新的http.Handler。在中间件中,我们记录了请求的远程地址、方法和URL路径,然后调用下一个处理器。在处理器执行完成后,我们再次记录日志,包括响应的持续时间。
要追踪特定请求,你可以在日志中添加一个唯一的请求ID。这可以通过在中间件中生成一个UUID并将其存储在请求上下文中来实现。这是一个修改后的示例:
package main
import (
"context"
"log"
"net/http"
"time"
"github.com/google/uuid"
)
const requestIDKey = "requestID"
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestID := uuid.New().String()
ctx := context.WithValue(r.Context(), requestIDKey, requestID)
start := time.Now()
// 记录请求信息
log.Printf("Request ID: %s %s %s", requestID, r.RemoteAddr, r.Method, r.URL.Path)
// 调用下一个处理器
next.ServeHTTP(w, r.WithContext(ctx))
duration := time.Since(start)
log.Printf("Request ID: %s %s %s %v", requestID, r.RemoteAddr, r.URL.Path, duration)
})
}
func mainHandler(w http.ResponseWriter, r *http.Request) {
requestID := r.Context().Value(requestIDKey).(string)
w.Write([]byte("Hello, World! Request ID: " + requestID))
}
func main() {
http.Handle("/", loggingMiddleware(http.HandlerFunc(mainHandler)))
log.Fatal(http.ListenAndServe(":8080", nil))
}
在这个修改后的示例中,我们使用github.com/google/uuid库生成了一个唯一的请求ID,并将其存储在请求上下文中。然后,在日志记录中添加了这个请求ID,以便于追踪特定请求。