Compare commits

...

23 Commits

Author SHA1 Message Date
Ceki Gulcu 5ffbc67def prepare release 2.0.13
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-04-12 16:21:00 +02:00
Ceki Gulcu 3386517ad6 fix issues/409 SLF4J-601, wrong classname when using slf4j inside a wrapper
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-04-12 15:47:48 +02:00
Ceki Gulcu 448bca173c start work on 2.0.13-SNAPSHOT
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-02-05 22:58:12 +01:00
Ceki Gulcu 955209464d increase leniency count
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-02-05 22:32:22 +01:00
Ceki Gulcu c1473c957a prepare release 2.0.12
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-02-05 22:21:34 +01:00
Ceki Gulcu 98932348fb minor reminder
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-02-05 22:20:48 +01:00
Ceki Gulcu c52da92599 revert Util.report methods removed by mistake
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-02-05 22:17:54 +01:00
Ceki Gulcu da91e4f219 export provider packages, allow reflection by org.slf4j
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-02-05 21:45:58 +01:00
Ceki Gulcu 8c4ea8f225 more comments
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-23 15:51:31 +01:00
Ceki Gulcu 6b2921a523 start wotk on 2.0.12-SNAPSHOT
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 20:50:02 +01:00
Ceki Gulcu 3f4717c44e get javadoc:aggregate command to work
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 20:48:59 +01:00
Ceki Gulcu d9145fba56 prepare release 2.0.11
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 18:58:10 +01:00
Ceki Gulcu 68ff7064ec acceptance test, disabled for the moment
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 18:50:54 +01:00
Guillaume Nodet db8cd90c10 Use computeIfAbsent with a protected method, make reset protected
Signed-off-by: Guillaume Nodet <gnodet@gmail.com>
2024-01-08 17:39:25 +01:00
Guillaume Nodet d564304a61 Use computeIfAbsent with a protected method, make reset protected
Signed-off-by: Guillaume Nodet <gnodet@gmail.com>
2024-01-08 17:39:25 +01:00
Ceki Gulcu ef8dda71dd javadoc changed for SimpleLogger constructor
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 15:23:23 +01:00
Ceki Gulcu fe42ecb5f7 change constructor access modifier instead of
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 15:16:08 +01:00
Ceki Gulcu 7029a8b7fd add renderLevel method in SimpleLogger
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2024-01-08 15:02:22 +01:00
Ceki Gulcu 8c873b2e75 start work on 2.0.11-SNAPSHOT
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2023-12-29 00:03:40 +01:00
Ceki Gulcu 7bcee9aa1f javadoc configuration tweak
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2023-12-29 00:02:38 +01:00
Ceki Gulcu 6fe9c07113 more javadoc adjustments
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2023-12-28 21:48:34 +01:00
Ceki Gulcu df562c22d8 migrator should have javadocs
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2023-12-28 21:38:38 +01:00
Ceki Gulcu 6d39ca8bf9 prepare release 2.0.10
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
2023-12-28 21:14:08 +01:00
30 changed files with 757 additions and 304 deletions

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -24,10 +24,9 @@
<inceptionYear>2005</inceptionYear>
<properties>
<!-- yyyy-MM-dd'T'HH:mm:ss'Z' -->
<project.build.outputTimestamp>2023-09-03T16:20:19Z</project.build.outputTimestamp>
<project.build.outputTimestamp>2024-04-12T14:20:00Z</project.build.outputTimestamp>
<latest.1.version>1.7.36</latest.1.version>
<!-- java.util.ServiceLoader requires Java 6 -->
<jdk.version>8</jdk.version>
@ -38,14 +37,14 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- used in integration testing -->
<cal10n.version>0.8.1</cal10n.version>
<reload4j.version>1.2.22</reload4j.version>
<reload4j.version>1.2.22</reload4j.version>
<logback.version>1.2.10</logback.version>
<jcl.version>1.2</jcl.version>
<junit.version>4.13.1</junit.version>
<maven-site-plugin.version>3.7.1</maven-site-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
<maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.3</maven-javadoc-plugin.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<maven-deploy-plugin.version>3.0.0-M1</maven-deploy-plugin.version>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
@ -53,7 +52,6 @@
<maven-bundle-plugin.version>5.1.9</maven-bundle-plugin.version>
</properties>
<dependencies>
<dependency>
@ -72,7 +70,7 @@
<artifactId>reload4j</artifactId>
<version>${reload4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.cal10n</groupId>
<artifactId>cal10n-api</artifactId>
@ -147,14 +145,14 @@
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</execution>
</execution>
<execution>
<execution>
<id>module-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</goals>
<configuration>
<release>9</release>
<compileSourceRoots>
@ -165,7 +163,6 @@
</execution>
</executions>
</plugin>
@ -200,19 +197,19 @@
<supportIncrementalBuild>true</supportIncrementalBuild>
<!-- populated by the plugin itself -->
<instructions>
<Bundle-SymbolicName>${replacestring;${project.artifactId};-;.}</Bundle-SymbolicName>
<Bundle-Vendor>SLF4J.ORG</Bundle-Vendor>
<_snapshot/>
<_exportcontents>!META-INF.versions.9,*;-noimport:=true</_exportcontents>
<Bundle-Description>${project.description}</Bundle-Description>
<Bundle-DocURL>${project.url}</Bundle-DocURL>
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
<Implementation-Version>${project.version}</Implementation-Version>
<Implementation-Title>${project.artifactId}</Implementation-Title>
<Multi-Release>true</Multi-Release>
<_removeheaders>Private-Package,Bundle-SCM, Bundle-Developers, Include-Resource</_removeheaders>
</instructions>
<Bundle-SymbolicName>${replacestring;${project.artifactId};-;.}</Bundle-SymbolicName>
<Bundle-Vendor>SLF4J.ORG</Bundle-Vendor>
<_snapshot/>
<_exportcontents>!META-INF.versions.9,*;-noimport:=true</_exportcontents>
<Bundle-Description>${project.description}</Bundle-Description>
<Bundle-DocURL>${project.url}</Bundle-DocURL>
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
<Implementation-Version>${project.version}</Implementation-Version>
<Implementation-Title>${project.artifactId}</Implementation-Title>
<Multi-Release>true</Multi-Release>
<_removeheaders>Private-Package,Bundle-SCM, Bundle-Developers, Include-Resource</_removeheaders>
</instructions>
</configuration>
<executions>
<execution>
@ -267,71 +264,8 @@
<version>3.0.0</version>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>${maven-jxr-plugin.version}</version>
<configuration>
<aggregate>true</aggregate>
<javadocDir>target/site/apidocs/</javadocDir>
<linkJavadoc>true</linkJavadoc>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<linkJavadoc>true</linkJavadoc>
<linksource>true</linksource>
<aggregate>true</aggregate>
<additionalOptions>
<additionalOption>-Xdoclint:none</additionalOption>
</additionalOptions>
<excludePackageNames>org.slf4j.migrator:org.slf4j.migrator.*</excludePackageNames>
<sourceFileExcludes>
<sourceFileExclude>**/module-info.java</sourceFileExclude>
</sourceFileExcludes>
<groups>
<group>
<title>SLF4J packages</title>
<packages>org.slf4j:org.slf4j.*</packages>
</group>
<group>
<title>SLF4J extensions</title>
<packages>
org.slf4j.cal10n:org.slf4j.profiler:org.slf4j.ext:org.slf4j.instrumentation:org.slf4j.agent
</packages>
</group>
<group>
<title>Jakarta Commons Logging packages</title>
<packages>org.apache.commons.*</packages>
</group>
<group>
<title>java.util.logging (JUL) to SLF4J bridge</title>
<packages>org.slf4j.bridge</packages>
</group>
<group>
<title>Apache log4j</title>
<packages>org.apache.log4j:org.apache.log4j.*</packages>
</group>
</groups>
</configuration>
</plugin>
</plugins>
</reporting>
</build>
<profiles>
<profile>

108
pom.xml
View File

@ -6,11 +6,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-bom</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<packaging>pom</packaging>
<url>http://www.slf4j.org</url>
<name>SLF4J BOM</name>
<description>SLF4J project BOM</description>
@ -25,9 +25,9 @@
<scm>
<url>https://github.com/qos-ch/slf4j</url>
<connection>scm:git:https://github.com/qos-ch/slf4j.git</connection>
</scm>
</scm>
<!-- Inspired by Improving the Maven Bill of Materials (BOM) Pattern -->
<!-- https://www.garretwilson.com/blog/2023/06/14/improve-maven-bom-pattern -->
<modules>
@ -38,7 +38,7 @@
<module>slf4j-jdk14</module>
<module>slf4j-jdk-platform-logging</module>
<module>slf4j-log4j12</module>
<module>slf4j-reload4j</module>
<module>slf4j-reload4j</module>
<module>slf4j-ext</module>
<module>jcl-over-slf4j</module>
<module>log4j-over-slf4j</module>
@ -68,7 +68,7 @@
<artifactId>slf4j-nop</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
@ -81,49 +81,49 @@
<artifactId>slf4j-jdk-platform-logging</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>osgi-over-slf4j</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -145,8 +145,84 @@
</developer>
</developers>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<configuration>
<verbose>true</verbose>
<skippedModules>
slf4j-jdk-platform-logging,slf4j-migrator,osgi-over-slf4j
</skippedModules>
<detectLinks>true</detectLinks>
<doctitle>SLF4J project modules ${project.version}</doctitle>
<windowtitle>SLF4J javadoc</windowtitle>
<bottom><![CDATA[Copyright &copy; 2005-{currentYear} QOS.CH Sarl. All rights reserved]]></bottom>
<linksource>true</linksource>
<additionalOptions>
<additionalOption>-Xdoclint:none</additionalOption>
</additionalOptions>
<groups>
<group>
<title>SLF4J API packages</title>
<packages>org.slf4j:org.slf4j.spi:org.slf4j.event:org.slf4j.helpers</packages>
</group>
<group>
<title>slf4j-simple package</title>
<packages>org.slf4j.simple</packages>
</group>
<group>
<title>slf4j-nop package</title>
<packages>org.slf4j.nop</packages>
</group>
<group>
<title>slf4j-jdk14 package</title>
<packages>org.slf4j.jul</packages>
</group>
<group>
<title>slf4j-reload4j package</title>
<packages>org.slf4j.reload4j</packages>
</group>
<group>
<title>SLF4J extensions</title>
<packages>
org.slf4j.cal10n:org.slf4j.profiler:org.slf4j.ext:org.slf4j.instrumentation:org.slf4j.agent
</packages>
</group>
<group>
<title>Jakarta Commons Logging packages</title>
<packages>org.apache.commons.*</packages>
</group>
<group>
<title>java.util.logging (JUL) to SLF4J bridge</title>
<packages>org.slf4j.bridge</packages>
</group>
<group>
<title>log4j-over-slf4j redirection</title>
<packages>org.apache.log4j:org.apache.log4j.*</packages>
</group>
</groups>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
@ -169,5 +245,5 @@
</build>
</profile>
</profiles>
</project>

View File

@ -4,6 +4,10 @@
#JDK8 - mvn site:site
#rscpSLF4J apidocs/
# JDK 11+
# adding the following
#mvn -Ddoclint=none -Dadditionalparam=-Xdoclint:none javadoc:aggregate
#mvn versions:set -DgenerateBackupPoms=false -DnewVersion=${VERSION_NUMBER}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -91,6 +91,9 @@ public class MDC {
static {
SLF4JServiceProvider provider = LoggerFactory.getProvider();
if (provider != null) {
// obtain and attach the MDCAdapter from the provider
// If you wish to change the adapter, Setting the MDC.mdcAdapter variable might not be enough as
// the provider might perform additional assignments that you would need to replicate/adapt.
mdcAdapter = provider.getMDCAdapter();
} else {
Reporter.error("Failed to find provider.");

View File

@ -23,6 +23,10 @@ public interface LoggingEvent {
Object[] getArgumentArray();
/**
* List of markers in the event, might be null.
* @return markers in the event, might be null.
*/
List<Marker> getMarkers();
List<KeyValuePair> getKeyValuePairs();

View File

@ -117,14 +117,28 @@ public final class Util {
return trace[i + 2];
}
// private static final void report(String msg, Throwable t) {
// System.err.println(msg);
// System.err.println("Reported exception:");
// t.printStackTrace();
// }
//
// static final private void report(String msg) {
// System.err.println("SLF4J: " + msg);
// }
/**
* See {@link Reporter#error(String, Throwable)} class for alternative.
*
* @deprecated replaced by the {@link Reporter#error(String, Throwable)} method.
* @param msg message to print
* @param t throwable to print
*/
static final public void report(String msg, Throwable t) {
System.err.println(msg);
System.err.println("Reported exception:");
t.printStackTrace();
}
/**
* See {@link Reporter} class for alternatives.
*
* @deprecated replaced by one of {@link Reporter#info(String)},
* {@link Reporter#warn(String)} or {@link Reporter#error(String)} methods.
* @param msg message to print
*/
static final public void report(String msg) {
System.err.println("SLF4J: " + msg);
}
}

View File

@ -1,7 +1,7 @@
/**
* Copyright (c) 2004-2022 QOS.ch
* All rights reserved.
*
* <p>
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@ -9,10 +9,10 @@
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* <p>
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -20,10 +20,10 @@
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package org.slf4j.spi;
import java.util.List;
import java.util.function.Supplier;
import org.slf4j.Logger;
@ -38,11 +38,11 @@ import org.slf4j.event.LoggingEvent;
*/
public class DefaultLoggingEventBuilder implements LoggingEventBuilder, CallerBoundaryAware {
// The caller boundary when the log() methods are invoked, is this class itself.
static String DLEB_FQCN = DefaultLoggingEventBuilder.class.getName();
protected DefaultLoggingEvent loggingEvent;
protected Logger logger;
@ -53,7 +53,7 @@ public class DefaultLoggingEventBuilder implements LoggingEventBuilder, CallerBo
/**
* Add a marker to the current logging event being built.
*
* <p>
* It is possible to add multiple markers to the same logging event.
*
* @param marker the marker to add
@ -72,165 +72,16 @@ public class DefaultLoggingEventBuilder implements LoggingEventBuilder, CallerBo
@Override
public LoggingEventBuilder addArgument(Object p) {
loggingEvent.addArgument(p);
this.loggingEvent.addArgument(p);
return this;
}
@Override
public LoggingEventBuilder addArgument(Supplier<?> objectSupplier) {
loggingEvent.addArgument(objectSupplier.get());
this.loggingEvent.addArgument(objectSupplier.get());
return this;
}
@Override
public void setCallerBoundary(String fqcn) {
loggingEvent.setCallerBoundary(fqcn);
}
@Override
public void log() {
log(loggingEvent);
}
@Override
public LoggingEventBuilder setMessage(String message) {
loggingEvent.setMessage(message);
return this;
}
@Override
public LoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
loggingEvent.setMessage(messageSupplier.get());
return this;
}
@Override
public void log(String message) {
loggingEvent.setMessage(message);
log(loggingEvent);
}
@Override
public void log(String message, Object arg) {
loggingEvent.setMessage(message);
loggingEvent.addArgument(arg);
log(loggingEvent);
}
@Override
public void log(String message, Object arg0, Object arg1) {
loggingEvent.setMessage(message);
loggingEvent.addArgument(arg0);
loggingEvent.addArgument(arg1);
log(loggingEvent);
}
@Override
public void log(String message, Object... args) {
loggingEvent.setMessage(message);
loggingEvent.addArguments(args);
log(loggingEvent);
}
@Override
public void log(Supplier<String> messageSupplier) {
if (messageSupplier == null) {
log((String) null);
} else {
log(messageSupplier.get());
}
}
protected void log(LoggingEvent aLoggingEvent) {
setCallerBoundary(DLEB_FQCN);
if (logger instanceof LoggingEventAware) {
((LoggingEventAware) logger).log(aLoggingEvent);
} else {
logViaPublicSLF4JLoggerAPI(aLoggingEvent);
}
}
private void logViaPublicSLF4JLoggerAPI(LoggingEvent aLoggingEvent) {
Object[] argArray = aLoggingEvent.getArgumentArray();
int argLen = argArray == null ? 0 : argArray.length;
Throwable t = aLoggingEvent.getThrowable();
int tLen = t == null ? 0 : 1;
String msg = aLoggingEvent.getMessage();
Object[] combinedArguments = new Object[argLen + tLen];
if (argArray != null) {
System.arraycopy(argArray, 0, combinedArguments, 0, argLen);
}
if (t != null) {
combinedArguments[argLen] = t;
}
msg = mergeMarkersAndKeyValuePairs(aLoggingEvent, msg);
switch (aLoggingEvent.getLevel()) {
case TRACE:
logger.trace(msg, combinedArguments);
break;
case DEBUG:
logger.debug(msg, combinedArguments);
break;
case INFO:
logger.info(msg, combinedArguments);
break;
case WARN:
logger.warn(msg, combinedArguments);
break;
case ERROR:
logger.error(msg, combinedArguments);
break;
}
}
/**
* Prepend markers and key-value pairs to the message.
*
* @param aLoggingEvent
* @param msg
* @return
*/
private String mergeMarkersAndKeyValuePairs(LoggingEvent aLoggingEvent, String msg) {
StringBuilder sb = null;
if (aLoggingEvent.getMarkers() != null) {
sb = new StringBuilder();
for (Marker marker : aLoggingEvent.getMarkers()) {
sb.append(marker);
sb.append(' ');
}
}
if (aLoggingEvent.getKeyValuePairs() != null) {
if (sb == null) {
sb = new StringBuilder();
}
for (KeyValuePair kvp : aLoggingEvent.getKeyValuePairs()) {
sb.append(kvp.key);
sb.append('=');
sb.append(kvp.value);
sb.append(' ');
}
}
if (sb != null) {
sb.append(msg);
return sb.toString();
} else {
return msg;
}
}
@Override
public LoggingEventBuilder addKeyValue(String key, Object value) {
loggingEvent.addKeyValue(key, value);
@ -243,4 +94,184 @@ public class DefaultLoggingEventBuilder implements LoggingEventBuilder, CallerBo
return this;
}
@Override
public void setCallerBoundary(String fqcn) {
this.loggingEvent.setCallerBoundary(fqcn);
}
@Override
public void log() {
log(this.loggingEvent);
}
@Override
public LoggingEventBuilder setMessage(String message) {
this.loggingEvent.setMessage(message);
return this;
}
@Override
public LoggingEventBuilder setMessage(Supplier<String> messageSupplier) {
this.loggingEvent.setMessage(messageSupplier.get());
return this;
}
@Override
public void log(String message) {
this.loggingEvent.setMessage(message);
log(this.loggingEvent);
}
@Override
public void log(String message, Object arg) {
this.loggingEvent.setMessage(message);
this.loggingEvent.addArgument(arg);
log(this.loggingEvent);
}
@Override
public void log(String message, Object arg0, Object arg1) {
this.loggingEvent.setMessage(message);
this.loggingEvent.addArgument(arg0);
this.loggingEvent.addArgument(arg1);
log(this.loggingEvent);
}
@Override
public void log(String message, Object... args) {
this.loggingEvent.setMessage(message);
this.loggingEvent.addArguments(args);
log(this.loggingEvent);
}
@Override
public void log(Supplier<String> messageSupplier) {
if(messageSupplier == null) {
log((String) null);
} else {
log(messageSupplier.get());
}
}
protected void log(LoggingEvent aLoggingEvent) {
if(aLoggingEvent.getCallerBoundary() == null) {
setCallerBoundary(DLEB_FQCN);
}
if(logger instanceof LoggingEventAware) {
((LoggingEventAware) logger).log(aLoggingEvent);
} else if(logger instanceof LocationAwareLogger) {
logViaLocationAwareLoggerAPI((LocationAwareLogger) logger, aLoggingEvent);
} else {
logViaPublicSLF4JLoggerAPI(aLoggingEvent);
}
}
private void logViaLocationAwareLoggerAPI(LocationAwareLogger locationAwareLogger, LoggingEvent aLoggingEvent) {
String msg = aLoggingEvent.getMessage();
List<Marker> markerList = aLoggingEvent.getMarkers();
String mergedMessage = mergeMarkersAndKeyValuePairsAndMessage(aLoggingEvent);
locationAwareLogger.log(null, aLoggingEvent.getCallerBoundary(), aLoggingEvent.getLevel().toInt(),
mergedMessage,
aLoggingEvent.getArgumentArray(), aLoggingEvent.getThrowable());
}
private void logViaPublicSLF4JLoggerAPI(LoggingEvent aLoggingEvent) {
Object[] argArray = aLoggingEvent.getArgumentArray();
int argLen = argArray == null ? 0 : argArray.length;
Throwable t = aLoggingEvent.getThrowable();
int tLen = t == null ? 0 : 1;
Object[] combinedArguments = new Object[argLen + tLen];
if(argArray != null) {
System.arraycopy(argArray, 0, combinedArguments, 0, argLen);
}
if(t != null) {
combinedArguments[argLen] = t;
}
String mergedMessage = mergeMarkersAndKeyValuePairsAndMessage(aLoggingEvent);
switch(aLoggingEvent.getLevel()) {
case TRACE:
logger.trace(mergedMessage, combinedArguments);
break;
case DEBUG:
logger.debug(mergedMessage, combinedArguments);
break;
case INFO:
logger.info(mergedMessage, combinedArguments);
break;
case WARN:
logger.warn(mergedMessage, combinedArguments);
break;
case ERROR:
logger.error(mergedMessage, combinedArguments);
break;
}
}
/**
* Prepend markers and key-value pairs to the message.
*
* @param aLoggingEvent
*
* @return
*/
private String mergeMarkersAndKeyValuePairsAndMessage(LoggingEvent aLoggingEvent) {
StringBuilder sb = mergeMarkers(aLoggingEvent.getMarkers(), null);
sb = mergeKeyValuePairs(aLoggingEvent.getKeyValuePairs(), sb);
final String mergedMessage = mergeMessage(aLoggingEvent.getMessage(), sb);
return mergedMessage;
}
private StringBuilder mergeMarkers(List<Marker> markerList, StringBuilder sb) {
if(markerList == null || markerList.isEmpty())
return sb;
if(sb == null)
sb = new StringBuilder();
for(Marker marker : markerList) {
sb.append(marker);
sb.append(' ');
}
return sb;
}
private StringBuilder mergeKeyValuePairs(List<KeyValuePair> keyValuePairList, StringBuilder sb) {
if(keyValuePairList == null || keyValuePairList.isEmpty())
return sb;
if(sb == null)
sb = new StringBuilder();
for(KeyValuePair kvp : keyValuePairList) {
sb.append(kvp.key);
sb.append('=');
sb.append(kvp.value);
sb.append(' ');
}
return sb;
}
private String mergeMessage(String msg, StringBuilder sb) {
if(sb != null) {
sb.append(msg);
return sb.toString();
} else {
return msg;
}
}
}

View File

@ -36,7 +36,7 @@ abstract public class MultithreadedInitializationTest {
assertAllSubstLoggersAreFixed();
long recordedEventCount = getRecordedEventCount();
int LENIENCY_COUNT = 21;
int LENIENCY_COUNT = 30;
long expectedEventCount = eventCount.get() + extraLogEvents();

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -8,7 +8,7 @@
<parent>
<artifactId>slf4j-parent</artifactId>
<groupId>org.slf4j</groupId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -2,5 +2,8 @@ module org.slf4j.jul {
requires org.slf4j;
requires java.logging;
provides org.slf4j.spi.SLF4JServiceProvider with org.slf4j.jul.JULServiceProvider;
exports org.slf4j.jul;
opens org.slf4j.jul to org.slf4j;
}

View File

@ -19,6 +19,8 @@ import org.slf4j.event.SubstituteLoggingEvent;
import org.slf4j.helpers.SubstituteLogger;
import org.slf4j.helpers.SubstituteServiceProvider;
import org.slf4j.jul.ListHandler;
import org.slf4j.spi.CallerBoundaryAware;
import org.slf4j.spi.LoggingEventBuilder;
public class CallerInfoTest {
Level oldLevel;
@ -77,6 +79,22 @@ public class CallerInfoTest {
assertEquals(this.getClass().getName(), logRecod.getSourceClassName());
}
@Test
public void testCallerInfoWithFluentAPIAndAWrapper() {
Logger logger = LoggerFactory.getLogger("bla");
LoggingWrapper wrappedLogger = new LoggingWrapper(logger);
wrappedLogger.logWithEvent("hello");
List<LogRecord> recordList = listHandler.recordList;
assertEquals(1, recordList.size());
LogRecord logRecod = recordList.get(0);
assertEquals(this.getClass().getName(), logRecod.getSourceClassName());
}
@Test
public void testPostInitializationCallerInfoWithSubstituteLogger() {
Logger logger = LoggerFactory.getLogger("bla");
@ -119,4 +137,22 @@ public class CallerInfoTest {
assertEquals(EventConstants.NA_SUBST, logRecod.getSourceClassName());
}
static class LoggingWrapper {
Logger underlyingLogger;
LoggingWrapper(Logger aLogger) {
this.underlyingLogger = aLogger;
}
public void logWithEvent(String msg) {
LoggingEventBuilder lev = underlyingLogger.atInfo();
// setting the caller boundary to LoggingWrapper
if(lev instanceof CallerBoundaryAware) {
// builder is CallerBoundaryAware
((CallerBoundaryAware) lev).setCallerBoundary(LoggingWrapper.class.getName());
}
lev.log(msg);
}
}
}

View File

@ -8,7 +8,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
@ -24,7 +24,7 @@
<relocation>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
<version>2.0.9</version>
<version>2.0.13</version>
</relocation>
</distributionManagement>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -1,4 +1,7 @@
module org.slf4j.nop {
requires org.slf4j;
provides org.slf4j.spi.SLF4JServiceProvider with org.slf4j.nop.NOPServiceProvider;
exports org.slf4j.nop;
opens org.slf4j.nop to org.slf4j;
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-parent</artifactId>
<version>2.0.10-SNAPSHOT</version>
<version>2.0.13</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

View File

@ -221,10 +221,10 @@ public class SimpleLogger extends LegacyAbstractLogger {
public static final String DEFAULT_LOG_LEVEL_KEY = SimpleLogger.SYSTEM_PREFIX + "defaultLogLevel";
/**
* Package access allows only {@link SimpleLoggerFactory} to instantiate
* Protected access allows only {@link SimpleLoggerFactory} and also derived classes to instantiate
* SimpleLogger instances.
*/
SimpleLogger(String name) {
protected SimpleLogger(String name) {
this.name = name;
String levelString = recursivelyComputeLevelString();
@ -409,7 +409,7 @@ public class SimpleLogger extends LegacyAbstractLogger {
buf.append('[');
// Append a readable representation of the log level
String levelStr = level.name();
String levelStr = renderLevel(level.toInt());
buf.append(levelStr);
if (CONFIG_PARAMS.levelInBrackets)
buf.append(']');
@ -439,6 +439,22 @@ public class SimpleLogger extends LegacyAbstractLogger {
write(buf, t);
}
protected String renderLevel(int levelInt) {
switch (levelInt) {
case LOG_LEVEL_TRACE:
return "TRACE";
case LOG_LEVEL_DEBUG:
return("DEBUG");
case LOG_LEVEL_INFO:
return "INFO";
case LOG_LEVEL_WARN:
return "WARN";
case LOG_LEVEL_ERROR:
return "ERROR";
}
throw new IllegalStateException("Unrecognized level ["+levelInt+"]");
}
public void log(LoggingEvent event) {
int levelInt = event.getLevel().toInt();

View File

@ -47,28 +47,31 @@ public class SimpleLoggerFactory implements ILoggerFactory {
/**
* Return an appropriate {@link SimpleLogger} instance by name.
*
* This method will call {@link #createLogger(String)} if the logger
* has not been created yet.
*/
public Logger getLogger(String name) {
Logger simpleLogger = loggerMap.get(name);
if (simpleLogger != null) {
return simpleLogger;
} else {
Logger newInstance = new SimpleLogger(name);
Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
return oldInstance == null ? newInstance : oldInstance;
}
return loggerMap.computeIfAbsent(name, this::createLogger);
}
/**
* Actually creates the logger for the given name.
*/
protected Logger createLogger(String name) {
return new SimpleLogger(name);
}
/**
* Clear the internal logger cache.
*
* This method is intended to be called by classes (in the same package) for
* testing purposes. This method is internal. It can be modified, renamed or
* removed at any time without notice.
* This method is intended to be called by classes (in the same package or
* subclasses) for testing purposes. This method is internal. It can be
* modified, renamed or removed at any time without notice.
*
* You are strongly discouraged from calling this method in production code.
*/
void reset() {
protected void reset() {
loggerMap.clear();
}
}

View File

@ -1,4 +1,6 @@
module org.slf4j.simple {
module org.slf4j.simple {
requires org.slf4j;
provides org.slf4j.spi.SLF4JServiceProvider with org.slf4j.simple.SimpleServiceProvider;
exports org.slf4j.simple;
opens org.slf4j.simple to org.slf4j;
}

View File

@ -0,0 +1,50 @@
package org.slf4j.simple;
import org.junit.Ignore;
import org.slf4j.Logger;
import org.slf4j.event.Level;
import java.io.PrintStream;
@Ignore
public class AcceptanceTest extends LoggerTestSuite {
@Override
public Logger createLogger(ListAppendingOutputStream outputStream, Level level) {
SimpleLogger.CONFIG_PARAMS.outputChoice = new OutputChoice(new PrintStream(outputStream));
SimpleLogger logger = new SimpleLogger("TestSuiteLogger");
logger.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(level.toString());
return logger;
}
@Override
public String extractMessage(String message) {
return message
.split("\n")[0]
.split("- ")[1];
}
@Override
public String extractExceptionMessage(String message) {
String[] logLines = message.split("\n");
if (logLines.length < 2) {
return null;
}
String exceptionLine = logLines[1];
return exceptionLine.split(": ")[1];
}
@Override
public String extractExceptionType(String message) {
String[] logLines = message.split("\n");
if (logLines.length < 2) {
return null;
}
String exceptionLine = logLines[1];
return exceptionLine.split(": ")[0];
}
}

View File

@ -0,0 +1,274 @@
package org.slf4j.simple;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.event.Level;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public abstract class LoggerTestSuite {
public static class ListAppendingOutputStream extends OutputStream {
private final StringBuilder word = new StringBuilder();
private int index = 0;
private final List<String> list;
private ListAppendingOutputStream(List<String> list) {this.list = list;}
@Override
public void write(int b) throws IOException {
word.append((char) b);
}
@Override
public void flush() {
list.add(word.toString());
word.delete(0, word.length());
index++;
}
}
private ListAppendingOutputStream prepareSink(List<String> source) {
return new ListAppendingOutputStream(source);
}
@Test
public void testTrace() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.TRACE);
assertTrue("Trace level should be enabled for this test", configuredLogger.isTraceEnabled());
configuredLogger.trace("Simple trace message");
assertEquals("Trace message should've been captured", 1, loggingEvents.size());
assertTrue("Message should be logged in trace level", isTraceMessage(loggingEvents.get(0)));
assertEquals("Supplied trace message wasn't found in the log",
"Simple trace message",
extractMessage(loggingEvents.get(0)));
loggingEvents.clear();
configuredLogger.debug("Simple debug message");
configuredLogger.info("Simple info message");
configuredLogger.warn("Simple warn message");
configuredLogger.error("Simple error message");
assertEquals("The other levels should have been captured", 4, loggingEvents.size());
}
@Test
public void testDebug() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.DEBUG);
configuredLogger.trace("Simple trace message");
assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
assertTrue("Debug level should be enabled for this test", configuredLogger.isDebugEnabled());
configuredLogger.debug("Simple debug message");
assertEquals("Debug message should've been captured", 1, loggingEvents.size());
assertTrue("Message should be logged in debug level", isDebugMessage(loggingEvents.get(0)));
assertEquals("Supplied debug message wasn't found in the log",
"Simple debug message",
extractMessage(loggingEvents.get(0)));
loggingEvents.clear();
configuredLogger.info("Simple info message");
configuredLogger.warn("Simple warn message");
configuredLogger.error("Simple error message");
assertEquals("The other levels should have been captured", 3, loggingEvents.size());
}
@Test
public void testInfo() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
configuredLogger.trace("Simple trace message");
configuredLogger.debug("Simple debug message");
assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
assertTrue("Info level should be enabled for this test", configuredLogger.isInfoEnabled());
configuredLogger.info("Simple info message");
assertEquals("Info message should've been captured", 1, loggingEvents.size());
assertTrue("Message should be logged in debug level", isInfoMessage(loggingEvents.get(0)));
assertEquals("Supplied info message wasn't found in the log",
"Simple info message",
extractMessage(loggingEvents.get(0)));
loggingEvents.clear();
configuredLogger.warn("Simple warn message");
configuredLogger.error("Simple error message");
assertEquals("The other levels should have been captured", 2, loggingEvents.size());
}
@Test
public void testWarn() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.WARN);
configuredLogger.trace("Simple trace message");
configuredLogger.debug("Simple debug message");
configuredLogger.info("Simple info message");
assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
assertTrue("Warn level should be enabled for this test", configuredLogger.isWarnEnabled());
configuredLogger.warn("Simple warn message");
assertEquals("Warn message should've been captured", 1, loggingEvents.size());
assertTrue("Message should be logged in warn level", isWarnMessage(loggingEvents.get(0)));
assertEquals("Supplied warn message wasn't found in the log",
"Simple warn message",
extractMessage(loggingEvents.get(0)));
loggingEvents.clear();
configuredLogger.error("Simple error message");
assertEquals("The other levels should have been captured", 1, loggingEvents.size());
}
@Test
public void testError() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.ERROR);
configuredLogger.trace("Simple trace message");
configuredLogger.debug("Simple debug message");
configuredLogger.info("Simple info message");
configuredLogger.warn("Simple warn message");
assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
assertTrue("Error level should be enabled for this test", configuredLogger.isErrorEnabled());
configuredLogger.error("Simple error message");
assertEquals("Error message should've been captured", 1, loggingEvents.size());
assertTrue("Message should be logged in error level", isErrorMessage(loggingEvents.get(0)));
assertEquals("Supplied error message wasn't found in the log",
"Simple error message",
extractMessage(loggingEvents.get(0)));
}
@Test
public void testFormatting() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
configuredLogger.info("Some {} string", "formatted");
assertEquals("The formatted message should've been captured", 1, loggingEvents.size());
assertEquals("Message should've been formatted", "Some formatted string", extractMessage(loggingEvents.get(0)));
}
@Test
public void testException() {
ArrayList<String> loggingEvents = new ArrayList<>();
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
Exception exception = new RuntimeException("My error");
configuredLogger.info("Logging with an exception", exception);
assertEquals("The formatted message should've been captured", 1, loggingEvents.size());
assertEquals("Message should've been formatted",
"My error",
extractExceptionMessage(loggingEvents.get(0)));
assertEquals("Message should've been formatted",
"java.lang.RuntimeException",
extractExceptionType(loggingEvents.get(0)));
}
/**
* Allows tests to check whether the log message contains a trace message.
* Override if needed.
* @param message String containing the full log message
* @return whether it is a trace message or not
*/
protected boolean isTraceMessage(String message) {
return message.toLowerCase().contains("trace");
}
/**
* Allows tests to check whether the log message contains a debug message.
* Override if needed.
* @param message String containing the full log message
* @return whether it is a debug message or not
*/
protected boolean isDebugMessage(String message) {
return message.toLowerCase().contains("debug");
}
/**
* Allows tests to check whether the log message contains an info message.
* Override if needed.
* @param message String containing the full log message
* @return whether it is an info message or not
*/
protected boolean isInfoMessage(String message) {
return message.toLowerCase().contains("info");
}
/**
* Allows tests to check whether the log message contains a warn message.
* Override if needed.
* @param message String containing the full log message
* @return whether it is a warn message or not
*/
protected boolean isWarnMessage(String message) {
return message.toLowerCase().contains("warn");
}
/**
* Allows tests to check whether the log message contains an error message.
* Override if needed.
* @param message String containing the full log message
* @return whether it is an error message or not
*/
protected boolean isErrorMessage(String message) {
return message.toLowerCase().contains("error");
}
/**
* Extracts only the part of the log string that should represent the `message` string.
* @param message the full log message
* @return only the supplied message
*/
public abstract String extractMessage(String message);
/**
* Extracts only the part of the log string that should represent the supplied exception message, if any.
* @param message the full log message
* @return only the supplied exception message
*/
public abstract String extractExceptionMessage(String message);
/**
* Extracts only the part of the log string that should represent the supplied exception type.
* @param message the full log message
* @return only the supplied exception type name
*/
public abstract String extractExceptionType(String message);
/**
* Configures the logger for running the tests.
* @param outputStream The output stream for logs to be written to
* @param level The expected level the tests will run for this logger
* @return a configured logger able to run the tests
*/
public abstract Logger createLogger(ListAppendingOutputStream outputStream, Level level);
}