skip to Main Content

I read all the decisions about dropping the ThreadLocal and I can relate.
Seems like passing around the request.Context() that is of type context.Context gives the ability to manage scoped services.

I am using logrus for logging and want to log a requestId that is a generate udid from a midlleware in gin

I know i can do something like this

func Authentication(conf Configuration, logger ILogger, cache ICacheService) gin.HandlerFunc {
    return func(c *gin.Context) {

        logger := logrus.WithContext(c)
        c.Set("traceId", uuid.New().String())
        c.Next()
    }
}

And the pass around the entry or even store the entry inside the context whatever works, but…
I also have a Redis and MongoDb clients that are singletons and I am wrapping them with my own package to facilitate logging of any outgoing IO requests.

because they are singletones I cannot pas the context.Context to the constructor but ill have to pass it to every method like GetKey SetKet etc..

any common patterns for using the context request id logging inside a Singleton service ?

2

Answers


  1. The idiomatic way is to pass context.Context to every method. In fact, contexts are not supposed to be passed in constructors or stored as struct members. As mentioned in the documentation:

    Do not store Contexts inside a struct type; instead, pass a Context explicitly to each function that needs it.

    Login or Signup to reply.
  2. I am wrapping them with my own package to facilitate logging of any
    outgoing IO requests.

    Libraries with good API design provide customization of transport functionality or possibly provide the ability to add hooks for such purposes with closure context making you possible to decorate them with logging. Redis should support custom dialers and you can inject your logging activity directly with closure function that get access both to context and to your logger, so no need to make wrapping if it was the only reason.

    A cleaner software design is to instantiate logger once and pass it down to your dependencies. Context.Values are request scoped-values, not scoped services. Using dynamic context api for such purposes make your software very hard to predict, it will be better to utilize conveniences of strongly-typed API with Dependency Injection instead.

    Hope it helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search