Or, what if...
type FunnelContext interface { context.Context logger.Logger } type RequestHandler struct { // No context specific fields here, instance stays reusable across requests } func (RequestHandler) Handle(ctx FunnelContext) {} On Thursday, August 24, 2017 at 8:58:15 PM UTC-7, Dave Cheney wrote: > > > Should we stop using a global logger? > > Yes[1] > > 1. https://dave.cheney.net/2017/01/26/context-is-for-cancelation > > On Friday, 25 August 2017 13:38:48 UTC+10, buchan...@gmail.com wrote: >> >> In Funnel [1], we've been using a global logger, based on logrus [2]. >> This has worked fine through the early stages of the project, but it's >> starting to show a few cracks. In particular, we need to ensure that a >> request (task) ID is present in all log messages. Solutions to this have >> grown to be inconsistent: >> >> - We create a child logger instance which has the ID preconfigured, and >> pass that to some function calls. [3] >> - We're looking at passing a context to logging calls, and the logger >> pulls the ID from context.Value. [4] >> - Some calls have been left behind and are still using the global logger. >> >> Other notes: >> - A global logger configured to a single task ID won't work, since >> multiple requests may be handled concurrently. >> - Request handling spans multiple packages. >> - We're using context extensively, we're ok with using it more. >> >> We're trying to decide whether to stick to a global (singleton) logger, >> or remove the global logger completely and start passing logger instances >> everywhere. I think we can make either work, and so far neither is an >> obvious choice. What do you think? >> >> Global logger: >> - seems to be the most common approach >> - convenient access >> - global singleton might lead to difficulty and inflexibility, e.g. >> capturing logging in tests, multiple configurations >> >> Logger instances: >> - more fields on every type and function that wants to log >> - full control over logging in each individual type and function >> - clearly stated dependencies for each type/function. I'd say Go idioms >> tend toward obvious, clear, and powerful over clean, concise, magic. >> >> A third, interesting option might be to add all logging configuration to >> the context using context.Value, including output, formatting, etc. Global >> logging functions would pull all needed config from the context. I'm >> worried this gets into the hotly debated territory of abusing >> context.Value. On the other hand, we're already passing context everywhere, >> and this is useful context that crosses API boundaries. >> >> Anywho, would love to get thoughts from the experts out there. Thanks for >> reading! >> >> Alex >> >> >> [1] https://github.com/ohsu-comp-bio/funnel >> [2] https://github.com/sirupsen/logrus >> [3] >> https://github.com/ohsu-comp-bio/funnel/blob/master/worker/runner.go#L25 >> [4] https://github.com/ohsu-comp-bio/funnel/pull/194 >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.