Visitor tracking use case

Skip to first unread message

Kai Hendry

Jan 1, 2019, 4:54:07 AM1/1/19
to Gorilla web toolkit
Hi there,

I am looking for some simple middleware to set a random identifier like "foobar" in a cookie, e.g.

Set-Cookie: mysite=foobar; expires=Wed, 02-Jan-2019 09:37:33 GMT; Max-Age=86400

And then when I use my structured logs, I can see something like:

Jan 1st 05:35:36pm INFO production request: visitor=foobar ip= method=GET path=/
Jan 1st 05:35:38pm INFO production request: visitor=foobar ip= method=GET path=/about

So I can effectively see a list of paths where the user navigated in their session. Furthermore for debugging purposes, I was hoping to print that random identifier somewhere, so if I user complained to me & choose to identify themselves, I can basically see what they were doing, by filtering my json logs for their visitor identifier.

I'm not sure if is the right tool for the job. I don't see why I need to store anything.. can't I just rely on reading the user's initially set cookie every time from the handler right? Assuming their user agent accepted the initial cookie on first visit et al.

Be great to get any pointers, and do please let me know if this is a dumb idea.

Kind regards,

Matt S

Jan 1, 2019, 12:03:42 PM1/1/19
Hi Kai,

A simple logging handler that makes a request ID available in the request.Context would suffice. Extending an example from my own app -

type requestIDKey struct{}

// RequestID generates a random ID for each HTTP request
func RequestID(next http.Handler) http.Handler {
 fn := func(w http.ResponseWriter, r *http.Request) {
  id, err := generateRandomString(24)
  if err != nil {
  // Handle error
  ctx := Request.Context()
  ctx.WithValue(ctx, requestIDKey{}, id)
next.ServeHTTP(w, r)  

return http.HandlerFunc(fn)

// LogRequest logs each HTTP request, using the given logger.
func LogRequest(logger log.Logger) func(http.Handler) http.Handler {
fn := func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
start := time.Now()
next.ServeHTTP(w, r)
 "id": r.Context().Value(requestIDKey{}).(string)
"method", r.Method,
"host", r.Host,
"url", r.URL.String(),
"ip", r.RemoteAddr,
"forwarded-ip", r.Header.Get("X-Forwarded-For"),
"duration", time.Since(start),

return fn

Hope that's clear. If not, open an issue on the mux repository, as it's easier to provide code samples + more discoverable for future readers: 

You received this message because you are subscribed to the Google Groups "Gorilla web toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
For more options, visit

Kai Hendry

Jan 2, 2019, 5:13:38 AM1/2/19
to Gorilla web toolkit
Thank you Matt, I've created an issue here:
Reply all
Reply to author
0 new messages