在一个结构化日志行中跟踪 Go 中的 HTTP 请求

Tracing an HTTP request in Go in a one structured log line

我了解到您可以“修饰”HTTP 传输,以便您可以了解请求的详细信息,但是我不太明白您如何在同一行中记录 URL。

https://play.golang.org/p/g-ypQN9ceGa

结果

  INFO[0000] Client request            dns_start_ms=0 first_byte_ms=590 response_code=200 total_ms=590 url=
  INFO[0000] 200

我一直很困惑我是否应该使用 https://golang.org/pkg/context/#WithValue to pass around the context in a struct, especially in light where https://blog.golang.org/context-and-structs 将 context.Context 作为参数作为结尾 .

查看 request.go from net/http. You see that the RequestURI field is never set there. Quoting from same reference

中请求的构造方式

Usually the URL field should be used instead.
It is an error to set this field in an HTTP client request

所以,我建议您改用 request.URL
它是从请求 uri 中解析出来的。它应该有你需要的数据。

您可以按如下方式构建输出:

f := log.Fields{
    "url": fmt.Sprintf("%s %s%s", r.Method, r.URL.Host, r.URL.Path),
}

此外,根据我的经验,使用 context.WithValue 并将上下文作为参数传递要容易得多。

将代码中的 r.RequestURI 替换为 r.URL.String() 以记录完整、有效的 URL (https://golang.org/pkg/net/url/#URL.String). RequestURI is empty on the client side (https://golang.org/pkg/net/http/#Request),如代码输出所示。

我不明白 context.Context 与您的问题有什么关系,但我相信 https://blog.golang.org/context-and-structs 被认为是“最佳实践”。