Golang Logging with Mapped Diagnostic Context
Asked Answered
D

1

7

How can I achieve MDC Logging (Java) in GoLang?

I need to add UUIDs in all server logs in order to be able to trace concurrent requests.

Darbie answered 8/12, 2016 at 21:3 Comment(1)
This helps: joeshaw.org/revisiting-context-and-http-handler-for-go-17Darbie
N
12

Java MDC relies on thread local storage, something Go does not have.

The closest thing is to thread a Context through your stack.

This is what more and more libraries are doing in Go.

A somewhat typical way is to do this via a middleware package that adds a request id to the context of a web request, like:

req = req.WithContext(context.WithValue(req.Context(),"requestId",ID))

Then, assuming you pass the context around, you pull it out with ctx.Value("requestId") and use it wherever it makes sense.

Possibly making your own custom logger function like:

func logStuff(ctx context.Context, msg string) {
    log.Println(ctx.Value("requestId"),msg) // call stdlib logger
}

There's a bunch of ways you may want to handle this, but that's a fairly simple form.

Nucleon answered 8/12, 2016 at 21:47 Comment(3)
Go never ceases to amaze in the stupid design decisions that have all be solved in many other langauges and ecosystemsInca
Sure, there are some places where one might say, hmm, weird. I don't think this is one of them. Threadlocals are a great source of bugs in languages that have them. Folks use the as a crutch for poor application design and, especially in a RPC type system, often forget to clean values out, mixing data from one request to the next.Nucleon
Don't use a string as the key. Use instead a value of a private type to avoid any conflict. type requestIdKey struct{} req = req.WithContext(context.WithValue(req.Context(),requestIdKey{},ID))Rondo

© 2022 - 2024 — McMap. All rights reserved.