mirror of https://github.com/qos-ch/slf4j
Compare commits
35 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
61400453cd | |
|
|
58b66c2c7e | |
|
|
be4841cce8 | |
|
|
d2073bece8 | |
|
|
32a9854cf4 | |
|
|
77936c6f1f | |
|
|
34c9d30af5 | |
|
|
902b463957 | |
|
|
b3c2f16f12 | |
|
|
9468c7a28f | |
|
|
183aaa5070 | |
|
|
c233ea1932 | |
|
|
4b4d533771 | |
|
|
9349d64f95 | |
|
|
0def25ebfa | |
|
|
69c333de28 | |
|
|
2470fad4fd | |
|
|
c2c29fec98 | |
|
|
0597225b5b | |
|
|
f7b34c2e60 | |
|
|
4fa92fc007 | |
|
|
101086ba35 | |
|
|
8ae0efca23 | |
|
|
3ff00870b3 | |
|
|
0df43e9e53 | |
|
|
46b5ea54a6 | |
|
|
5321a975d4 | |
|
|
09111e8c1e | |
|
|
6a04f67fdd | |
|
|
03aa6b915a | |
|
|
7c3b0ef011 | |
|
|
42810107b0 | |
|
|
982e4b067f | |
|
|
dd4486b5c5 | |
|
|
1d82519b07 |
39
README.md
39
README.md
|
|
@ -2,31 +2,33 @@
|
|||
|
||||
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.
|
||||
logback, reload4j, log4j 2.x, logevents, penna, rainbowgum, tinylog)
|
||||
allowing the end user to plug in the desired logging framework at
|
||||
deployment time.
|
||||
|
||||
More information can be found on the [SLF4J website](http://www.slf4j.org).
|
||||
|
||||
# Build Status
|
||||
[](https://travis-ci.org/qos-ch/slf4j)
|
||||
|
||||
# Search org.slf4j artifacts on Maven Central
|
||||
[](https://search.maven.org/search?q=g:org.slf4j%20AND%20v:2.0.%3F)
|
||||
[](https://central.sonatype.com/search?namespace=org.slf4j)
|
||||
|
||||
|
||||
# In case of problems
|
||||
|
||||
In case of problems please do not hesitate to post an e-mail message
|
||||
on the slf4j-user@qos.ch 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.
|
||||
on the [slf4j-user@qos.ch](https://mailman.qos.ch/cgi-bin/mailman/listinfo/slf4j-user)
|
||||
mailing list or to start a <a
|
||||
href="https://github.com/qos-ch/slf4j/discussions">discussion</a> on
|
||||
github. 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](https://github.com/sponsors/qos-ch/sponsorships?tier_id=77436).
|
||||
In principle, most championed issues are solved within 3 business days ensued by a release.
|
||||
For urgent issues do not hesitate to [champion a
|
||||
release](https://github.com/sponsors/qos-ch/sponsorships?tier_id=77436).
|
||||
In principle, most championed issues are solved within 3 business days
|
||||
ensued by a release.
|
||||
|
||||
# How to build SLF4J
|
||||
|
||||
|
|
@ -43,14 +45,13 @@ process:
|
|||
1. Start a discussion on the [slf4j-dev mailing
|
||||
list](http://www.slf4j.org/mailing-lists.html) about your proposed
|
||||
change. Alternately, file a [bug
|
||||
report](http://www.slf4j.org/bug-reporting.html) to initiate the
|
||||
discussion. Note that we ask pull requests to be linked to a [Jira
|
||||
ticket](https://jira.qos.ch/).
|
||||
report](https://github.com/qos-ch/slf4j/issues) on github to initiate the
|
||||
discussion.
|
||||
|
||||
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
|
||||
3. Make your changes on the branch 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.
|
||||
|
||||
|
|
@ -61,10 +62,8 @@ will be automatically rejected by the [DCO GitHub
|
|||
check](https://probot.github.io/apps/dco/) 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
|
||||
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?
|
||||
|
|
|
|||
|
|
@ -82,12 +82,12 @@
|
|||
</target>
|
||||
|
||||
<target name="testAll" depends="init,
|
||||
testNoProvider150,
|
||||
testNoProvider150,
|
||||
testMismatch,
|
||||
testMatch,
|
||||
testMultiBinding,
|
||||
testFuture_16Series,
|
||||
testActiveSecurityManager">
|
||||
testMultiBinding,
|
||||
testFuture_16Series"
|
||||
>
|
||||
</target>
|
||||
|
||||
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
<property name="path_to_policy" value="file:./src/policy/java-under-ant.policy"/>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- no longer supported in JDK 24 and later -->
|
||||
<target name="testActiveSecurityManager" depends="setPathToPolicy_FromTop, setPathToPolicy_FromIntegration">
|
||||
<junit printsummary="yes" fork="no" haltonfailure="yes">
|
||||
<jvmarg value="-Djava.security.manager"/>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ package org.slf4j;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.slf4j.helpers.Reporter.SLF4J_INTERNAL_VERBOSITY_KEY;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Random;
|
||||
|
|
@ -43,11 +44,13 @@ public class CompatibilityAssertionTest {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.setProperty(SLF4J_INTERNAL_VERBOSITY_KEY, "debug");
|
||||
System.setErr(sps);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.clearProperty(SLF4J_INTERNAL_VERBOSITY_KEY);
|
||||
System.setErr(old);
|
||||
}
|
||||
|
||||
|
|
@ -56,9 +59,13 @@ public class CompatibilityAssertionTest {
|
|||
Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
String msg = "hello world " + diff;
|
||||
logger.info(msg);
|
||||
assertEquals(1, sps.stringList.size());
|
||||
assertEquals(2, sps.stringList.size());
|
||||
|
||||
String s0 = (String) sps.stringList.get(0);
|
||||
assertTrue(s0.contains(msg));
|
||||
assertTrue(s0.startsWith("SLF4J(D): Connected with provider of type [org.slf4j.simple.SimpleServiceProvider]"));
|
||||
|
||||
String s1 = (String) sps.stringList.get(1);
|
||||
assertTrue(s1.contains(msg));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,11 +55,13 @@ public class MultiBindingAssertionTest {
|
|||
String msg = "hello world " + diff;
|
||||
logger.info(msg);
|
||||
List<String> list = sps.stringList;
|
||||
assertMsgContains(list, 0, "Class path contains multiple SLF4J providers.");
|
||||
assertMsgContains(list, 1, "Found provider");
|
||||
assertMsgContains(list, 2, "Found provider");
|
||||
assertMsgContains(list, 3, "See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.");
|
||||
assertMsgContains(list, 4, "Actual provider is of type [");
|
||||
int line = 0;
|
||||
|
||||
assertMsgContains(list, line++, "Class path contains multiple SLF4J providers.");
|
||||
assertMsgContains(list, line++, "Found provider");
|
||||
assertMsgContains(list, line++, "Found provider");
|
||||
assertMsgContains(list, line++, "See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.");
|
||||
//assertMsgContains(list, line++, "SLF4J(D): Connected with provider of type [");
|
||||
}
|
||||
|
||||
void assertMsgContains(List<String> strList, int index, String msg) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<name>Apache-2.0</name>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,137 +0,0 @@
|
|||
<project name="testing-log4j-bridge" default="usage" basedir=".">
|
||||
|
||||
<property name="lbversion" value="0.9.8-SNAPSHOT" />
|
||||
<property name="slf4jversion" value="1.4.2" />
|
||||
<property name="source.home" value="./src/main/java/" />
|
||||
<property name="javac.dest.12" value="./target/classes12/" />
|
||||
<property name="javac.dest.13" value="./target/classes13/" />
|
||||
<property name="lib" value="./lib" />
|
||||
|
||||
<property name="deprecation" value="on" />
|
||||
|
||||
<path id="basic.classpath">
|
||||
<pathelement location="${source.home}" />
|
||||
<pathelement location="${lib}/junit-3.8.1.jar" />
|
||||
</path>
|
||||
|
||||
<path id="log4j12.classpath">
|
||||
<path refid="basic.classpath" />
|
||||
<pathelement location="${javac.dest.12}" />
|
||||
<pathelement location="${lib}/log4j-1.2.14.jar" />
|
||||
</path>
|
||||
|
||||
<path id="log4j13.classpath">
|
||||
<path refid="basic.classpath" />
|
||||
<pathelement location="${javac.dest.13}" />
|
||||
<pathelement location="${lib}/log4j-1.3alpha-8.jar" />
|
||||
</path>
|
||||
|
||||
<path id="los.classpath">
|
||||
<path refid="basic.classpath" />
|
||||
<pathelement location="${lib}/log4j-over-slf4j-${slf4jversion}.jar" />
|
||||
<pathelement location="${lib}/logback-classic-${lbversion}.jar" />
|
||||
<pathelement location="${lib}/logback-core-${lbversion}.jar" />
|
||||
<pathelement location="${lib}/slf4j-api-${slf4jversion}.jar" />
|
||||
</path>
|
||||
|
||||
<!-- ================================================================= -->
|
||||
<!-- Default target -->
|
||||
<!-- ================================================================= -->
|
||||
<target name="usage">
|
||||
<echo>
|
||||
These are some of the targets supported by this ANT build script:
|
||||
|
||||
all - run all available tests
|
||||
refresh - copy required jar files to the lib directory
|
||||
</echo>
|
||||
</target>
|
||||
|
||||
<delete>
|
||||
<fileset dir="." includes="**/*.bak"/>
|
||||
</delete>
|
||||
|
||||
<target name="refresh">
|
||||
<delete>
|
||||
<fileset dir="lib">
|
||||
<include name="logback-*.jar"/>
|
||||
<include name="log4j-bridge-*.jar"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
<copy file="../../slf4j-api/target/slf4j-api-${slf4jversion}.jar" todir="lib/"/>
|
||||
<copy file="../target/log4j-over-slf4j-${slf4jversion}.jar" todir="lib/"/>
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${javac.dest.12}" />
|
||||
<mkdir dir="${javac.dest.13}" />
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete>
|
||||
<fileset dir="${javac.dest.12}" includes="**" />
|
||||
<fileset dir="${javac.dest.13}" includes="**" />
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="build_log4j12" depends="init">
|
||||
<javac srcdir="${source.home}"
|
||||
destdir="${javac.dest.12}"
|
||||
includes="**/Log4j12Calls.java"
|
||||
deprecation="${deprecation}" debug="on">
|
||||
<classpath refid="log4j12.classpath" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="build_log4j13" depends="init">
|
||||
<javac srcdir="${source.home}"
|
||||
destdir="${javac.dest.13}"
|
||||
includes="**/Log4j13Calls.java" deprecation="${deprecation}" debug="on">
|
||||
<classpath refid="log4j13.classpath" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="build_loggerTest" depends="init">
|
||||
<javac srcdir="${source.home}"
|
||||
destdir="${javac.dest.12}"
|
||||
includes="**/LoggerTest.java"
|
||||
deprecation="${deprecation}" debug="on">
|
||||
<classpath refid="los.classpath" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<!-- ================================================================= -->
|
||||
<!-- Run tests -->
|
||||
<!-- ================================================================= -->
|
||||
<target name="all" depends="test12, test13, loggerTest" />
|
||||
|
||||
|
||||
<target name="loggerTest" depends="build_loggerTest">
|
||||
<junit printsummary="yes" fork="yes" haltonfailure="yes">
|
||||
<classpath refid="los.classpath" />
|
||||
<classpath location="${javac.dest.12}" />
|
||||
<formatter type="plain" usefile="false" />
|
||||
<test name="test.LoggerTest" />
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
<target name="test12" depends="build_log4j12">
|
||||
<junit printsummary="yes" fork="yes" haltonfailure="yes">
|
||||
<classpath refid="los.classpath" />
|
||||
<classpath location="${javac.dest.12}" />
|
||||
<formatter type="plain" usefile="false" />
|
||||
<test name="test.Log4j12Calls" />
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
<target name="test13" depends="build_log4j13">
|
||||
<junit printsummary="yes" fork="yes" haltonfailure="yes">
|
||||
<classpath refid="los.classpath" />
|
||||
<classpath location="${javac.dest.13}" />
|
||||
<formatter type="plain" usefile="false" />
|
||||
<test name="test.Log4j13Calls" />
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
This directory is used to test the module against various log4j calls.
|
||||
Two test cases simulate the typical calls that one can find in an application
|
||||
that uses either log4j 1.2.x, or log4j 1.3.x.
|
||||
|
||||
In the same directory is a build.xml file that uses ant to
|
||||
compile the test cases with the corresponding log4j version,
|
||||
and to run these tests without log4j in the classpath but with
|
||||
logback jars instead.
|
||||
|
||||
To run the tests, one must have ant installed. Issuing the following command,
|
||||
once in the compatibility directory will launch the tests:
|
||||
|
||||
ant all
|
||||
|
||||
To obtain more information about the use of the log4j-over-slf4j module,
|
||||
please visit http://www.slf4j.org/log4j-over-slf4j.html
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package test;
|
||||
|
||||
public class DummyObject {
|
||||
|
||||
public String toString() {
|
||||
return "dummy";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/**
|
||||
* Logback: the reliable, generic, fast and flexible logging framework.
|
||||
*
|
||||
* Copyright (C) 1999-2006, QOS.ch
|
||||
*
|
||||
* This library is free software, you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation.
|
||||
*/
|
||||
package test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.MDC;
|
||||
|
||||
/**
|
||||
*
|
||||
* A test case that issues the typical calls
|
||||
* that an application using log4j 1.2 would do.
|
||||
*
|
||||
* @author Ceki Gülcü
|
||||
* @author Sébastien Pennec
|
||||
*/
|
||||
public class Log4j12Calls extends TestCase {
|
||||
public static final Logger logger = Logger.getLogger(Log4j12Calls.class);
|
||||
|
||||
public void testLog() {
|
||||
MDC.put("key", "value1");
|
||||
|
||||
logger.trace("Trace level can be noisy");
|
||||
logger.debug("Entering application");
|
||||
logger.info("Violets are blue");
|
||||
logger.warn("Here is a warning");
|
||||
logger.error("Exiting application", new Exception("just testing"));
|
||||
|
||||
MDC.remove("key");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
* Logback: the reliable, generic, fast and flexible logging framework.
|
||||
*
|
||||
* Copyright (C) 1999-2006, QOS.ch
|
||||
*
|
||||
* This library is free software, you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation.
|
||||
*/
|
||||
|
||||
package test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.MDC;
|
||||
|
||||
/**
|
||||
*
|
||||
* A test case that issues the typical calls
|
||||
* that an application using log4j 1.3 would do.
|
||||
*
|
||||
* @author Ceki Gülcü
|
||||
* @author Sébastien Pennec
|
||||
*/
|
||||
|
||||
public class Log4j13Calls extends TestCase {
|
||||
public static final Logger logger = Logger.getLogger(Log4j12Calls.class);
|
||||
|
||||
public void testLog() {
|
||||
MDC.put("key", "value1");
|
||||
|
||||
logger.trace("Trace level can be noisy");
|
||||
logger.debug("Entering application");
|
||||
logger.info("Violets are blue");
|
||||
logger.warn("Here is a warning");
|
||||
logger.info("The answer is {}.", new Integer(42));
|
||||
logger.info("Number: {} and another one: {}.", new Integer(42), new Integer(24));
|
||||
|
||||
logger.error("Exiting application", new Exception("just testing"));
|
||||
|
||||
MDC.remove("key");
|
||||
|
||||
MDC.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
package test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
import ch.qos.logback.core.read.ListAppender;
|
||||
import org.apache.log4j.Level;
|
||||
|
||||
/**
|
||||
* A class that tests the invocation of the org.apache.log4j.Logger class that
|
||||
* belongs to the log4j-bridge package
|
||||
*
|
||||
* @author Sébastien Pennec
|
||||
* @author Ceki Gülcü
|
||||
*/
|
||||
|
||||
public class LoggerTest extends TestCase {
|
||||
|
||||
LoggerContext context;
|
||||
ListAppender<LoggingEvent> appender;
|
||||
ch.qos.logback.classic.Logger logbackLogger;
|
||||
org.apache.log4j.Logger log4jLogger;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
context.shutdownAndReset();
|
||||
appender = new ListAppender<LoggingEvent>();
|
||||
appender.setContext(context);
|
||||
appender.setName("listAppender");
|
||||
appender.start();
|
||||
ch.qos.logback.classic.Logger lbLogger = context
|
||||
.getLogger(LoggerContext.ROOT_NAME);
|
||||
lbLogger.addAppender(appender);
|
||||
|
||||
log4jLogger = org.apache.log4j.Logger.getLogger(LoggerTest.class);
|
||||
logbackLogger = context.getLogger(LoggerTest.class);
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
appender.stop();
|
||||
context.stop();
|
||||
appender = null;
|
||||
context = null;
|
||||
logbackLogger = null;
|
||||
log4jLogger = null;
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testLogWithObjectMessages() {
|
||||
LoggingEvent event;
|
||||
|
||||
log4jLogger.debug("test");
|
||||
event = appender.list.get(0);
|
||||
assertEquals("test", event.getMessage());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.debug(null);
|
||||
event = appender.list.get(0);
|
||||
assertEquals(null, event.getMessage());
|
||||
appender.list.clear();
|
||||
|
||||
DummyObject dummy = new DummyObject();
|
||||
log4jLogger.debug(dummy);
|
||||
event = appender.list.get(0);
|
||||
assertEquals(dummy.toString(), event.getMessage());
|
||||
appender.list.clear();
|
||||
}
|
||||
|
||||
public void testIsEnabledAPI() {
|
||||
assertFalse(log4jLogger.isTraceEnabled());
|
||||
assertTrue(log4jLogger.isDebugEnabled());
|
||||
assertTrue(log4jLogger.isInfoEnabled());
|
||||
assertTrue(log4jLogger.isWarnEnabled());
|
||||
assertTrue(log4jLogger.isErrorEnabled());
|
||||
}
|
||||
|
||||
public void testPrintAPI() {
|
||||
Exception e = new Exception("just testing");
|
||||
|
||||
log4jLogger.trace(null);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.debug(null);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.debug("debug message");
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.info(null);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.info("info message");
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.warn(null);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.warn("warn message");
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.error(null);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.error("error message");
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.debug(null, e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.debug("debug message", e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.info(null, e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.info("info message", e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.warn(null, e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.warn("warn message", e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.error(null, e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
log4jLogger.error("error message", e);
|
||||
assertEquals(1, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
}
|
||||
|
||||
public void testLogAPI() {
|
||||
log4jLogger.log("x", Level.TRACE, "x", null);
|
||||
assertEquals(0, appender.list.size());
|
||||
|
||||
log4jLogger.log("x", Level.DEBUG, "x", null);
|
||||
log4jLogger.log("x", Level.INFO, "x", null);
|
||||
log4jLogger.log("x", Level.WARN, "x", null);
|
||||
log4jLogger.log("x", Level.ERROR, "x", null);
|
||||
log4jLogger.log("x", Level.FATAL, "x", null);
|
||||
|
||||
assertEquals(5, appender.list.size());
|
||||
appender.list.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache Software Licenses</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<name>Apache-2.0</name>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-bom</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<properties>
|
||||
<!-- yyyy-MM-dd'T'HH:mm:ss'Z' -->
|
||||
<project.build.outputTimestamp>2024-04-12T14:20:00Z</project.build.outputTimestamp>
|
||||
<project.build.outputTimestamp>2026-05-12T18:37:04Z</project.build.outputTimestamp>
|
||||
<latest.1.version>1.7.36</latest.1.version>
|
||||
<!-- java.util.ServiceLoader requires Java 6 -->
|
||||
<jdk.version>8</jdk.version>
|
||||
|
|
|
|||
23
pom.xml
23
pom.xml
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-bom</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<url>http://www.slf4j.org</url>
|
||||
|
|
@ -16,12 +16,13 @@
|
|||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>http://www.opensource.org/licenses/mit-license.php</url>
|
||||
<name>MIT</name>
|
||||
<url>https://opensource.org/license/mit</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/qos-ch/slf4j</url>
|
||||
<connection>scm:git:https://github.com/qos-ch/slf4j.git</connection>
|
||||
|
|
@ -48,6 +49,10 @@
|
|||
<module>slf4j-migrator</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<central-publishing-maven-plugin.version>0.9.0</central-publishing-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
|
|
@ -218,6 +223,18 @@
|
|||
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.sonatype.central</groupId>
|
||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||
<version>${central-publishing-maven-plugin.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<publishingServerId>central</publishingServerId>
|
||||
<excludeArtifacts>integration</excludeArtifacts>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,9 @@ echoRunAndCheck "$MVN install"
|
|||
|
||||
if [ ! -z "$PASS" ]
|
||||
then
|
||||
export GPG_TTY=$(tty)
|
||||
echoRunAndCheck "$MVN deploy -P javadocjar,sign-artifacts"
|
||||
# WARNING deploying without cleaning may leave stale MANIFEST files
|
||||
export GPG_TTY=$(tty)
|
||||
echoRunAndCheck "$MVN deploy -P javadocjar,sign-artifacts"
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ import org.slf4j.helpers.Reporter;
|
|||
import org.slf4j.helpers.SubstituteLogger;
|
||||
import org.slf4j.helpers.SubstituteServiceProvider;
|
||||
import org.slf4j.helpers.Util;
|
||||
import org.slf4j.spi.MDCAdapter;
|
||||
import org.slf4j.spi.SLF4JServiceProvider;
|
||||
|
||||
/**
|
||||
|
|
@ -82,6 +83,9 @@ public final class LoggerFactory {
|
|||
static final String UNSUCCESSFUL_INIT_URL = CODES_PREFIX + "#unsuccessfulInit";
|
||||
static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also "
|
||||
+ UNSUCCESSFUL_INIT_URL;
|
||||
|
||||
static final String CONNECTED_WITH_MSG = "Connected with provider of type [";
|
||||
|
||||
/**
|
||||
* System property for explicitly setting the provider class. If set and the provider could be instantiated,
|
||||
* then the service loading mechanism will be bypassed.
|
||||
|
|
@ -192,6 +196,7 @@ public final class LoggerFactory {
|
|||
reportMultipleBindingAmbiguity(providersList);
|
||||
if (providersList != null && !providersList.isEmpty()) {
|
||||
PROVIDER = providersList.get(0);
|
||||
earlyBindMDCAdapter();
|
||||
// SLF4JServiceProvider.initialize() is intended to be called here and nowhere else.
|
||||
PROVIDER.initialize();
|
||||
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
|
||||
|
|
@ -212,6 +217,19 @@ public final class LoggerFactory {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of PROVIDER.getMDCAdapter() can be null while PROVIDER has not yet initialized.
|
||||
*
|
||||
* However, SLF4JServiceProvider implementations are expected to initialize their internal
|
||||
* MDCAdapter field in their constructor or on field declaration.
|
||||
*/
|
||||
private static void earlyBindMDCAdapter() {
|
||||
MDCAdapter mdcAdapter = PROVIDER.getMDCAdapter();
|
||||
if(mdcAdapter != null) {
|
||||
MDC.setMDCAdapter(mdcAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
static SLF4JServiceProvider loadExplicitlySpecified(ClassLoader classLoader) {
|
||||
String explicitlySpecified = System.getProperty(PROVIDER_PROPERTY_KEY);
|
||||
if (null == explicitlySpecified || explicitlySpecified.isEmpty()) {
|
||||
|
|
@ -403,9 +421,16 @@ public final class LoggerFactory {
|
|||
}
|
||||
|
||||
private static void reportActualBinding(List<SLF4JServiceProvider> providerList) {
|
||||
// binderPathSet can be null under Android
|
||||
if (!providerList.isEmpty() && isAmbiguousProviderList(providerList)) {
|
||||
// impossible since a provider has been found
|
||||
if (providerList.isEmpty()) {
|
||||
throw new IllegalStateException("No providers were found which is impossible after successful initialization.");
|
||||
}
|
||||
|
||||
if (isAmbiguousProviderList(providerList)) {
|
||||
Reporter.info("Actual provider is of type [" + providerList.get(0) + "]");
|
||||
} else {
|
||||
SLF4JServiceProvider provider = providerList.get(0);
|
||||
Reporter.debug(CONNECTED_WITH_MSG + provider.getClass().getName() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,7 @@ import java.io.Closeable;
|
|||
import java.util.Deque;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.helpers.BasicMDCAdapter;
|
||||
import org.slf4j.helpers.NOPMDCAdapter;
|
||||
import org.slf4j.helpers.Reporter;
|
||||
import org.slf4j.helpers.Util;
|
||||
import org.slf4j.helpers.*;
|
||||
import org.slf4j.spi.MDCAdapter;
|
||||
import org.slf4j.spi.SLF4JServiceProvider;
|
||||
|
||||
|
|
@ -66,9 +63,9 @@ import org.slf4j.spi.SLF4JServiceProvider;
|
|||
public class MDC {
|
||||
|
||||
static final String NULL_MDCA_URL = "http://www.slf4j.org/codes.html#null_MDCA";
|
||||
private static final String MDC_APAPTER_CANNOT_BE_NULL_MESSAGE = "MDCAdapter cannot be null. See also " + NULL_MDCA_URL;
|
||||
private static final String MDC_ADAPTER_CANNOT_BE_NULL_MESSAGE = "MDCAdapter cannot be null. See also " + NULL_MDCA_URL;
|
||||
static final String NO_STATIC_MDC_BINDER_URL = "http://www.slf4j.org/codes.html#no_static_mdc_binder";
|
||||
static MDCAdapter mdcAdapter;
|
||||
static MDCAdapter MDC_ADAPTER;
|
||||
|
||||
/**
|
||||
* An adapter to remove the key when done.
|
||||
|
|
@ -88,17 +85,30 @@ public class MDC {
|
|||
private MDC() {
|
||||
}
|
||||
|
||||
static {
|
||||
private static MDCAdapter getMDCAdapterGivenByProvider() {
|
||||
SLF4JServiceProvider provider = LoggerFactory.getProvider();
|
||||
if (provider != null) {
|
||||
if(provider != null) {
|
||||
// If you wish to change the mdc adapter, setting the MDC.MDCAdapter variable might be insufficient.
|
||||
// Keep in mind that the provider *might* perform additional internal mdcAdapter assignments that
|
||||
// you would also need to replicate/adapt.
|
||||
|
||||
// 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();
|
||||
|
||||
final MDCAdapter anAdapter = provider.getMDCAdapter();
|
||||
emitTemporaryMDCAdapterWarningIfNeeded(provider);
|
||||
return anAdapter;
|
||||
} else {
|
||||
Reporter.error("Failed to find provider.");
|
||||
Reporter.error("Defaulting to no-operation MDCAdapter implementation.");
|
||||
mdcAdapter = new NOPMDCAdapter();
|
||||
return new NOPMDCAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
private static void emitTemporaryMDCAdapterWarningIfNeeded(SLF4JServiceProvider provider) {
|
||||
boolean isSubstitute = provider instanceof SubstituteServiceProvider;
|
||||
if(isSubstitute) {
|
||||
Reporter.info("Temporary mdcAdapter given by SubstituteServiceProvider.");
|
||||
Reporter.info("This mdcAdapter will be replaced after backend initialization has completed.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,10 +131,10 @@ public class MDC {
|
|||
if (key == null) {
|
||||
throw new IllegalArgumentException("key parameter cannot be null");
|
||||
}
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
if (getMDCAdapter() == null) {
|
||||
throw new IllegalStateException(MDC_ADAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.put(key, val);
|
||||
getMDCAdapter().put(key, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -177,10 +187,8 @@ public class MDC {
|
|||
throw new IllegalArgumentException("key parameter cannot be null");
|
||||
}
|
||||
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.get(key);
|
||||
mdcAdapterNullCheck();
|
||||
return getMDCAdapter().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,20 +206,16 @@ public class MDC {
|
|||
throw new IllegalArgumentException("key parameter cannot be null");
|
||||
}
|
||||
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.remove(key);
|
||||
mdcAdapterNullCheck();
|
||||
getMDCAdapter().remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all entries in the MDC of the underlying implementation.
|
||||
*/
|
||||
public static void clear() {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.clear();
|
||||
mdcAdapterNullCheck();
|
||||
getMDCAdapter().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -222,10 +226,8 @@ public class MDC {
|
|||
* @since 1.5.1
|
||||
*/
|
||||
public static Map<String, String> getCopyOfContextMap() {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.getCopyOfContextMap();
|
||||
mdcAdapterNullCheck();
|
||||
return getMDCAdapter().getCopyOfContextMap();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -240,23 +242,38 @@ public class MDC {
|
|||
* @since 1.5.1
|
||||
*/
|
||||
public static void setContextMap(Map<String, String> contextMap) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.setContextMap(contextMap);
|
||||
mdcAdapterNullCheck();
|
||||
getMDCAdapter().setContextMap(contextMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MDCAdapter instance currently in use.
|
||||
*
|
||||
*
|
||||
* Since 2.0.17, if the MDCAdapter instance is null, then this method set it to use
|
||||
* the adapter returned by the SLF4JProvider. However, in the vast majority of cases
|
||||
* the MDCAdapter will be set earlier (during initialization) by {@link LoggerFactory}.
|
||||
*
|
||||
* @return the MDcAdapter instance currently in use.
|
||||
* @since 1.4.2
|
||||
*/
|
||||
public static MDCAdapter getMDCAdapter() {
|
||||
return mdcAdapter;
|
||||
if(MDC_ADAPTER == null) {
|
||||
MDC_ADAPTER = getMDCAdapterGivenByProvider();
|
||||
}
|
||||
return MDC_ADAPTER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set MDCAdapter instance to use.
|
||||
*
|
||||
* @since 2.0.17
|
||||
*/
|
||||
static void setMDCAdapter(MDCAdapter anMDCAdapter) {
|
||||
if(anMDCAdapter == null) {
|
||||
throw new IllegalStateException(MDC_ADAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
MDC_ADAPTER = anMDCAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a value into the deque(stack) referenced by 'key'.
|
||||
|
|
@ -266,28 +283,24 @@ public class MDC {
|
|||
* @since 2.0.0
|
||||
*/
|
||||
static public void pushByKey(String key, String value) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.pushByKey(key, value);
|
||||
mdcAdapterNullCheck();
|
||||
getMDCAdapter().pushByKey(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the stack referenced by 'key' and return the value possibly null.
|
||||
* Pop the <b>stack</b> referenced by 'key' and return the value possibly null.
|
||||
*
|
||||
* @param key identifies the deque(stack)
|
||||
* @return the value just popped. May be null/
|
||||
* @since 2.0.0
|
||||
*/
|
||||
static public String popByKey(String key) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.popByKey(key);
|
||||
mdcAdapterNullCheck();
|
||||
return getMDCAdapter().popByKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the deque(stack) referenced by 'key'. May be null.
|
||||
* Returns a copy of the <b>deque(stack)</b> referenced by 'key'. May be null.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
* @return copy of stack referenced by 'key'. May be null.
|
||||
|
|
@ -295,9 +308,13 @@ public class MDC {
|
|||
* @since 2.0.0
|
||||
*/
|
||||
public Deque<String> getCopyOfDequeByKey(String key) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
mdcAdapterNullCheck();
|
||||
return getMDCAdapter().getCopyOfDequeByKey(key);
|
||||
}
|
||||
|
||||
private static void mdcAdapterNullCheck() {
|
||||
if (getMDCAdapter() == null) {
|
||||
throw new IllegalStateException(MDC_ADAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.getCopyOfDequeByKey(key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ package org.slf4j.helpers;
|
|||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* An internally used class for reporting internal messages generated by SLF4J itself during initialization.
|
||||
* An internally used class for reporting internal messages generated by SLF4J itself, typically
|
||||
* during initialization.
|
||||
*
|
||||
* <p>
|
||||
* Internal reporting is performed by calling the {@link #info(String)}, {@link #warn(String)} (String)}
|
||||
* {@link #error(String)} (String)} and {@link #error(String, Throwable)} methods.
|
||||
* Internal reporting is performed by calling the {@link #debug(String)}, {@link #info(String)},
|
||||
* {@link #warn(String)} (String)} {@link #error(String)} (String)} and
|
||||
* {@link #error(String, Throwable)} methods.
|
||||
* </p>
|
||||
* <p>See {@link #SLF4J_INTERNAL_VERBOSITY_KEY} and {@link #SLF4J_INTERNAL_REPORT_STREAM_KEY} for
|
||||
* configuration options.</p>
|
||||
|
|
@ -23,7 +25,7 @@ public class Reporter {
|
|||
* this class is used internally by Reporter
|
||||
*/
|
||||
private enum Level {
|
||||
INFO(1), WARN(2), ERROR(3);
|
||||
DEBUG(0), INFO(1), WARN(2), ERROR(3);
|
||||
|
||||
int levelInt;
|
||||
|
||||
|
|
@ -40,6 +42,7 @@ public class Reporter {
|
|||
Stderr, Stdout;
|
||||
}
|
||||
|
||||
static final String SLF4J_DEBUG_PREFIX = "SLF4J(D): ";
|
||||
static final String SLF4J_INFO_PREFIX = "SLF4J(I): ";
|
||||
static final String SLF4J_WARN_PREFIX = "SLF4J(W): ";
|
||||
static final String SLF4J_ERROR_PREFIX = "SLF4J(E): ";
|
||||
|
|
@ -62,11 +65,11 @@ public class Reporter {
|
|||
public static final String SLF4J_INTERNAL_VERBOSITY_KEY = "slf4j.internal.verbosity";
|
||||
|
||||
|
||||
static private final TargetChoice TARGET_CHOICE = initTargetChoice();
|
||||
static private final TargetChoice TARGET_CHOICE = getTargetChoice();
|
||||
|
||||
static private final Level INTERNAL_VERBOSITY = initVerbosity();
|
||||
|
||||
static private TargetChoice initTargetChoice() {
|
||||
static private TargetChoice getTargetChoice() {
|
||||
String reportStreamStr = System.getProperty(SLF4J_INTERNAL_REPORT_STREAM_KEY);
|
||||
|
||||
if(reportStreamStr == null || reportStreamStr.isEmpty()) {
|
||||
|
|
@ -88,6 +91,10 @@ public class Reporter {
|
|||
return Level.INFO;
|
||||
}
|
||||
|
||||
if(verbosityStr.equalsIgnoreCase("DEBUG")) {
|
||||
return Level.DEBUG;
|
||||
}
|
||||
|
||||
if(verbosityStr.equalsIgnoreCase("ERROR")) {
|
||||
return Level.ERROR;
|
||||
}
|
||||
|
|
@ -97,6 +104,7 @@ public class Reporter {
|
|||
return Level.WARN;
|
||||
}
|
||||
|
||||
// anything else including verbosityStr.equalsIgnoreCase("INFO")
|
||||
return Level.INFO;
|
||||
}
|
||||
|
||||
|
|
@ -114,13 +122,30 @@ public class Reporter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an internal message of level DEBUG. Message text is prefixed with the string "SLF4J(D)",
|
||||
* with (D) standing as a shorthand for DEBUG.
|
||||
*
|
||||
* <p>Messages of level DEBUG are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY}
|
||||
* system property is set to "DEBUG" and disabled when set to "INFO", "WARN" or "ERROR". By default,
|
||||
* {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is set to "INFO".</p>
|
||||
*
|
||||
* @param msg the message text
|
||||
* @since 2.0.16
|
||||
*/
|
||||
public static void debug(String msg) {
|
||||
if(isEnabledFor(Level.DEBUG)) {
|
||||
getTarget().println(SLF4J_DEBUG_PREFIX + msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an internal message of level INFO. Message text is prefixed with the string "SLF4J(I)", with
|
||||
* (I) standing as a shorthand for INFO.
|
||||
*
|
||||
* <p>Messages of level INFO are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} system property is
|
||||
* set to "INFO" and disabled when set to "WARN" or "ERROR". By default, {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is
|
||||
* set to "INFO".</p>
|
||||
* set to "DEBUG" or "INFO" and disabled when set to "WARN" or "ERROR". By default,
|
||||
* {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is set to "INFO".</p>
|
||||
*
|
||||
* @param msg the message text
|
||||
*/
|
||||
|
|
@ -136,8 +161,8 @@ public class Reporter {
|
|||
* (W) standing as a shorthand for WARN.
|
||||
*
|
||||
* <p>Messages of level WARN are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} system property is
|
||||
* set to "INFO" or "WARN" and disabled when set to "ERROR". By default, {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is
|
||||
* set to "INFO".</p>
|
||||
* set to "DEBUG", "INFO" or "WARN" and disabled when set to "ERROR". By default,
|
||||
* {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is set to "INFO".</p>
|
||||
*
|
||||
* @param msg the message text
|
||||
*/
|
||||
|
|
@ -147,7 +172,6 @@ public class Reporter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Report an internal message of level "ERROR accompanied by a {@link Throwable}.
|
||||
* Message text is prefixed with the string "SLF4J(E)", with (E) standing as a shorthand for ERROR.
|
||||
|
|
@ -164,10 +188,9 @@ public class Reporter {
|
|||
t.printStackTrace(getTarget());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Report an internal message of level "ERROR". Message text is prefixed with the string "SLF4J(E)", with
|
||||
* (E) standing as a shorthand for ERROR.
|
||||
* Report an internal message of level "ERROR". Message text is prefixed with the string "SLF4J(E)",
|
||||
* with (E) standing as a shorthand for ERROR.
|
||||
*
|
||||
* <p>Messages of level ERROR are always enabled.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2024 QOS.ch
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* 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:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* 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.helpers;
|
||||
|
||||
/**
|
||||
* Various utility methods
|
||||
*
|
||||
* @since 2.0.14
|
||||
*/
|
||||
public class Slf4jEnvUtil {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current version of slf4j, or null if data is not available.
|
||||
*
|
||||
* @return current version or null if missing version data
|
||||
* @since 2.0.14
|
||||
*/
|
||||
static public String slf4jVersion() {
|
||||
// String moduleVersion = slf4jVersionByModule();
|
||||
// if(moduleVersion != null)
|
||||
// return moduleVersion;
|
||||
|
||||
Package pkg = Slf4jEnvUtil.class.getPackage();
|
||||
if(pkg == null) {
|
||||
return null;
|
||||
}
|
||||
final String pkgVersion = pkg.getImplementationVersion();
|
||||
return pkgVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current version of slf4j via class.getModule()
|
||||
* or null if data is not available.
|
||||
*
|
||||
* @return current version or null if missing version data
|
||||
* @since 2.0.14
|
||||
*/
|
||||
// static private String slf4jVersionByModule() {
|
||||
// Module module = Slf4jEnvUtil.class.getModule();
|
||||
// if (module == null)
|
||||
// return null;
|
||||
//
|
||||
// ModuleDescriptor md = module.getDescriptor();
|
||||
// if (md == null)
|
||||
// return null;
|
||||
// Optional<String> opt = md.rawVersion();
|
||||
// return opt.orElse(null);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -7,8 +7,18 @@ import org.slf4j.spi.SLF4JServiceProvider;
|
|||
|
||||
public class SubstituteServiceProvider implements SLF4JServiceProvider {
|
||||
private final SubstituteLoggerFactory loggerFactory = new SubstituteLoggerFactory();
|
||||
private final IMarkerFactory markerFactory = new BasicMarkerFactory();
|
||||
private final MDCAdapter mdcAdapter = new BasicMDCAdapter();
|
||||
|
||||
// LoggerFactory expects providers to initialize markerFactory as early as possible.
|
||||
private final IMarkerFactory markerFactory;
|
||||
|
||||
// LoggerFactory expects providers to initialize their MDCAdapter field
|
||||
// as early as possible, preferably at construction time.
|
||||
private final MDCAdapter mdcAdapter;
|
||||
|
||||
public SubstituteServiceProvider() {
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new BasicMDCAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILoggerFactory getLoggerFactory() {
|
||||
|
|
@ -36,6 +46,5 @@ public class SubstituteServiceProvider implements SLF4JServiceProvider {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,10 +169,10 @@ public class DefaultLoggingEventBuilder implements LoggingEventBuilder, CallerBo
|
|||
}
|
||||
|
||||
private void logViaLocationAwareLoggerAPI(LocationAwareLogger locationAwareLogger, LoggingEvent aLoggingEvent) {
|
||||
String msg = aLoggingEvent.getMessage();
|
||||
List<Marker> markerList = aLoggingEvent.getMarkers();
|
||||
Marker firstMarker = (markerList != null && !markerList.isEmpty()) ? markerList.get(0) : null;
|
||||
String mergedMessage = mergeMarkersAndKeyValuePairsAndMessage(aLoggingEvent);
|
||||
locationAwareLogger.log(null, aLoggingEvent.getCallerBoundary(), aLoggingEvent.getLevel().toInt(),
|
||||
locationAwareLogger.log(firstMarker, aLoggingEvent.getCallerBoundary(), aLoggingEvent.getLevel().toInt(),
|
||||
mergedMessage,
|
||||
aLoggingEvent.getArgumentArray(), aLoggingEvent.getThrowable());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public interface MDCAdapter {
|
|||
public void setContextMap(Map<String, String> contextMap);
|
||||
|
||||
/**
|
||||
* Push a value into the deque(stack) referenced by 'key'.
|
||||
* Push a value into the <b>deque(stack)</b> referenced by 'key'.
|
||||
*
|
||||
* @param key identifies the appropriate stack
|
||||
* @param value the value to push into the stack
|
||||
|
|
@ -102,7 +102,7 @@ public interface MDCAdapter {
|
|||
public void pushByKey(String key, String value);
|
||||
|
||||
/**
|
||||
* Pop the stack referenced by 'key' and return the value possibly null.
|
||||
* Pop the <b>stack</b> referenced by 'key' and return the value possibly null.
|
||||
*
|
||||
* @param key identifies the deque(stack)
|
||||
* @return the value just popped. May be null/
|
||||
|
|
@ -111,7 +111,7 @@ public interface MDCAdapter {
|
|||
public String popByKey(String key);
|
||||
|
||||
/**
|
||||
* Returns a copy of the deque(stack) referenced by 'key'. May be null.
|
||||
* Returns a copy of the <b>deque(stack)</b> referenced by 'key'. May be null.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
* @return copy of stack referenced by 'key'. May be null.
|
||||
|
|
@ -122,7 +122,7 @@ public interface MDCAdapter {
|
|||
|
||||
|
||||
/**
|
||||
* Clear the deque(stack) referenced by 'key'.
|
||||
* Clear the <b>deque(stack)</b> referenced by 'key'.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
*
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -37,11 +39,21 @@ import org.slf4j.Marker;
|
|||
import org.slf4j.MarkerFactory;
|
||||
import org.slf4j.helpers.BasicMarker;
|
||||
import org.slf4j.helpers.NOPLogger;
|
||||
import org.slf4j.helpers.Reporter;
|
||||
|
||||
public class NoBindingTest {
|
||||
|
||||
int diff = new Random().nextInt(10000);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.setProperty(Reporter.SLF4J_INTERNAL_VERBOSITY_KEY, "debug");
|
||||
}
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.clearProperty(Reporter.SLF4J_INTERNAL_VERBOSITY_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogger() {
|
||||
Logger logger = LoggerFactory.getLogger(NoBindingTest.class);
|
||||
|
|
|
|||
|
|
@ -40,12 +40,11 @@ abstract public class MultithreadedInitializationTest {
|
|||
|
||||
long expectedEventCount = eventCount.get() + extraLogEvents();
|
||||
|
||||
assertTrue(expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount);
|
||||
assertTrue(expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, expectedEventCount < recordedEventCount + LENIENCY_COUNT);
|
||||
}
|
||||
assertTrue("unmet condition: " + expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount);
|
||||
assertTrue("unmet condition: " + expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, expectedEventCount < (recordedEventCount + LENIENCY_COUNT)); }
|
||||
|
||||
abstract protected long getRecordedEventCount();
|
||||
|
||||
|
||||
protected int extraLogEvents() {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -115,16 +115,11 @@ class SLF4JPlatformLogger implements System.Logger {
|
|||
* @param thrown
|
||||
* @param params
|
||||
*/
|
||||
private void log(Level jplLevel, ResourceBundle bundle, String msg, Throwable thrown, Object... params) {
|
||||
if (jplLevel == Level.OFF)
|
||||
return;
|
||||
private void log(final Level jplLevel, final ResourceBundle bundle, final String msg, final Throwable thrown, final Object... params) {
|
||||
|
||||
if (jplLevel == Level.ALL) {
|
||||
performLog(org.slf4j.event.Level.TRACE, bundle, msg, thrown, params);
|
||||
return;
|
||||
}
|
||||
final Level jplLevelReduced = fixExtremeLevels(jplLevel);
|
||||
|
||||
org.slf4j.event.Level slf4jLevel = jplLevelToSLF4JLevel(jplLevel);
|
||||
org.slf4j.event.Level slf4jLevel = jplLevelToSLF4JLevel(jplLevelReduced);
|
||||
boolean isEnabled = slf4jLogger.isEnabledForLevel(slf4jLevel);
|
||||
|
||||
if (isEnabled) {
|
||||
|
|
@ -132,6 +127,27 @@ class SLF4JPlatformLogger implements System.Logger {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Level.OFF and Level.ALL levels are not supposed to be used when calling log printing methods.
|
||||
* </p>
|
||||
*
|
||||
* <p>We compensate for such incorrect usage by transforming Level.OFF as Level.ERROR and
|
||||
* Level.ALL as Level.TRACE.
|
||||
* </p>
|
||||
*
|
||||
* @param jplLevel
|
||||
* @return
|
||||
*/
|
||||
private Level fixExtremeLevels(Level jplLevel) {
|
||||
if (jplLevel == Level.OFF)
|
||||
return Level.ERROR;
|
||||
|
||||
if (jplLevel == Level.ALL)
|
||||
return Level.TRACE;
|
||||
|
||||
return jplLevel;
|
||||
}
|
||||
|
||||
private void performLog(org.slf4j.event.Level slf4jLevel, ResourceBundle bundle, String msg, Throwable thrown, Object... params) {
|
||||
String message = getResourceStringOrMessage(bundle, msg);
|
||||
LoggingEventBuilder leb = slf4jLogger.makeLoggingEventBuilder(slf4jLevel);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.junit.After;
|
|||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The present test is fragile in the sense that it sets up SimpleLogger
|
||||
|
|
@ -108,12 +109,27 @@ public class SLF4JPlatformLoggingTest {
|
|||
//INFO throwTest - a problem
|
||||
//java.lang.Exception
|
||||
// at org.slf4j.jdk.platform.logging/org.slf4j.jdk.platform.logging.SLF4JPlatformLoggingTest.throwTest(SLF4JPlatformLoggingTest.java:92)
|
||||
|
||||
assertEquals("INFO throwTest - we have a problem", results.get(0));
|
||||
assertEquals(Exception.class.getName(), results.get(1));
|
||||
assertTrue(results.get(2).contains("at "));
|
||||
assertTrue(results.get(2).contains(this.getClass().getName()));
|
||||
|
||||
int line = 0;
|
||||
//assertTrue(results.get(0).startsWith("SLF4J(I): Connected with provider of type ["));
|
||||
assertEquals("INFO throwTest - we have a problem", results.get(line++));
|
||||
assertEquals(Exception.class.getName(), results.get(line++));
|
||||
assertTrue(results.get(line).contains("at "));
|
||||
assertTrue(results.get(line++).contains(this.getClass().getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extremeLevels() throws IOException {
|
||||
LoggerFinder finder = System.LoggerFinder.getLoggerFinder();
|
||||
assertEquals(EXPECTED_FINDER_CLASS, finder.getClass().getName());
|
||||
Logger systemLogger = finder.getLogger("extremeLevels", null);
|
||||
systemLogger.log(Level.OFF, "hello");
|
||||
systemLogger.log(Level.ALL, "world");
|
||||
|
||||
List<String> results = SPS.stringList;
|
||||
assertEquals(1, results.size());
|
||||
assertEquals("ERROR extremeLevels - hello", results.get(0));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements Lo
|
|||
|
||||
transient final java.util.logging.Logger logger;
|
||||
|
||||
static int NOT_FOUND = -1;
|
||||
|
||||
// WARN: JDK14LoggerAdapter constructor should have only package access so
|
||||
// that only JDK14LoggerFactory be able to create one.
|
||||
JDK14LoggerAdapter(java.util.logging.Logger logger) {
|
||||
|
|
@ -181,26 +183,10 @@ public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements Lo
|
|||
final private void fillCallerData(String callerFQCN, LogRecord record) {
|
||||
StackTraceElement[] steArray = new Throwable().getStackTrace();
|
||||
|
||||
int selfIndex = -1;
|
||||
for (int i = 0; i < steArray.length; i++) {
|
||||
final String className = steArray[i].getClassName();
|
||||
int furthestIndex = findFurthestIndex(callerFQCN, steArray);
|
||||
|
||||
if (barrierMatch(callerFQCN, className)) {
|
||||
selfIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int found = -1;
|
||||
for (int i = selfIndex + 1; i < steArray.length; i++) {
|
||||
final String className = steArray[i].getClassName();
|
||||
if (!(barrierMatch(callerFQCN, className))) {
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != -1) {
|
||||
if (furthestIndex != NOT_FOUND) {
|
||||
int found = furthestIndex+1;
|
||||
StackTraceElement ste = steArray[found];
|
||||
// setting the class name has the side effect of setting
|
||||
// the needToInferCaller variable to false.
|
||||
|
|
@ -209,7 +195,24 @@ public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements Lo
|
|||
}
|
||||
}
|
||||
|
||||
static String SELF = JDK14LoggerAdapter.class.getName();
|
||||
// find the furthest index which matches any of the barrier classes
|
||||
// We assume that the actual caller is at most MAX_SEARCH_DEPTH calls away
|
||||
private int findFurthestIndex(String callerFQCN, StackTraceElement[] steArray) {
|
||||
|
||||
final int maxIndex = Math.min(MAX_SEARCH_DEPTH, steArray.length);
|
||||
int furthestIndex = NOT_FOUND;
|
||||
|
||||
for (int i = 0; i < maxIndex; i++) {
|
||||
final String className = steArray[i].getClassName();
|
||||
if (barrierMatch(callerFQCN, className)) {
|
||||
furthestIndex = i;
|
||||
}
|
||||
}
|
||||
return furthestIndex;
|
||||
}
|
||||
|
||||
static final int MAX_SEARCH_DEPTH = 12;
|
||||
static String SELF = JDK14LoggerAdapter.class.getName();
|
||||
|
||||
static String SUPER = LegacyAbstractLogger.class.getName();
|
||||
static String SUPER_OF_SUPER = AbstractLogger.class.getName();
|
||||
|
|
|
|||
|
|
@ -17,8 +17,16 @@ public class JULServiceProvider implements SLF4JServiceProvider {
|
|||
public static String REQUESTED_API_VERSION = "2.0.99"; // !final
|
||||
|
||||
private ILoggerFactory loggerFactory;
|
||||
private IMarkerFactory markerFactory;
|
||||
private MDCAdapter mdcAdapter;
|
||||
// LoggerFactory expects providers to initialize markerFactory as early as possible.
|
||||
private final IMarkerFactory markerFactory;
|
||||
// LoggerFactory expects providers to initialize their MDCAdapter field
|
||||
// as early as possible, preferably at construction time.
|
||||
private final MDCAdapter mdcAdapter;
|
||||
|
||||
public JULServiceProvider() {
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new BasicMDCAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILoggerFactory getLoggerFactory() {
|
||||
|
|
@ -42,7 +50,5 @@ public class JULServiceProvider implements SLF4JServiceProvider {
|
|||
@Override
|
||||
public void initialize() {
|
||||
loggerFactory = new JDK14LoggerFactory();
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new BasicMDCAdapter();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
<relocation>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-reload4j</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.18</version>
|
||||
</relocation>
|
||||
</distributionManagement>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
@ -29,6 +29,14 @@
|
|||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<type>test-jar</type>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -18,9 +18,18 @@ public class NOPServiceProvider implements SLF4JServiceProvider {
|
|||
public static String REQUESTED_API_VERSION = "2.0.99"; // !final
|
||||
|
||||
private final ILoggerFactory loggerFactory = new NOPLoggerFactory();
|
||||
private final IMarkerFactory markerFactory = new BasicMarkerFactory();
|
||||
private final MDCAdapter mdcAdapter = new NOPMDCAdapter();
|
||||
|
||||
// LoggerFactory expects providers to initialize markerFactory as early as possible.
|
||||
private final IMarkerFactory markerFactory;
|
||||
|
||||
// LoggerFactory expects providers to initialize their MDCAdapter field
|
||||
// as early as possible, preferably at construction time.
|
||||
private final MDCAdapter mdcAdapter;
|
||||
|
||||
public NOPServiceProvider() {
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new NOPMDCAdapter();
|
||||
}
|
||||
public ILoggerFactory getLoggerFactory() {
|
||||
return loggerFactory;
|
||||
}
|
||||
|
|
@ -39,7 +48,6 @@ public class NOPServiceProvider implements SLF4JServiceProvider {
|
|||
}
|
||||
|
||||
public void initialize() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Copyright (c) 2004-2016 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,29 +20,29 @@
|
|||
* 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.nop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.LoggerFactoryFriend;
|
||||
import org.slf4j.helpers.StringPrintStream;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.slf4j.helpers.Reporter.SLF4J_INTERNAL_VERBOSITY_KEY;
|
||||
|
||||
public class MultithreadedInitializationTest {
|
||||
|
||||
static int NUM_LINES_IN_SLF4J_CONNECTED_WITH_PROVIDER_INFO = 1;
|
||||
final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
|
||||
|
||||
private static final AtomicLong EVENT_COUNT = new AtomicLong(0);
|
||||
|
|
@ -52,16 +52,18 @@ public class MultithreadedInitializationTest {
|
|||
int diff = new Random().nextInt(10000);
|
||||
String loggerName = "org.slf4j.impl.MultithreadedInitializationTest";
|
||||
private final PrintStream oldErr = System.err;
|
||||
StringPrintStream sps = new StringPrintStream(oldErr);
|
||||
StringPrintStream sps = new StringPrintStream(oldErr, false);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
System.setProperty(SLF4J_INTERNAL_VERBOSITY_KEY, "debug");
|
||||
LoggerFactoryFriend.reset();
|
||||
System.setErr(sps);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.clearProperty(SLF4J_INTERNAL_VERBOSITY_KEY);
|
||||
LoggerFactoryFriend.reset();
|
||||
System.setErr(oldErr);
|
||||
}
|
||||
|
|
@ -71,7 +73,7 @@ public class MultithreadedInitializationTest {
|
|||
System.out.println("THREAD_COUNT=" + THREAD_COUNT);
|
||||
LoggerAccessingThread[] accessors = harness();
|
||||
|
||||
for (LoggerAccessingThread accessor : accessors) {
|
||||
for(LoggerAccessingThread accessor : accessors) {
|
||||
EVENT_COUNT.getAndIncrement();
|
||||
accessor.logger.info("post harness");
|
||||
}
|
||||
|
|
@ -80,19 +82,19 @@ public class MultithreadedInitializationTest {
|
|||
logger.info("hello");
|
||||
EVENT_COUNT.getAndIncrement();
|
||||
|
||||
assertEquals(0, sps.stringList.size());
|
||||
assertEquals(NUM_LINES_IN_SLF4J_CONNECTED_WITH_PROVIDER_INFO, sps.stringList.size());
|
||||
}
|
||||
|
||||
private static LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
|
||||
LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
|
||||
final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
for(int i = 0; i < THREAD_COUNT; i++) {
|
||||
threads[i] = new LoggerAccessingThread(barrier, i);
|
||||
threads[i].start();
|
||||
}
|
||||
|
||||
barrier.await();
|
||||
for (int i = 0; i < THREAD_COUNT; i++) {
|
||||
for(int i = 0; i < THREAD_COUNT; i++) {
|
||||
threads[i].join();
|
||||
}
|
||||
return threads;
|
||||
|
|
@ -118,33 +120,35 @@ public class MultithreadedInitializationTest {
|
|||
logger.info("in run method");
|
||||
EVENT_COUNT.getAndIncrement();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class StringPrintStream extends PrintStream {
|
||||
;
|
||||
|
||||
public static final String LINE_SEP = System.getProperty("line.separator");
|
||||
PrintStream other;
|
||||
List<String> stringList = new ArrayList<>();
|
||||
|
||||
public StringPrintStream(PrintStream ps) {
|
||||
super(ps);
|
||||
other = ps;
|
||||
}
|
||||
|
||||
public void print(String s) {
|
||||
other.print(s);
|
||||
stringList.add(s);
|
||||
}
|
||||
|
||||
public void println(String s) {
|
||||
other.println(s);
|
||||
stringList.add(s);
|
||||
}
|
||||
|
||||
public void println(Object o) {
|
||||
other.println(o);
|
||||
stringList.add(o.toString());
|
||||
}
|
||||
};
|
||||
// public static class StringPrintStream extends PrintStream {
|
||||
//
|
||||
// public static final String LINE_SEP = System.getProperty("line.separator");
|
||||
// PrintStream other;
|
||||
// List<String> stringList = new ArrayList<>();
|
||||
//
|
||||
// public StringPrintStream(PrintStream ps) {
|
||||
// super(ps);
|
||||
// other = ps;
|
||||
// }
|
||||
//
|
||||
// public void print(String s) {
|
||||
// other.print(s);
|
||||
// stringList.add(s);
|
||||
// }
|
||||
//
|
||||
// public void println(String s) {
|
||||
// other.println(s);
|
||||
// stringList.add(s);
|
||||
// }
|
||||
//
|
||||
// public void println(Object o) {
|
||||
// other.println(o);
|
||||
// stringList.add(o.toString());
|
||||
// }
|
||||
// };
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
@ -51,7 +51,6 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.19.1</version>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
<reuseForks>false</reuseForks>
|
||||
|
|
@ -61,7 +60,7 @@
|
|||
<exclude>**/AllTest.java</exclude>
|
||||
<exclude>**/PackageTest.java</exclude>
|
||||
</excludes>
|
||||
<argLine>-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001</argLine>
|
||||
<!--<argLine>-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001</argLine> -->
|
||||
<!--<argLine>XXadd-opens log4j/org.apache.log4j=org.slf4j.log4j12</argLine>-->
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
|||
|
|
@ -19,10 +19,17 @@ public class Reload4jServiceProvider implements SLF4JServiceProvider {
|
|||
public static String REQUESTED_API_VERSION = "2.0.99"; // !final
|
||||
|
||||
private ILoggerFactory loggerFactory;
|
||||
private IMarkerFactory markerFactory;
|
||||
private MDCAdapter mdcAdapter;
|
||||
|
||||
// LoggerFactory expects providers to initialize markerFactory as early as possible.
|
||||
private final IMarkerFactory markerFactory;
|
||||
|
||||
// LoggerFactory expects providers to have a valid MDCAdapter field
|
||||
// as early as possible, preferably at construction time.
|
||||
private final MDCAdapter mdcAdapter;
|
||||
|
||||
public Reload4jServiceProvider() {
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new Reload4jMDCAdapter();
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
Level level = Level.TRACE;
|
||||
|
|
@ -34,8 +41,6 @@ public class Reload4jServiceProvider implements SLF4JServiceProvider {
|
|||
@Override
|
||||
public void initialize() {
|
||||
loggerFactory = new Reload4jLoggerFactory();
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new Reload4jMDCAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-parent</artifactId>
|
||||
<version>2.0.13</version>
|
||||
<version>2.0.19-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ public class SimpleLogger extends LegacyAbstractLogger {
|
|||
case LOG_LEVEL_INFO:
|
||||
return "INFO";
|
||||
case LOG_LEVEL_WARN:
|
||||
return "WARN";
|
||||
return CONFIG_PARAMS.warnLevelString;
|
||||
case LOG_LEVEL_ERROR:
|
||||
return "ERROR";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,16 @@ public class SimpleServiceProvider implements SLF4JServiceProvider {
|
|||
public static String REQUESTED_API_VERSION = "2.0.99"; // !final
|
||||
|
||||
private ILoggerFactory loggerFactory;
|
||||
private IMarkerFactory markerFactory;
|
||||
private MDCAdapter mdcAdapter;
|
||||
// LoggerFactory expects providers to initialize markerFactory as early as possible.
|
||||
private final IMarkerFactory markerFactory;
|
||||
// LoggerFactory expects providers to initialize their MDCAdapter field
|
||||
// as early as possible, preferably at construction time.
|
||||
private final MDCAdapter mdcAdapter;
|
||||
|
||||
public SimpleServiceProvider() {
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new NOPMDCAdapter();
|
||||
}
|
||||
|
||||
public ILoggerFactory getLoggerFactory() {
|
||||
return loggerFactory;
|
||||
|
|
@ -41,10 +49,8 @@ public class SimpleServiceProvider implements SLF4JServiceProvider {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
loggerFactory = new SimpleLoggerFactory();
|
||||
markerFactory = new BasicMarkerFactory();
|
||||
mdcAdapter = new NOPMDCAdapter();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
package org.slf4j.simple;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test class to verify configuration parameters of SimpleLogger
|
||||
*
|
||||
* @since 2.0.18
|
||||
*/
|
||||
public class ConfigParamsTest {
|
||||
|
||||
|
||||
private ListAppendingOutputStream prepareSink(List<String> outputList) {
|
||||
return new ListAppendingOutputStream(outputList);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
static public void resetConfigParams() {
|
||||
SimpleLogger.CONFIG_PARAMS.init();
|
||||
}
|
||||
|
||||
public Logger createLogger(ListAppendingOutputStream outputStream, Level level, String warnLevelString) {
|
||||
SimpleLogger.CONFIG_PARAMS.outputChoice = new OutputChoice(new PrintStream(outputStream));
|
||||
|
||||
SimpleLogger.CONFIG_PARAMS.warnLevelString = warnLevelString;
|
||||
|
||||
SimpleLogger logger = new SimpleLogger(ConfigParamsTest.class.getName());
|
||||
logger.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(level.toString());
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleTest(){
|
||||
String WARN_LEVEL_STRING = "WXYZ";
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), Level.TRACE, WARN_LEVEL_STRING);
|
||||
|
||||
configuredLogger.warn("This is a test");
|
||||
|
||||
String str0 = outputList.get(0);
|
||||
assertTrue(str0.contains(WARN_LEVEL_STRING));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package org.slf4j.simple;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
public class ListAppendingOutputStream extends OutputStream {
|
||||
|
||||
private final StringBuilder stringBuilder = new StringBuilder();
|
||||
private final List<String> targetList;
|
||||
|
||||
ListAppendingOutputStream(List<String> list) {this.targetList = list;}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
stringBuilder.append((char) b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
targetList.add(stringBuilder.toString());
|
||||
stringBuilder.delete(0, stringBuilder.length());
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,6 @@ 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;
|
||||
|
||||
|
|
@ -16,179 +14,157 @@ 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);
|
||||
|
||||
private ListAppendingOutputStream prepareSink(List<String> outputList) {
|
||||
return new ListAppendingOutputStream(outputList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrace() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.TRACE);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), 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("Trace message should've been captured", 1, outputList.size());
|
||||
assertTrue("Message should be logged in trace level", isTraceMessage(outputList.get(0)));
|
||||
assertEquals("Supplied trace message wasn't found in the log",
|
||||
"Simple trace message",
|
||||
extractMessage(loggingEvents.get(0)));
|
||||
extractMessage(outputList.get(0)));
|
||||
|
||||
loggingEvents.clear();
|
||||
outputList.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());
|
||||
assertEquals("The other levels should have been captured", 4, outputList.size());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDebug() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.DEBUG);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), Level.DEBUG);
|
||||
|
||||
configuredLogger.trace("Simple trace message");
|
||||
assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
|
||||
assertEquals("Lower levels should have been ignored", 0, outputList.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("Debug message should've been captured", 1, outputList.size());
|
||||
assertTrue("Message should be logged in debug level", isDebugMessage(outputList.get(0)));
|
||||
assertEquals("Supplied debug message wasn't found in the log",
|
||||
"Simple debug message",
|
||||
extractMessage(loggingEvents.get(0)));
|
||||
extractMessage(outputList.get(0)));
|
||||
|
||||
loggingEvents.clear();
|
||||
outputList.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());
|
||||
assertEquals("The other levels should have been captured", 3, outputList.size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testInfo() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), Level.INFO);
|
||||
|
||||
configuredLogger.trace("Simple trace message");
|
||||
configuredLogger.debug("Simple debug message");
|
||||
assertEquals("Lower levels should have been ignored", 0, loggingEvents.size());
|
||||
assertEquals("Lower levels should have been ignored", 0, outputList.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("Info message should've been captured", 1, outputList.size());
|
||||
assertTrue("Message should be logged in debug level", isInfoMessage(outputList.get(0)));
|
||||
assertEquals("Supplied info message wasn't found in the log",
|
||||
"Simple info message",
|
||||
extractMessage(loggingEvents.get(0)));
|
||||
extractMessage(outputList.get(0)));
|
||||
|
||||
loggingEvents.clear();
|
||||
outputList.clear();
|
||||
|
||||
configuredLogger.warn("Simple warn message");
|
||||
configuredLogger.error("Simple error message");
|
||||
assertEquals("The other levels should have been captured", 2, loggingEvents.size());
|
||||
assertEquals("The other levels should have been captured", 2, outputList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWarn() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.WARN);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), 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());
|
||||
assertEquals("Lower levels should have been ignored", 0, outputList.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("Warn message should've been captured", 1, outputList.size());
|
||||
assertTrue("Message should be logged in warn level", isWarnMessage(outputList.get(0)));
|
||||
assertEquals("Supplied warn message wasn't found in the log",
|
||||
"Simple warn message",
|
||||
extractMessage(loggingEvents.get(0)));
|
||||
extractMessage(outputList.get(0)));
|
||||
|
||||
loggingEvents.clear();
|
||||
outputList.clear();
|
||||
|
||||
configuredLogger.error("Simple error message");
|
||||
assertEquals("The other levels should have been captured", 1, loggingEvents.size());
|
||||
assertEquals("The other levels should have been captured", 1, outputList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testError() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.ERROR);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), 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());
|
||||
assertEquals("Lower levels should have been ignored", 0, outputList.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("Error message should've been captured", 1, outputList.size());
|
||||
assertTrue("Message should be logged in error level", isErrorMessage(outputList.get(0)));
|
||||
assertEquals("Supplied error message wasn't found in the log",
|
||||
"Simple error message",
|
||||
extractMessage(loggingEvents.get(0)));
|
||||
extractMessage(outputList.get(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatting() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), 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)));
|
||||
assertEquals("The formatted message should've been captured", 1, outputList.size());
|
||||
assertEquals("Message should've been formatted", "Some formatted string", extractMessage(outputList.get(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testException() {
|
||||
ArrayList<String> loggingEvents = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(loggingEvents), Level.INFO);
|
||||
ArrayList<String> outputList = new ArrayList<>();
|
||||
Logger configuredLogger = createLogger(prepareSink(outputList), 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("The formatted message should've been captured", 1, outputList.size());
|
||||
assertEquals("Message should've been formatted",
|
||||
"My error",
|
||||
extractExceptionMessage(loggingEvents.get(0)));
|
||||
extractExceptionMessage(outputList.get(0)));
|
||||
|
||||
assertEquals("Message should've been formatted",
|
||||
"java.lang.RuntimeException",
|
||||
extractExceptionType(loggingEvents.get(0)));
|
||||
extractExceptionType(outputList.get(0)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ public class SimpleLoggerMultithreadedInitializationTest extends MultithreadedIn
|
|||
//
|
||||
// final int diff = new Random().nextInt(10000);
|
||||
static int NUM_LINES_IN_SLF4J_REPLAY_WARNING = 3;
|
||||
static int NUM_LINES_IN_SLF4J_CONNECTED_WITH_PROVIDER_INFO = 1;
|
||||
|
||||
private final PrintStream oldErr = System.err;
|
||||
final String loggerName = this.getClass().getName();
|
||||
StringPrintStream sps = new StringPrintStream(oldErr, false);
|
||||
|
|
@ -67,7 +69,7 @@ public class SimpleLoggerMultithreadedInitializationTest extends MultithreadedIn
|
|||
|
||||
@Override
|
||||
protected int extraLogEvents() {
|
||||
return NUM_LINES_IN_SLF4J_REPLAY_WARNING;
|
||||
return NUM_LINES_IN_SLF4J_REPLAY_WARNING + NUM_LINES_IN_SLF4J_CONNECTED_WITH_PROVIDER_INFO;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package org.slf4j.simple;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.helpers.Slf4jEnvUtil;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class Slf4jVersionTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void slf4jVersionTest() {
|
||||
|
||||
String version = Slf4jEnvUtil.slf4jVersion();
|
||||
assertNotNull(version);
|
||||
assertTrue(version.startsWith("2"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue