Deprecate implicit materialization of Slf4jFactory#683
Conversation
| @deprecated("LoggerFactories should be passed explicitly, not implicitly", "2.5.0") | ||
| def apply[F[_]: Slf4jFactory]: Slf4jFactory[F] = implicitly | ||
|
|
||
| def create[F[_]: Sync]: Slf4jFactory[F] = new Slf4jFactory[F] { |
There was a problem hiding this comment.
This would have been more convenient as an apply method, but unfortunately that's been squatted :(
There was a problem hiding this comment.
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.
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.
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 🥳 |
LoggerFactorySlf4jFactory
|
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.
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
LoggerFactoryimplementation, they should be passed explicitly, not implicitly.Closes #681.