Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement proposal: "LoggerForType", use phantom types to disambiguate loggers #439

Open
gbogard opened this issue Apr 29, 2021 · 2 comments

Comments

@gbogard
Copy link

gbogard commented Apr 29, 2021

Hello :)

As someone else pointed out in this issue #397, the class that shows up in traces reflects where the logger was instantiated, usually the main class of the application. In many applications, it is however desirable to have several loggers, each with a name reflecting a particular portion of code. This makes it easier to spot where an issue comes from, and allows logging backends to be configured on a per-class basis.

However, creating multiple loggers and passing them around can be a rather frustrating experience. Having multiple loggers means you have to give up using implicits to pass them around. I came up with a solution to address this issue, and believe this could be a nice improvement for this library.

The idea is to use a phantom type to bind a logger instance to a single class, and optionally use a ClassTag to conveniently instantiate named loggers. There are code examples in the repository :)

final case class LoggerForType[F[_], T](logger: Logger[T]) extends Logger[F]

I haven't yet published the work as a library, and I am willing to open a PR to include it directly in log4cats, if the maintainers find it desirable :)

Cheers, and thank you for your work

@nigredo-tori
Copy link
Contributor

nigredo-tori commented Apr 30, 2021

There's an alternative implementation of this idea using type tags, which doesn't require any changes to this library:

implicit val fooLogger: SelfAwareStructuredLogger[IO] @@ Foo =
  SLF4JLogger.getLogger[IO].taggedWith[Foo]
implicit val barLogger: SelfAwareStructuredLogger[IO] @@ Bar =
  SLF4JLogger.getLogger[IO].taggedWith[Bar]

This way we don't lose the actual subtype of the logger (SelfAwareStructuredLogger). The drawback is that a function asking for
SelfAwareStructuredLogger[F] would happily accept any of these. Though I don't know how often this would come up.

Also, #421 solves the same issue with a different set of tradeoffs.

@gbogard
Copy link
Author

gbogard commented May 3, 2021

@nigredo-tori thank you for your answer!
The type tags solution seems nice, I think me team is going to use that for now, it's probably nicer not to use a more generic tool.
Maybe this approach could be documented in the README of this library ? This feels like a fairly common use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants