-
Notifications
You must be signed in to change notification settings - Fork 74
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
Deprecate implicit materialization of Slf4jFactory
#683
Deprecate implicit materialization of Slf4jFactory
#683
Conversation
def apply[F[_]: Slf4jFactory]: Slf4jFactory[F] = implicitly | ||
|
||
def create[F[_]: Sync]: Slf4jFactory[F] = new Slf4jFactory[F] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would have been more convenient as an apply
method, but unfortunately that's been squatted :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's good this way! cats.effect.std.Console
is also instatiated using make
instead of apply
. Maybe we should rename this to make
rather than create
:D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agree now that we decided we are not totally deprecating implicit
(otherwise, the apply
was dead deprecated weight).
Regarding naming: I chose create
based on this.
def create[F[_]: Sync](implicit name: LoggerName): F[SelfAwareStructuredLogger[F]] = |
But I think make
is good too 🤔 and maybe better to keep it independent of create
.
To me It's just that I would highly encourage explicit instantiation of these by the user, and then allow them to chose if they wish to pass implicitely or explicitely in their own app :). I think the status quo is that I'd also prefer to see this paired with some docs that showcase the explicit use of // the assorted imports, also code does not compile
object Main extends IOApp.Simple {
override def run: IO[Unit] = for {
implicit0(lf: LoggerFactory[IO]) = Slf4jFactory.create[IO]
// other capabilities like cats.effect.std.{Console, Random}, etc here.
app <- instantiateApp[IO]
} yield ()
type MyApp = Nothing
def instantiateApp[F[_]: LoggerFactory]: F[MyApp] =
for {
// many others in F
someClass = new SomeClass[F]()
// many others in F
} yield ???
}
class SomeClass[F[_]](implicit loggers: LoggerFactory[F]){
private val logger = loggers.getLogger //explicit call the LoggerFactory passed along by the user, even if implicit
} LE: paired with updating this section of the docs which does rely on these implicits. |
Maybe we should make some kind of integrative typelevel doc that showcases a pattern of instantiating capabilities available in the ecosystem and link that as an example? 😅 Since it would serve well to be consistent across everything under |
I definitely agree those examples can be passed around implicitly :) that's because they have canonical implementations. Meaning that there is essentially only one true implementation.
This is not the case for The fact that there are legitimate fears in #681 (review) that the wrong/unexpected implementation could be passed implicitly reinforces that this should be explicit. I definitely agree the docs can/should be improved (indeed CI is failing about that). But first let's make sure we're all on the same page with this change :) |
Ah, your comment in #681 (comment) clarifies things for me.
That seems reasonable to me: we'd deprecate just this method and nothing more.
Happy to hear other's thoughts :) |
Yes, but the fear is accidentally getting a new
Well, there are good implementations of the capabilities. And I definitely would not be the one to try to implement a |
Then we are in agreement 🥳 |
LoggerFactory
Slf4jFactory
To repeat my comment in #681 (comment) - Why not provide this as a convenience but in an implicits namespace, like we do with (for example) the cats-effect global runtime? That way it's not just "floating around out there" but it's available in a convenient form when needed. |
override def fromSlf4j(logger: JLogger): F[SelfAwareStructuredLogger[F]] = | ||
Slf4jLogger.fromSlf4j(logger) | ||
} | ||
@deprecated("Use Slf4jFactory.create[F] explicitly", "2.5.0") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Version needs to be bumped to 2.6.0 now 😅
slf4j/src/main/scala/org/typelevel/log4cats/slf4j/package.scala
Outdated
Show resolved
Hide resolved
@danicheg what do you think about this approach? I'm fine going forward with this even without convenience |
I think that |
Merging and we'll defer the discussion about implicit LoggerFactory when the ecosystem reaches more of a consensus about implicit capabilities in general 😅 |
See #681 (comment). Since there is not one canonical
LoggerFactory
implementation, they should be passed explicitly, not implicitly.Closes #681.