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

Viewed 482

I have learned you can "decorate" the HTTP transport so that you can details of the request, however I can't quite figure out how you log the URL in the same line.

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

results in

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

I'm perpetually confused if I should be using 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 concludes with pass context.Context in as an argument.

2 Answers

Go through the behaviour of how the request is constructed in 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

So, I would suggest you to use request.URL instead.
It is a parsed from the request uri. It should have the data you need.

You can construct the output as following:

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

Also, in my experience, it is far more easier to use context.WithValue and pass the context as an argument.

Related