Giter VIP home page Giter VIP logo

slf4j's Introduction

About SLF4J

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, reload4j, log4j 2.x) allowing the end user to plug in the desired logging framework at deployment time.

More information can be found on the SLF4J website.

Build Status

Build Status

Search org.slf4j artifacts on Maven Central

Maven Central

In case of problems

In case of problems please do not hesitate to post an e-mail message on the [email protected] mailing list. However, please do not directly e-mail SLF4J developers. The answer to your question might be useful to other users. Moreover, there are many knowledgeable users on the slf4j-user mailing lists who can quickly answer your questions.

Urgent issues

For urgent issues do not hesitate to champion a release. In principle, most championed issues are solved within 3 business days ensued by a release.

How to build SLF4J

SLF4J uses Maven as its build tool.

SLF4J version 2.0.x will run under Java 8 but requires Java 9 or later to build.

How to contribute pull requests

If you are interested in improving SLF4J, that is great! The SLF4J community looks forward to your contribution. Please follow this process:

  1. Start a discussion on the slf4j-dev mailing list about your proposed change. Alternately, file a bug report to initiate the discussion. Note that we ask pull requests to be linked to a Jira ticket.

  2. Fork qos-ch/slf4j. Ideally, create a new branch from your fork for your contribution to make it easier to merge your changes back.

  3. Make your changes on the branch you hopefully created in Step 2. Be sure that your code passes existing unit tests. Please add unit tests for your work if appropriate. It usually is.

  4. All commits must have signed off by the contributor attesting to Developer Certificate of Origin (DCO). Commits without sign off will be automatically rejected by the DCO GitHub check application.

  5. Push your changes to your fork/branch in GitHub. Don't push it to your master! If you do it will make it harder to submit new changes later.

  6. Submit a pull request to SLF4J from your commit page on GitHub.

  7. Did we mention that you will be asked to link your pull request with a Jira ticket?

slf4j's People

Contributors

adorokhine avatar ash2k avatar barney2k7 avatar bnorm avatar ceki avatar chetanmeh avatar davishmcclurg avatar delgurth avatar dfa1 avatar dimitrisli avatar garcia-jj avatar gnodet avatar hanneswell avatar hazendaz avatar hboutemy avatar javabean avatar javabrett avatar jconlon avatar kengotoda avatar korzha avatar liborjelinek avatar lukecwik avatar mattbishop avatar motlin avatar nicolas-f avatar rgoers avatar sebkur avatar sschuberth avatar sullis avatar twillouer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slf4j's Issues

[Feature Request]: Add error method with varargs and Throwable in Logger interface

Feature request
I am requesting a feature where the logger interface is extended to have an error method that accepts varargs along with a Throwable.

Motivation
Currently, the error method accepts either a message with varargs or a message with a Throwable. There isn't a method that accepts both combined. This leads to a situation where developers are forced to combine messages and/or params with error objects manually, which can lead to loss of stack trace information or awkward workarounds.

Suggested Solution
Add the following method to the Logger interface:

void error(Throwable tString format, Object... arguments);

Usage Example
This allows the user to log an error with formatting options as well as attaching an exception stack trace like so:

logger.error(throwable, "Something went wrong with the value: {} {}", value1, value2);

I believe this enhancement will make the API more flexible and user-friendly when dealing with common logging scenarios that involve both parameters and exceptions.

license url (in POM) pointing to the generic license instead of actual license

While evaluating the License Maven Plugin to manage/download dependency licenses, I noticed that it does not download the 'correct' license for SLF4J. It does download a copy of the MIT license but the downloaded copy includes a generic copyright notice compared to a specific SLF4J copyright notice:

- Copyright <YEAR> <COPYRIGHT HOLDER>
+ Copyright (c) 2004-2023 QOS.ch

The plugin downloads the license referenced in <license><url> in the project's main POM. In this case, the specified URL points to the generic copy of the MIT license hosted at opensource.org: http://www.opensource.org/licenses/mit-license.php. Project Lombok, for example, points to its custom copy of the MIT license (which also includes the license of each dependency), instead:

<license>
    <name>The MIT License</name>
    <url>https://projectlombok.org/LICENSE</url>
    <distribution>repo</distribution>
</license>

Now I am wondering if it is an oversight to not point to SLF4J's specific copy of the MIT license?

Please notice, I deliberately ignore the discussion, if the MIT license actually requires projects depending on an MIT licensed dependency to bundle a copy of that license: Including a copy of the license does not break the license while not including it may.

Thanks for considering and please feel free to simply close this ticket, if you do not consider this an issue as grabbing a copy of the license and manually bundling it with our project(s) is simple.


Also, I've noticed that some of the sub modules in this project include license files with different a copyright notice. For example the copyright notice of the jul-to-slf4j sub module reads Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland), which would require that sub module's POM to override <license><url> to point to its own license file, if the above is considered an issue.

Can this Library use in android app ?

I want to use 'org.slf4j:slf4j-simple' on 'Android Studio Flamingo | 2022.2.1'.

in file 'app/build.gradle' / block 'dependencies', only add
implementation 'org.slf4j:slf4j-simple:2.0.13'

build error

> Task :app:mergeExtDexDebug FAILED
AGPBI: {"kind":"error","text":"java.lang.NullPointerException","sources":[{"file":"C:\\Users\\wanko\\.gradle\\caches\\modules-2\\files-2.1\\org.slf4j\\slf4j-simple\\2.0.13\\be11a3f05f7cf546524b07ad252719d840f4daed\\slf4j-simple-2.0.13.jar"}],"tool":"D8"}
AGPBI: {"kind":"error","text":"java.lang.NullPointerException","sources":[{"file":"C:\\Users\\wanko\\.gradle\\caches\\modules-2\\files-2.1\\org.slf4j\\slf4j-api\\2.0.13\\80229737f704b121a318bba5d5deacbcf395bc77\\slf4j-api-2.0.13.jar"}],"tool":"D8"}

> Task :app:processDebugManifestForPackage
> Task :app:mergeLibDexDebug
> Task :app:mergeDebugResources
> Task :app:mergeDebugJavaResource
> Task :app:processDebugResources
> Task :app:compileDebugJavaWithJavac
> Task :app:dexBuilderDebug
> Task :app:mergeProjectDexDebug

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeExtDexDebug'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Failed to transform slf4j-simple-2.0.13.jar (org.slf4j:slf4j-simple:2.0.13) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=21, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for DexingWithClasspathTransform: C:\Users\wanko\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-simple\2.0.13\be11a3f05f7cf546524b07ad252719d840f4daed\slf4j-simple-2.0.13.jar.
         > Error while dexing.
   > Failed to transform slf4j-api-2.0.13.jar (org.slf4j:slf4j-api:2.0.13) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=21, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for DexingWithClasspathTransform: C:\Users\wanko\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\2.0.13\80229737f704b121a318bba5d5deacbcf395bc77\slf4j-api-2.0.13.jar.
         > Error while dexing.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s
30 actionable tasks: 30 executed

OK
implementation 'org.slf4j:slf4j-simple:2.0.9'

NG
implementation 'org.slf4j:slf4j-simple:2.0.10'
implementation 'org.slf4j:slf4j-simple:2.0.12'
implementation 'org.slf4j:slf4j-simple:2.0.13'

MavenGate (CVE)

XFrog triggers an alert XRAY-589059 on packages:

  • org.slf4j:jul-to-slf4j
  • org.slf4j:slf4j-api

Looks like groupId domain org.slf4j can be claimed by malicious user.

Fluent logging of primitive types

When using LoggingEventBuilder to addArgument or addKeyValue the only parameter options are Object or Supplier. If I use any primitive type (boolean, char, byte, short, int, long, float, double) then the compiler autoboxes them, even when the specified log level is not enabled and the Nop builder then discards them. This can generate a lot of eden garbage. This is an issue for me as I am working on a high throughput, garbage free, app which deals primarily in primitive types.
Adding these variants as additional methods eg addKeyValue("Foo", 1.23d) etc would delay the auto boxing until when, and only when, the logging is going to output something.
Currently the only surefire way to avoid this is to wrap such logging within an is<Level>Enabled block.

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder"

I was using log4j version 2.23.1 which comes with slf4j-api version 2.0.9. Below are the dependencies:
<log4j2.version>2.23.1</log4j2.version>

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-api</artifactId>
	<version>${log4j2.version}</version>
</dependency>

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-core</artifactId>
	<version>${log4j2.version}</version>
</dependency>

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-slf4j2-impl</artifactId>
	<version>${log4j2.version}</version>
</dependency>

And I was using maven-assembly-plugin to build a single jar with all dependencies

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-assembly-plugin</artifactId>
	<version>3.7.1</version>
	<configuration>
		<descriptorRefs>
			<descriptorRef>jar-with-dependencies</descriptorRef>
		</descriptorRefs>
	</configuration>
	<executions>
		<execution>
			<id>assemble-all</id>
			<phase>package</phase>
			<goals>
				<goal>single</goal>
			</goals>
		</execution>
	</executions>
</plugin>

Included the following imports:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Using slf4j logger

Logger log = LoggerFactory.getLogger(Main.class);

When I run the standalone main application (fat jar including all the dependencies), I see the below log in the console

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

When I run same standalone main application (without fat jar) and added the above log4j and slf4j dependencies to classpath, I don't see any issue

org.slf4j.LoggerFactory (in module org.slf4j) cannot access class org.slf4j.impl.StaticLoggerBinder (JPMS APPLICATION)

       <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.23.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.23.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.23.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.13</version>
        </dependency>

log4j2.xml

<Properties>
        <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss,SSS} %highlight{%-5level} [%t] %highlight{%c{1.}.%M(%L)}: %msg%n" />
        <property name="FILE_PATH" value="${sys:LogHomeRoot}" />
</Properties>
...
    public static void main(String[] args){
          String runLogDir = STR."\{System.getProperty("user.dir")}\{File.separator}log";
          System.setProperty("LogHomeRoot", runLogDir);
          ....
    }

In the scenario described, I attempted to dynamically specify the log path at runtime. Since the project ultimately needs to be packaged using jlink/jpackage, I added a module-info.class for SLF4J. However, an exception was still thrown at runtime. Eventually, I had to add the Java option --add-reads org.slf4j=org.apache.logging.log4j.slf4j.impl to start the application,
this is quite troublesome... Can this issue be resolved in a future version?

I added the module-info file to the JAR using the following commands:

jdeps --ignore-missing-deps --generate-module-info . slf4j-api-1.7.36.jar
javac --patch-module org.slf4j=slf4j-api-1.7.36.jar org.slf4j/module-info.java
jar uf slf4j-api-1.7.36.jar -C org.slf4j module-info.class

stackTrace
Caused by: java.lang.IllegalAccessError: class org.slf4j.LoggerFactory (in module org.slf4j) cannot access class org.slf4j.impl.StaticLoggerBinder (in module org.apache.logging.log4j.slf4j.impl) because module org.slf4j does not read module org.apache.logging.log4j.slf4j.impl
at org.slf4j/org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j/org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j/org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:417)
at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:362)
at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:388)
at my_driver/com.tom.controller.MyDriverPaneController.(MyDriverPaneController.java:16)
at my_driver/com.tom.FXMLVersionApp.start(FXMLVersionApp.java:23)
at javafx.graphics@22/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at javafx.graphics@22/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at javafx.graphics@22/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at javafx.graphics@22/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at javafx.graphics@22/com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:95)

putCloseable should not remove the key from MDC if it was previously set to a different value

Our team wrote some code that broadly looked like this:

MDC.put("color", "red");

try(ignored = MDC.putCloseable("color", "green")) {
...
}

assertTrue(MDC.get("color", "green")) // fails, the key is deleted

It should be an easy patch to allow callers to nest putCloseable calls and get expected results; in fact, I'll go try to write one now.

Thank you very much, by the way, for SLF4j -- it's a wonderful tool. Cheers

DefaultLoggingEventBuilder/Log4jEventBuilder "addArgument" with supplier behaves same as constant value.

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
            <version>3.0.0-alpha1</version>
        </dependency>

DefaultLoggingEventBuilder addArgument with supplier should be executed an after calling log() not directly during "addArgument" calling, else it is same as constant value.

    @Override
    public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
        loggingEvent.addArgument(objectSupplier.get());
        return this;
    }

should be

    @Override
    public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
        loggingEvent.addArgument(objectSupplier);
        return this;
    }

Same behaviour is in "Log4jEventBuilder"

slf4j doesn't work on the docker

Right now, I'm working on the Apache Pulsar project, and migrating the slf4j to 2.0.12 from 1.7.36, but it always prints the following log:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

please see apache/pulsar#22391, the GHA env is Ubuntu, we are using the testcontainers to run the integration test, and the test image is based on the alpine 3.9:

  • When running this image on ubuntu, it always prints the above log.
  • When running this image on the MacOS, it works fine.

I'm not sure where the problem is, thanks for your time!

How to reproduce

docker run -it nodece/java-test-image bin/pulsar proxy
  • Ubuntu 22
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2024-04-07T14:35:25,623Z [jdk.internal.loader.ClassLoaders$AppClassLoader@63c12fb0] error Uncaught exception in thread main: java.lang.IllegalArgumentException: metadataStoreUrl must be provided
org.apache.pulsar.broker.PulsarServerException: java.lang.IllegalArgumentException: metadataStoreUrl must be provided
        at org.apache.pulsar.proxy.server.ProxyServiceStarter.<init>(ProxyServiceStarter.java:205)
        at org.apache.pulsar.proxy.server.ProxyServiceStarter.main(ProxyServiceStarter.java:215)
Caused by: java.lang.IllegalArgumentException: metadataStoreUrl must be provided
        at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143)
        at org.apache.pulsar.proxy.server.ProxyServiceStarter.<init>(ProxyServiceStarter.java:193)
        ... 1 more
  • MacOS 14.1.1, it works fine.
2024-04-07T14:46:00,668+0000 [main] ERROR org.apache.pulsar.proxy.server.ProxyServiceStarter - Failed to start pulsar proxy service. error msg metadataStoreUrl must be provided
java.lang.IllegalArgumentException: metadataStoreUrl must be provided
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143) ~[com.google.guava-guava-32.1.2-jre.jar:?]
	at org.apache.pulsar.proxy.server.ProxyServiceStarter.<init>(ProxyServiceStarter.java:193) [org.apache.pulsar-pulsar-proxy-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
	at org.apache.pulsar.proxy.server.ProxyServiceStarter.main(ProxyServiceStarter.java:215) [org.apache.pulsar-pulsar-proxy-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
2024-04-07T14:46:00,699Z [jdk.internal.loader.ClassLoaders$AppClassLoader@63c12fb0] error Uncaught exception in thread main: java.lang.IllegalArgumentException: metadataStoreUrl must be provided
org.apache.pulsar.broker.PulsarServerException: java.lang.IllegalArgumentException: metadataStoreUrl must be provided
	at org.apache.pulsar.proxy.server.ProxyServiceStarter.<init>(ProxyServiceStarter.java:205)
	at org.apache.pulsar.proxy.server.ProxyServiceStarter.main(ProxyServiceStarter.java:215)
Caused by: java.lang.IllegalArgumentException: metadataStoreUrl must be provided
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143)
	at org.apache.pulsar.proxy.server.ProxyServiceStarter.<init>(ProxyServiceStarter.java:193)
	... 1 more

MDC Usage regression

Hello,
Currently i'm using Slf4j version 2.0.11 and Logback version 1.4.14
I'm working on an old products with a lot of code and using a lot of thread, so I need to have MDC properties thread inheritance. So I force the usage of a BasicMDCAdapter by setting the MDC.mdcAdapter to new BasicMDCAdapter() when my program starts.

The problem is that, using Slf4j version 2.0.11 and Logback version 1.4.14 this doesn't work anymore.
I don't have any MDC info in my logs.
Could you please tell me what is the correct way to use your BasicMDCAdapter ? or tell me another way to have MDC properties thread inheritance ?

Many thanks

`slf4j-simple-impl` logging implementation artifact separate from its exposed service provider artifact.

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.

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 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".

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:

  1. By default I want all logging in unit tests to be suppressed during the Maven build and in the IDE.
  2. 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-impl in 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.

Apparently dead code in LoggerFactory

While reading slf4j2 code to figure out how bindingsproviders work, I came across a line that confused me: catch(NoSuchFieldError) in LoggerFactory

private final static void versionSanityCheck() {
try {
String requested = PROVIDER.getRequestedApiVersion();
boolean match = false;
for (String aAPI_COMPATIBILITY_LIST : API_COMPATIBILITY_LIST) {
if (requested.startsWith(aAPI_COMPATIBILITY_LIST)) {
match = true;
}
}
if (!match) {
Util.report("The requested version " + requested + " by your slf4j provider is not compatible with "
+ Arrays.asList(API_COMPATIBILITY_LIST).toString());
Util.report("See " + VERSION_MISMATCH + " for further details.");
}
} catch (java.lang.NoSuchFieldError nsfe) {
// given our large user base and SLF4J's commitment to backward
// compatibility, we cannot cry here. Only for implementations
// which willingly declare a REQUESTED_API_VERSION field do we
// emit compatibility warnings.
} catch (Throwable e) {
// we should never reach here
Util.report("Unexpected problem occurred during version sanity check", e);
}
}

I was wondering why the comment references REQUESTED_API_VERSION, while there's no such thing in the try.

I found the change that invalidated that catch, and I'm still baffled as to why Java does not complain about a checked exception being not used I see why javac didn't alert: it's an Error, not checked!.

Wrong classname when using slf4j inside a wrapper and logging via LoggingEventBuilder

I am using the kotlin-logging library which is basically a wrapper around slf4j tailored for kotlin. (Original issue kotlin-logging-416).

When logging using the LoggingEventBuilder and setting the CallerBoundary accordingly it prints the wrong classname.

package my.pkg;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.CallerBoundaryAware;

public class Example {
    private static final LoggingWrapper wrapper = new LoggingWrapper();

    public static void main(String[] args) {
        wrapper.logWithEvent("hello");
    }
}

class LoggingWrapper {
    private Logger underlyingLogger = LoggerFactory.getLogger("anything");

    public void logWithEvent(String msg) {
        var builder = underlyingLogger.atInfo();
        // setting the caller boundary to LoggingWrapper
        if(builder instanceof CallerBoundaryAware)
            ((CallerBoundaryAware) builder).setCallerBoundary(LoggingWrapper.class.getName());
        builder.log(msg);
    }
}

Running the given example I expect the following output:

Apr. 06, 2024 6:28:12 AM my.pkg.Example main
INFORMATION: hello

However following is printed:

Apr. 06, 2024 6:28:12 AM my.pkg.LoggingWrapper logWithEvent
INFORMATION: hello

Checkout the example: example.zip

JUL bridge and System.Logger are inconsistent on handling of OFF and ALL

When logging with either the System.Logger or the JUL the expectation of passing Level.OFF (which does not have an SLF4J analog) is inconsistent when they should be same. Ideally they should both NOOP.

That is when passing making a logging request with Level.OFF it should be off.

This can be clearly seen in java.util.logging.Handler.isLoggable(LogRecord)

    public boolean isLoggable(LogRecord record) {
        final int levelValue = getLevel().intValue();
        if (record == null) return false;
        if (record.getLevel().intValue() < levelValue || levelValue == offValue) {
            return false;
        }
        final Filter filter = getFilter();
        if (filter == null) {
            return true;
        }
        return filter.isLoggable(record);
    }

N.B. the levelValue == offValue. All JUL handlers inherit isLoggable including the SLF4J bridge.

However here it is turned into ERROR here:

slf4jLogger.error(i18nMessage, record.getThrown());

Worse is in the System.Logger it is reported as an error:

It clearly was the intention of the System.Logger to follow JUL behavior as it is documented:

            /**
             * A marker to indicate that all levels are disabled.
             * This level {@linkplain #getSeverity() severity} is
             * {@link Integer#MAX_VALUE}.
             */
            OFF(Integer.MAX_VALUE);  // typically mapped to/from j.u.l.Level.OFF

Message formatting with last argument being Throwable

I really often hit issue with slf4j interpreting my messages not the way I'd like it to.
I don't think its reasonable to have two following lines result in different behaviour.

Throwable ex = ...
Item item = ...

log.warn("Processing issue; ex={}, item={}", ex, item);   // this works fine
log.warn("Processing issue; item={}, ex={}", item, ex);   // and this produces "... issue=Issue(123), ex={}"  followed by stacktrace

I think the MessageFormatter should take into account number of placeholders, and try to use last argument as throwable candidate only if not bound.

FAQ says:

If the exception is not the last argument, it will be treated as a plain object and its stack trace will NOT be printed. However, such situations should not occur in practice.

For me this is not true. I quite often want to see just ex.toString, specially where exception is part of business logic. I just want to log its name, description, details - I don't care about stack trace. So it's common to treat exception just as any other part of message.

SLF4J, in accordance with the programmer's most probable intention, will interpret NumberFormatException instance as a throwable instead of an unused Object parameter

And this one actually suggests what should be done. It says about choice between exception and unused object parameter. And code actually does not check if parameter is used - it just picks last argument, resulting in message with last '{}' not filled in, and with unwanted stacktrace appended.

Add support for log level independent logging

Besides ordinary/journal logging there are other logging needs like audit, trace, and metrics logging. Those other types of logging have all in common that the log message shall be published independently of a logging level.

Log4J2 supports such use cases by invoking org.apache.logging.log4j.spi.ExtendedLogger#logIfEnabled with level set to org.apache.logging.log4j.Level#OFF.

How would SLF4J support such use cases? It would be nice to have a method like org.slf4j.Logger#atOff#log(org.slf4j.Marker, java.lang.String) or org.slf4j.Logger#log(org.slf4j.Marker, java.lang.String) with a corresponding binding to Log4J2 that always publishes a log message independently of the log level.

Without such, the above mentioned use cases cannot elegantly implemented using this facade.

Make `slf4j.provider` constant public.

Good work @KengoTODA on SLF4J-450. Unfortunately the PROVIDER_PROPERTY_KEY constant is not public in LoggerFactory:

static final public String PROVIDER_PROPERTY_KEY = "slf4j.provider";

This is part of the official, documented API, so it's appropriate that it should be public. After all I might want to programmatically set the system property like this (see #361), for example in JUnit tests:

@BeforeAll
static void disableLogging() {
  System.setProperty("slf4j.provider", NOP_FallbackServiceProvider.class.getName());
}

If nobody has any objections, I can file a pull request for this.

Explicit provider fails when used with module system

it looks like it is trying to create e new instance based on this property. I guess it would be better to loop over the providers and check if there is a matching instance.

SLF4J(I): Attempting to load provider "org.slf4j.simple.SimpleServiceProvider" specified via "slf4j.provider" system property
SLF4J(E): Failed to instantiate the specified SLF4JServiceProvider (org.slf4j.simple.SimpleServiceProvider)
SLF4J(E): Reported exception:
java.lang.IllegalAccessException: class org.slf4j.LoggerFactory (in module org.slf4j) cannot access class org.slf4j.simple.SimpleServiceProvider (in module org.slf4j.simple) because module org.slf4j.simple does not export org.slf4j.simple to module org.slf4j
        at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:394)
        at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:714)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:495)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at [email protected]/org.slf4j.LoggerFactory.loadExplicitlySpecified(LoggerFactory.java:225)

No-op logger is not a sane default

If no SLF4J providers are found, SLF4J defaults to no-op logger, which results in all logs, including errors and exceptions being hidden.

IMO this is not a sane default, a better default would be logging exceptions, errors and warning to stdout. stdout is perfectly fine for development and became a common practice for Docker containers in production.

The codebase already has SimpleLogger that does this, but when I tried to reference it in slf4j.LoggerFactory it introduced a circular dependency. Maybe it makes sense to copy SimpleLogger to base package, remove all extra code for configurability/etc, call it FallbackStdoutLogger and use it by default?

Don't log to `stderr` when `slf4j.provider` is used.

I didn't realize SLF4J-450 was already implemented, so I was excited to look into this. Thanks for the work on this, @ceki and @KengoTODA.

In the source code I see:

    static SLF4JServiceProvider loadExplicitlySpecified(ClassLoader classLoader) {
        String explicitlySpecified = System.getProperty(PROVIDER_PROPERTY_KEY);
        if (null == explicitlySpecified || explicitlySpecified.isEmpty()) {
            return null;
        }
        try {
            String message = String.format("Attempting to load provider \"%s\" specified via \"%s\" system property", explicitlySpecified, PROVIDER_PROPERTY_KEY);
            Util.report(message);
…

Unfortunately this logs a message to stderr every time we use the slf4j.provider property. I don't quite understand the point of that. Logging something to stderr outside of the normal SLF4J logging system should only be done as a last resort, if there is some unexpected error. For example, if no logger implementation is present, SLF4J indicates, "No SLF4J providers were found.". The point here is that the user should be warned if they inadvertently don't include a logging implementation. (I'm not sure I fully agree with that decision, but I certain understand the motivation.)

But there is nothing inadvertent about the slf4j.provider. If you include it, you know you're specifically requesting a logging provider. You don't need SLF4J to remind you of that. If SLF4J uses a provider it finds on the classpath, SLF4J doesn't send a message to stderr notifying the user of which provider they chose. I don't see the difference here—if any thing, there is less of a reason to log information, because nothing happened "by default"—there was an explicit configuration.

Let's say that I want all my unit tests to ignore all logging output of the libraries they use, so that I won't have to have a logging implementation in test scope at all. (See SLF4J-592.) By default SLF4J does a a NOP, so I could just leave it at that, except that all my unit tests will have this:

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.

SLF4J-450 should fix that! Now I can do this in JUnit:

@BeforeAll
static void disableLogging() {
  System.setProperty("slf4j.provider", NOP_FallbackServiceProvider.class.getName());
}

Now I get the following, which defeats the purpose of what I was trying to do. 🤦‍♂️

SLF4J: Attempting to load provider "org.slf4j.helpers.NOP_FallbackServiceProvider" specified via "slf4j.provider" system property

I can do an ugly hack to get rid of the message:

@BeforeAll
static void disableLogging() {
  System.setProperty("slf4j.provider", NOP_FallbackServiceProvider.class.getName());
  final PrintStream originalSystemErr = System.err;
  try {
    System.setErr(new PrintStream(OutputStream.nullOutputStream()));
    LoggerFactory.getILoggerFactory();
  } finally {
    System.setErr(originalSystemErr);
  }
}

That suppresses the message. But if I'm going to do that, there's no point in using slf4j.provider at all, because SLF4J would default to the NOP provider anyway.

Please remove messages to stderr when slf4j.provider is used. Or just let me know that you're OK with this change, and I can file a pull request.

[question] Log4j Version

Hi @ceki

Please, what's the log4j version used when I've org.slf4j:log4j-over-slf4j:jar:1.7.10:compile as dependency?

Or at least, what's the log4j version that org.slf4j:log4j-over-slf4j:jar:1.7.10:compile is trying to mock?

Is there any page that I can use use as reference to get this information?


My question is mainly to figure out what are the Log4j features that I'm able to use based on its version.

Search for service provider using context class loader as a fallback

We are using a custom class loader for loading our application classes, but delegate loading SLF4j to standard classloaders.
Because of this SLF4J cannot load our custom ServiceProvider.

A simple fix for such situations is to perform a fallback search for service providers using context class loader.

The solution provided here would fix the issue.

I could provide an implementation if necessary.

load slf4j 2.0.x Exceptions in OSGI , the version number and check mode are incorrect.

Failed to load slf4j-api in the OSIG environment.

ERROR log :
Unresolved requirement: Import-Package: org.slf4j
-> Export-Package: org.slf4j; bundle-symbolic-name="slf4j.api"; bundle-version="2.0.12"; version="1.7.36"
slf4j.api [9]
Unresolved requirement: Require-Capability: osgi.extender; filter:="(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))"
Unresolved requirement: Import-Package: org.slf4j.helpers
-> Export-Package: org.slf4j.helpers; bundle-symbolic-name="slf4j.api"; bundle-version="2.0.12"; version="1.7.36"

in parent pom.xml slf4j-master/slf4j-master/parent/pom.xml
<latest.1.version>1.7.36</latest.1.version>

in slf4j-api pom.xml

<plugin>
       <groupId>org.apache.felix</groupId>
       <artifactId>maven-bundle-plugin</artifactId>
       <configuration>
         <instructions>
           <Import-Package>org.slf4j.spi;version="${range;[===,+);${version_cleanup;${project.version}}}"</Import-Package>
           <!-- Export the client/user package of slf4j-api version 1 to make the slf4j-api bundle in version 2 usable for bundles that only import slf4j-1.x -->
           <_exportcontents><![CDATA[
             *,\
             **org.slf4j;version="${latest.1.version}",\
             org.slf4j.helpers;version="${latest.1.version}"**
           ]]></_exportcontents>
           <Require-Capability><![CDATA[
             **osgi.extender;filter:="(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))",**
             osgi.serviceloader;filter:="(osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider)";osgi.serviceloader="org.slf4j.spi.SLF4JServiceProvider"
           ]]></Require-Capability>
         </instructions>
       </configuration>
     </plugin>

Please help to check the verification logic of the version number and filter.
Thanks

MDC + Context Propagation Feature Request

Problem

MDC is a useful way to inject pertinent context into log messages. But the current design makes it challenging to work with intra-service propagation solutions, like OpenTelemetry's Context mechanism. Typically these mechanisms are basically a Map from aString-shaped key to an Object. MDC provides a clear API for what we would want to propagate, which would be MDC.getCopyOfContextMap, but when we switch threads, we would have access to that context again, but we wouldn't have a way to use that context. We would need to write code to call MDC.setContextMap, and consistently do that every time we switch threads. Instead, it would be much easier if we could have SLF4J (or its implementations) call directly into the context propagation mechanism and read the context from there. In practice, they are often doing the same thing under the hood as a logging implementation with ThreadLocal, but they also have a mechanism for propagating the context across threads (for example with OTel, they have an auto-instrumentation java agent that can add java byte code to move the context automatically across when you fork, or schedule new work).

With the current API, folks go to extreme lengths to work around the current limitations of the SLF4J API.

Proposed Solution (Option 1)

Add a public API for overriding the MDCAdapter. Today, there's no way to wrap-and-modify or replace the MDCAdapter that's provided by a logging implementation. This means that if you want to change it, you need to take your logging implementation, rip out the suggested SLF4JServiceProvider implementation, and provide your own. Or else override MDC#mdcAdapter. However, there is currently a scary message that this is not the only place where you must override MDC.mdcAdapter. Instead, it would be great for MDC to have an MDC.overrideMDCAdapter(MDCAdapter) method that would also be compatible with the SLF4JServiceProvider implementations, perhaps adding a SLF4JServiceProvider#overrideMDCAdapter(MDCAdapter) method.

This has the advantage that it provides maximum flexibility. However, it may end up being a bit of a footgun if it provides too much flexibility and eventually becomes something that customers misuse.

Proposed Solution (Option 2)

Provide a way to register an additional way to fetch MDC Context. This could be an MDCExtension interface that exposes a method MDCExtension#getContext() and MDCExtension#get(key). This would let customers provide extra info when it’s time to read MDCContext. To implement this, we could add a method to MDCAdapter to take into account this extra MDCExtension.

Result

SLF4J users who do intra-service context propagation wouldn’t need to jump through hoops to integrate with MDC.

Note

I'm happy to implement this feature once we've come to a consensus on what it should look like.

Can we log the message to stdout when there is no provider available?

This is the default behavior since the very beginning of slf4j, including the latest slf4j-api:2.0.9:

When there's no provider available, slf4j prints an error message to stderr when the library is used for the first time and swallows all logging messages.

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.

Can we just log to stdout instead of swallowing the messages?

I know there's a slf4j-simple but it would be much easier to "combine" slf4j-api and slf4j-simple, or just log to stdout/stderr.

The graal native-image gives us an opportunity to build fast command line tools, which will use some existing java libraries. Since slf4j is widely used, a lot of libraries uses slf4j as their logging dependency.
However this requires us to include slf4j-simple for the projects which depend on these libraries.

This is ok for projects running on the server side since it would always need a logging impl anyway, but it's quite redundant for the command-line tools, and it would require extra configurations when building the native-image (we must ensure slf4j-simple accessible and can be used via reflection when building).

So can we consider to simply log to stdout when there is no provider available?

[BUG] - JCL-Over-SLF4J Module Definition does not specify the service loader for JPMS applications

Hey Guys,

The module definition for the jcl-over-slf4j unfortunately does not specify the service loader for org.apache.commons.logging.LogFactory

When executing applications in a built JRE (Using JLink or JPackage), the services are loaded from their module definitions, and the functionality is not loaded.

Could you please possible update the module definition -

module org.apache.commons.logging {
    requires org.slf4j;

    exports org.apache.commons.logging;
    
    provides org.apache.commons.logging.LogFactory with org.apache.commons.logging.impl.SLF4JLogFactory;
}

Much appreciated

Version 2.0.10 failed to execute mvn test

When I execute mvn test in the source directory, I report the following error:

----------------< org.slf4j:slf4j-jdk-platform-logging >----------------
[INFO] Building SLF4J JDK Platform Logging Integration 2.0.10            [7/16]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ slf4j-jdk-platform-logging ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource to META-INF
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:compile (default-compile) @ slf4j-jdk-platform-logging ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:compile (module-compile) @ slf4j-jdk-platform-logging ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-bundle-plugin:5.1.9:manifest (bundle-manifest) @ slf4j-jdk-platform-logging ---
[INFO] Stale files detected, re-generating manifest.
[INFO] Writing manifest: /home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src/slf4j-jdk-platform-logging/target/classes/META-INF/MANIFEST.MF
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ slf4j-jdk-platform-logging ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src/slf4j-jdk-platform-logging/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:testCompile (default-testCompile) @ slf4j-jdk-platform-logging ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src/slf4j-jdk-platform-logging/target/test-classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] module not found: org.slf4j
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for SLF4J BOM 2.0.10:
[INFO]
[INFO] SLF4J BOM .......................................... SUCCESS [  0.006 s]
[INFO] SLF4J Parent POM ................................... SUCCESS [  0.848 s]
[INFO] SLF4J API Module ................................... SUCCESS [  4.847 s]
[INFO] SLF4J Simple Provider .............................. SUCCESS [  3.226 s]
[INFO] SLF4J NOP Provider ................................. SUCCESS [  1.080 s]
[INFO] SLF4J JDK14 Provider ............................... SUCCESS [  2.813 s]
[INFO] SLF4J JDK Platform Logging Integration ............. FAILURE [  0.600 s]
[INFO] SLF4J LOG4J-12 Binding relocated ................... SKIPPED
[INFO] SLF4J Reload4j Provider ............................ SKIPPED
[INFO] SLF4J Extensions Module ............................ SKIPPED
[INFO] JCL 1.2 implemented over SLF4J ..................... SKIPPED
[INFO] Log4j Implemented Over SLF4J ....................... SKIPPED
[INFO] JUL to SLF4J bridge ................................ SKIPPED
[INFO] OSGi LogService implemented over SLF4J ............. SKIPPED
[INFO] SLF4J Integration tests ............................ SKIPPED
[INFO] SLF4J Migrator ..................................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.908 s
[INFO] Finished at: 2024-01-05T15:20:30+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:testCompile (default-testCompile) on project slf4j-jdk-platform-logging: Compilation failure
[ERROR] module not found: org.slf4j
[ERROR]
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <args> -rf :slf4j-jdk-platform-logging
[root@simon28li spack-src]#
[root@simon28li spack-src]# pwd
/home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src

But when I went to the subdirectory where the test error was reported to test, I didn't report an error. What caused this?

[root@simon28li spack-src]# cd slf4j-jdk-platform-logging
[root@simon28li slf4j-jdk-platform-logging]# mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< org.slf4j:slf4j-jdk-platform-logging >----------------
[INFO] Building SLF4J JDK Platform Logging Integration 2.0.10
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ slf4j-jdk-platform-logging ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource to META-INF
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:compile (default-compile) @ slf4j-jdk-platform-logging ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:compile (module-compile) @ slf4j-jdk-platform-logging ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-bundle-plugin:5.1.9:manifest (bundle-manifest) @ slf4j-jdk-platform-logging ---
[INFO] Stale files detected, re-generating manifest.
[INFO] Writing manifest: /home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src/slf4j-jdk-platform-logging/target/classes/META-INF/MANIFEST.MF
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ slf4j-jdk-platform-logging ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src/slf4j-jdk-platform-logging/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:testCompile (default-testCompile) @ slf4j-jdk-platform-logging ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/stage/root/spack-stage-slf4j-2.0.10-d3eqrim3igcnehqt456nzz2wvlafq2sh/spack-src/slf4j-jdk-platform-logging/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:3.0.0-M7:test (default-test) @ slf4j-jdk-platform-logging ---
[INFO] Using auto detected provider org.apache.maven.surefire.junit4.JUnit4Provider
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.slf4j.jdk.platform.logging.test.SLF4JPlatformLoggingTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.114 s - in org.slf4j.jdk.platform.logging.test.SLF4JPlatformLoggingTest
[INFO] org.slf4j.jdk.platform.logging.test.SLF4JPlatformLoggingTest.throwTest  Time elapsed: 0.034 s
[INFO] org.slf4j.jdk.platform.logging.test.SLF4JPlatformLoggingTest.smoke  Time elapsed: 0 s
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.298 s
[INFO] Finished at: 2024-01-05T15:25:11+08:00
[INFO] ------------------------------------------------------------------------
[root@simon28li slf4j-jdk-platform-logging]#

Error in the documentation (slf4j.binding)

In the documentation it is written:

SINCE 2.0.8 You can specify the provider class explicitly via the "slf4j.binding" system property. This bypasses the service loader mechanism for finding providers and may shorten SLF4J initialization.

But looking at the code (here), it is not slf4j.binding but slf4j.provider.

Can you update the documentation ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.