Open garretwilson opened 9 months ago
The only remaining question would be whether to include
SimpleServiceProvider
inslf4j-simple-impl
but not expose it as a service; or leave it inslf4j-simple
, requiring consumers to create their own provider wrapper class.
Here I think it might be best to leave SimpleServiceProvider
in slf4j-simple
to prevent confusion. This means that anyone using slf4j-simple-impl
would need to write their own service provider class, but they would probably be doing that anyway, and it's just a simple wrapper. The win is that they don't have to re-implement the actual logging code.
It would be extremely useful to bundle the
slf4j-simple
logging implementation as a separate artifact (e.g.slf4j-simple-impl
) so that it can be used without exposing it as an automatically detected service provider. (P.S. I didn't realize how cool the nameslf4j-simple-impl
is until I just wrote that.) This would involve simply splitting out the implementation code (and perhaps the actualSimpleServiceProvider
class as well, without exposing it as a service) into a separate subproject—little if any actual code changes would be needed.You can see how I've done something similar with Clogr's https://github.com/globalmentor/clogr/tree/main/clogr-logback and https://github.com/globalmentor/clogr/tree/main/clogr-logback-provider .
This would bring a couple of big wins, notably solving
SLF4J-592
: Mechanism for indicating provider to use for unit tests. Let me lay out the use cases:Basis for Specialized Implementations
Splitting out the
slf4j-simple
implementation would allow others to create specialized versions. Without the separate artifact, a specialized version has to duplicate theslf4j-simple
code, because otherwise simply referring to that dependency would expose a provider that would be detected by SLF4J, resulting in "dueling providers".This is not a theoretical need. Read Solving the Java Aws Lambda logging problem, in which Frank Afriat (@fafriat) investigates how to create a logging implementation that is simple but plays well with AWS Lambda. In theory you would just write to
stdout
/stderr
, but there are a couple of gotchas Frank had to work around. He had to forkslf4j-simple
and make a customized version. I believe (although I haven't asked him) that hadslf4j-simple-impl
existed, he could have simply used that dependency, added a few tweaks, and then exposed his own provider rather than copying all the code as he has done.Including/Selecting an Optional Logging Provider
If
slf4j-simple-impl
existed, I could include the dependency but not exposeSimpleServiceProvider
via the Java service provider mechanism, so that it wouldn't be detected by SLF4J automatically, requiring me to manually "enable it".In
SLF4J-592
: Mechanism for indicating provider to use for unit tests (see also my Maven exclude/remove test dependency defined in parent POM and someone else's Is there any simple pattern of slf4j usage in unit tests?) I pondered how I want logging to work in unit tests. After months of thinking, I finally know:stderr
during the build, just by setting some flag.I both cases, I don't want to affect the logging provider used by the artifacts actually being built.
With
slf4j-simple-impl
(assuming you putSimpleServiceProvider
insideslf4j-simple-impl
as well, but don't expose it as a Java service provider), I could simply includeslf4j-simple-impl
intest
scope in my parent POM. All my tests would automatically get theslf4j-simple-impl
logging implementation, but it wouldn't be used—it would lurking, ready to be enabled.In my build I would set
slf4j.provider
to….NOP_FallbackServiceProvider
during unit/integration tests. This would address 1) above—all logging in unit tests would be suppressed. This would not conflict with or affect in any way the logging providers of the actual artifacts build for the various libraries and applications.In my build I would add a Maven
debug
profile that I could invoke with-P debug
. This would overrideslf4j.provider
with….SimpleServiceProvider
for the unit/integration tests. Suddenly all my unit tests would start logging tostdout
/stderr
(whichever I have configured), helping me to track down problems in the build. This addresses 2) above.I believe this would be a complete, comprehensive solution to the build unit/integration test logging question. And pulling it off would be so simple. (The only remaining question would be whether to include
SimpleServiceProvider
inslf4j-simple-impl
but not expose it as a service; or leave it inslf4j-simple
, requiring consumers to create their own provider wrapper class.)Note that if you decide not to split out
slf4j-simple-impl
, I can easily write my own simple logging implementation—it would just be a shame to reinvent the wheel.If you think this is a great idea, just let me know and I could probably file a pull request for it.