Remix.run Logo
jjice 2 days ago

> The key decision is thus between two patterns: using a global logger or using dependency injection. The former is extremely convenient but adds a hidden dependency that’s hard to test, while the latter is more verbose but makes dependencies explicit, resulting in highly testable and flexible code.

Curious how different people handle this. I personally pretty much always pass a logger into function, classes, structs (what have you) so it has the context I need it to. It's a tad more verbose I guess, but it's such a minor lift I've always found it worth it.

cfors 2 days ago | parent | next [-]

In any API service, it's better to handle via dependency injection IMO.

Instantiate all of your metadata once, and then send that logger down, so that anybody who uses that logger is guaranteed to have the right metadata... the time to add logging is not when you are debugging.

9rx 2 days ago | parent | prev | next [-]

> more verbose

I'd say necessarily verbose. Without injection, it is not immediately apparent that something is dependent on something else (in this case a logger) with side effects, which ultimately harms understandability.

I expect by "more verbose" the author really meant "in need of more typing". I am not sure optimizing for less typing ever a good tradeoff. And if you can find good reason to optimize for less typing, you're not going to be choosing a structured language in the first place, so...

jjice 2 days ago | parent [-]

Totally agree. I'll suffer with an additional 20 characters of typing. I hadn't even considered the other ways the article goes into, I'd always used a child logger and passed it down, so I'm a bit reassured that I haven't been a _complete_ fool for all these years.

stackedinserter 2 days ago | parent | prev [-]

We pass logs in contexts.