You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 name slf4j-simple-impl is until I just wrote that.) This would involve simply splitting out the implementation code (and perhaps the actual SimpleServiceProvider class as well, without exposing it as a service) into a separate subproject—little if any actual code changes would be needed.
Splitting out the slf4j-simple implementation would allow others to create specialized versions. Without the separate artifact, a specialized version has to duplicate the slf4j-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 fork slf4j-simple and make a customized version. I believe (although I haven't asked him) that had slf4j-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 expose SimpleServiceProvider via the Java service provider mechanism, so that it wouldn't be detected by SLF4J automatically, requiring me to manually "enable it".
By default I want all logging in unit tests to be suppressed during the Maven build and in the IDE.
However if something goes wrong, I want to send logging to 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 put SimpleServiceProvider inside slf4j-simple-impl as well, but don't expose it as a Java service provider), I could simply include slf4j-simple-implin test scope in my parent POM. All my tests would automatically get the slf4j-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 override slf4j.provider with ….SimpleServiceProvider for the unit/integration tests. Suddenly all my unit tests would start logging to stdout/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 in slf4j-simple-impl but not expose it as a service; or leave it in slf4j-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.
The text was updated successfully, but these errors were encountered:
garretwilson
changed the title
Expose slf4j-simple logging implementation artifact separate from its provider.
Expose slf4j-simple-impl logging implementation artifact separate from its provider.
Nov 14, 2023
garretwilson
changed the title
Expose slf4j-simple-impl logging implementation artifact separate from its provider.
Expose slf4j-simple-impl logging implementation artifact separate from exposed service provider artifact.
Nov 14, 2023
garretwilson
changed the title
Expose slf4j-simple-impl logging implementation artifact separate from exposed service provider artifact.
Expose slf4j-simple-impl logging implementation artifact separate from its exposed service provider artifact.
Nov 14, 2023
garretwilson
changed the title
Expose slf4j-simple-impl logging implementation artifact separate from its exposed service provider artifact.slf4j-simple-impl logging implementation artifact separate from its exposed service provider artifact.
Nov 14, 2023
The only remaining question would be whether to include SimpleServiceProvider in slf4j-simple-impl but not expose it as a service; or leave it in slf4j-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.
The text was updated successfully, but these errors were encountered: