LOG4J2-2305 - Create separate implementation for SLF4J 1.8
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/6467586f Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/6467586f Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/6467586f Branch: refs/heads/master Commit: 6467586f82ebcfa2bf9174bebe755b0c6ce234c3 Parents: bf5ab86 Author: Ralph Goers <[email protected]> Authored: Thu Jul 5 22:40:43 2018 -0700 Committer: Ralph Goers <[email protected]> Committed: Thu Jul 5 22:40:43 2018 -0700 ---------------------------------------------------------------------- log4j-distribution/pom.xml | 17 + log4j-slf4j-impl/pom.xml | 40 -- log4j-slf4j18-impl/pom.xml | 218 +++++++++ .../logging/slf4j/EventDataConverter.java | 50 +++ .../org/apache/logging/slf4j/Log4jLogger.java | 439 +++++++++++++++++++ .../logging/slf4j/Log4jLoggerFactory.java | 58 +++ .../apache/logging/slf4j/Log4jMDCAdapter.java | 62 +++ .../org/apache/logging/slf4j/Log4jMarker.java | 132 ++++++ .../logging/slf4j/Log4jMarkerFactory.java | 138 ++++++ .../logging/slf4j/SLF4JLoggingException.java | 41 ++ .../logging/slf4j/SLF4JServiceProvider.java | 59 +++ .../org/apache/logging/slf4j/package-info.java | 22 + .../services/org.slf4j.spi.SLF4JServiceProvider | 1 + log4j-slf4j18-impl/src/site/markdown/index.md | 40 ++ log4j-slf4j18-impl/src/site/site.xml | 52 +++ .../logging/slf4j/CallerInformationTest.java | 67 +++ .../apache/logging/slf4j/CustomFlatMarker.java | 76 ++++ .../org/apache/logging/slf4j/Log4j1222Test.java | 57 +++ .../logging/slf4j/Log4j2_1482_Slf4jTest.java | 41 ++ .../apache/logging/slf4j/Log4jMarkerTest.java | 47 ++ .../org/apache/logging/slf4j/LoggerTest.java | 182 ++++++++ .../org/apache/logging/slf4j/MarkerTest.java | 186 ++++++++ .../org/apache/logging/slf4j/OptionalTest.java | 69 +++ .../org/apache/logging/slf4j/SerializeTest.java | 46 ++ .../src/test/resources/log4j-test1.xml | 40 ++ .../src/test/resources/log4j2-1482.xml | 27 ++ log4j-slf4j18/pom.xml | 259 ----------- .../logging/slf4j/SLF4JServiceProvider.java | 57 --- .../services/org.slf4j.spi.SLF4JServiceProvider | 1 - log4j-slf4j18/src/site/markdown/index.md | 40 -- log4j-slf4j18/src/site/site.xml | 52 --- .../logging/slf4j/CallerInformationTest.java | 67 --- .../apache/logging/slf4j/CustomFlatMarker.java | 76 ---- .../org/apache/logging/slf4j/Log4j1222Test.java | 57 --- .../logging/slf4j/Log4j2_1482_Slf4jTest.java | 41 -- .../apache/logging/slf4j/Log4jMarkerTest.java | 38 -- .../org/apache/logging/slf4j/LoggerTest.java | 182 -------- .../org/apache/logging/slf4j/MarkerTest.java | 178 -------- .../org/apache/logging/slf4j/OptionalTest.java | 69 --- .../org/apache/logging/slf4j/SerializeTest.java | 46 -- .../src/test/resources/log4j-test1.xml | 40 -- .../src/test/resources/log4j2-1482.xml | 27 -- pom.xml | 4 +- 43 files changed, 2169 insertions(+), 1272 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-distribution/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-distribution/pom.xml b/log4j-distribution/pom.xml index 30ee9b3..3107f22 100644 --- a/log4j-distribution/pom.xml +++ b/log4j-distribution/pom.xml @@ -304,6 +304,23 @@ <version>${project.version}</version> <classifier>javadoc</classifier> </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j18-impl</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j18-impl</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j18-impl</artifactId> + <version>${project.version}</version> + <classifier>javadoc</classifier> + </dependency> <!-- log4j-to-slf4j --> <dependency> <groupId>org.apache.logging.log4j</groupId> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j-impl/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-slf4j-impl/pom.xml b/log4j-slf4j-impl/pom.xml index 7664733..3ed84fb 100644 --- a/log4j-slf4j-impl/pom.xml +++ b/log4j-slf4j-impl/pom.xml @@ -161,46 +161,6 @@ </instructions> </configuration> </plugin> - <plugin> - <artifactId>maven-assembly-plugin</artifactId> - <executions> - <execution> - <id>zip</id> - <phase>package</phase> - <goals> - <goal>single</goal> - </goals> - <configuration> - <finalName>log4j-slf4j-impl-${project.version}</finalName> - <attach>false</attach> - <appendAssemblyId>false</appendAssemblyId> - <descriptors> - <descriptor>src/assembly/slf4j.xml</descriptor> - </descriptors> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-install-plugin</artifactId> - <executions> - <execution> - <id>zip</id> - <phase>install</phase> - <goals> - <goal>install-file</goal> - </goals> - <configuration> - <groupId>${project.groupId}</groupId> - <artifactId>${project.artifactId}</artifactId> - <version>${project.version}</version> - <packaging>zip</packaging> - <file>${project.build.directory}/${project.build.finalName}.zip</file> - </configuration> - </execution> - </executions> - </plugin> </plugins> </build> <reporting> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/pom.xml ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/pom.xml b/log4j-slf4j18-impl/pom.xml new file mode 100644 index 0000000..6d204d1 --- /dev/null +++ b/log4j-slf4j18-impl/pom.xml @@ -0,0 +1,218 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j</artifactId> + <version>3.0.0-SNAPSHOT</version> + <relativePath>../</relativePath> + </parent> + <artifactId>log4j-slf4j18-impl</artifactId> + <packaging>jar</packaging> + <name>Apache Log4j SLF4J 1.8+ Binding</name> + <description>The Apache Log4j SLF4J 1.8 API binding to Log4j 2 Core</description> + <properties> + <log4jParentDir>${basedir}/..</log4jParentDir> + <docLabel>SLF4J Documentation</docLabel> + <projectDir>/slf4j18</projectDir> + <slf4j.version>1.8.0-alpha2</slf4j.version> + <module.name>org.apache.logging.log4j.slf4j</module.name> + </properties> + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-ext</artifactId> + <version>${slf4j.version}</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-csv</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <!-- Include the standard NOTICE and LICENSE --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-remote-resources-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>process</goal> + </goals> + <configuration> + <skip>false</skip> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Export-Package> + org.apache.logging.slf4j, + org.slf4j.impl + </Export-Package> + <Require-Capability> + osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)" + </Require-Capability> + <Provide-Capability> + osgi.serviceloader;osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider + </Provide-Capability> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <reporting> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changes-plugin</artifactId> + <version>${changes.plugin.version}</version> + <reportSets> + <reportSet> + <reports> + <report>changes-report</report> + </reports> + </reportSet> + </reportSets> + <configuration> + <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate> + <useJql>true</useJql> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>${checkstyle.plugin.version}</version> + <configuration> + <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> --> + <configLocation>${log4jParentDir}/checkstyle.xml</configLocation> + <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation> + <enableRulesSummary>false</enableRulesSummary> + <propertyExpansion>basedir=${basedir}</propertyExpansion> + <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>${javadoc.plugin.version}</version> + <configuration> + <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br /> + Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo, + and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom> + <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating + project --> + <detectOfflineLinks>false</detectOfflineLinks> + <linksource>true</linksource> + </configuration> + <reportSets> + <reportSet> + <id>non-aggregate</id> + <reports> + <report>javadoc</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + <version>${findbugs.plugin.version}</version> + <configuration> + <fork>true</fork> + <jvmArgs>-Duser.language=en</jvmArgs> + <threshold>Normal</threshold> + <effort>Default</effort> + <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>${jxr.plugin.version}</version> + <reportSets> + <reportSet> + <id>non-aggregate</id> + <reports> + <report>jxr</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + <version>${pmd.plugin.version}</version> + <configuration> + <targetJdk>${maven.compiler.target}</targetJdk> + </configuration> + </plugin> + </plugins> + </reporting> +</project> + http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/EventDataConverter.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/EventDataConverter.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/EventDataConverter.java new file mode 100644 index 0000000..620232a --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/EventDataConverter.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import java.util.Map; + +import org.apache.logging.log4j.message.Message; +import org.apache.logging.log4j.message.ParameterizedMessage; +import org.apache.logging.log4j.message.StructuredDataMessage; +import org.slf4j.ext.EventData; + +/** + * + */ +public class EventDataConverter { + + public Message convertEvent(final String message, final Object[] objects, final Throwable throwable) { + try { + final EventData data = objects != null && objects[0] instanceof EventData ? + (EventData) objects[0] : new EventData(message); + final StructuredDataMessage msg = + new StructuredDataMessage(data.getEventId(), data.getMessage(), data.getEventType()); + for (final Map.Entry<String, Object> entry : data.getEventMap().entrySet()) { + final String key = entry.getKey(); + if (EventData.EVENT_TYPE.equals(key) || EventData.EVENT_ID.equals(key) + || EventData.EVENT_MESSAGE.equals(key)) { + continue; + } + msg.put(key, String.valueOf(entry.getValue())); + } + return msg; + } catch (final Exception ex) { + return new ParameterizedMessage(message, objects, throwable); + } + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java new file mode 100644 index 0000000..6cbb7c4 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java @@ -0,0 +1,439 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.message.Message; +import org.apache.logging.log4j.message.ParameterizedMessage; +import org.apache.logging.log4j.message.SimpleMessage; +import org.apache.logging.log4j.spi.ExtendedLogger; +import org.apache.logging.log4j.util.LoaderUtil; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.slf4j.spi.LocationAwareLogger; + +/** + * SLF4J logger implementation that uses Log4j. + */ +public class Log4jLogger implements LocationAwareLogger, Serializable { + + public static final String FQCN = Log4jLogger.class.getName(); + + private static final long serialVersionUID = 7869000638091304316L; + private static final Marker EVENT_MARKER = MarkerFactory.getMarker("EVENT"); + private final boolean eventLogger; + private transient ExtendedLogger logger; + private final String name; + private transient EventDataConverter converter; + private transient Log4jMarkerFactory markerFactory; + + public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) { + this.markerFactory = markerFactory; + this.logger = logger; + this.eventLogger = "EventLogger".equals(name); + this.name = name; + this.converter = createConverter(); + } + + @Override + public void trace(final String format) { + logger.logIfEnabled(FQCN, Level.TRACE, null, format); + } + + @Override + public void trace(final String format, final Object o) { + logger.logIfEnabled(FQCN, Level.TRACE, null, format, o); + } + + @Override + public void trace(final String format, final Object arg1, final Object arg2) { + logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2); + } + + @Override + public void trace(final String format, final Object... args) { + logger.logIfEnabled(FQCN, Level.TRACE, null, format, args); + } + + @Override + public void trace(final String format, final Throwable t) { + logger.logIfEnabled(FQCN, Level.TRACE, null, format, t); + } + + @Override + public boolean isTraceEnabled() { + return logger.isEnabled(Level.TRACE, null, null); + } + + @Override + public boolean isTraceEnabled(final Marker marker) { + return logger.isEnabled(Level.TRACE, getMarker(marker), null); + } + + @Override + public void trace(final Marker marker, final String s) { + logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s); + } + + @Override + public void trace(final Marker marker, final String s, final Object o) { + logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o); + } + + @Override + public void trace(final Marker marker, final String s, final Object o, final Object o1) { + logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1); + } + + @Override + public void trace(final Marker marker, final String s, final Object... objects) { + logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects); + } + + @Override + public void trace(final Marker marker, final String s, final Throwable throwable) { + logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable); + } + + @Override + public void debug(final String format) { + logger.logIfEnabled(FQCN, Level.DEBUG, null, format); + } + + @Override + public void debug(final String format, final Object o) { + logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o); + } + + @Override + public void debug(final String format, final Object arg1, final Object arg2) { + logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2); + } + + @Override + public void debug(final String format, final Object... args) { + logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args); + } + + @Override + public void debug(final String format, final Throwable t) { + logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t); + } + + @Override + public boolean isDebugEnabled() { + return logger.isEnabled(Level.DEBUG, null, null); + } + + @Override + public boolean isDebugEnabled(final Marker marker) { + return logger.isEnabled(Level.DEBUG, getMarker(marker), null); + } + + @Override + public void debug(final Marker marker, final String s) { + logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s); + } + + @Override + public void debug(final Marker marker, final String s, final Object o) { + logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o); + } + + @Override + public void debug(final Marker marker, final String s, final Object o, final Object o1) { + logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1); + } + + @Override + public void debug(final Marker marker, final String s, final Object... objects) { + logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects); + } + + @Override + public void debug(final Marker marker, final String s, final Throwable throwable) { + logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable); + } + + @Override + public void info(final String format) { + logger.logIfEnabled(FQCN, Level.INFO, null, format); + } + + @Override + public void info(final String format, final Object o) { + logger.logIfEnabled(FQCN, Level.INFO, null, format, o); + } + + @Override + public void info(final String format, final Object arg1, final Object arg2) { + logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2); + } + + @Override + public void info(final String format, final Object... args) { + logger.logIfEnabled(FQCN, Level.INFO, null, format, args); + } + + @Override + public void info(final String format, final Throwable t) { + logger.logIfEnabled(FQCN, Level.INFO, null, format, t); + } + + @Override + public boolean isInfoEnabled() { + return logger.isEnabled(Level.INFO, null, null); + } + + @Override + public boolean isInfoEnabled(final Marker marker) { + return logger.isEnabled(Level.INFO, getMarker(marker), null); + } + + @Override + public void info(final Marker marker, final String s) { + logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s); + } + + @Override + public void info(final Marker marker, final String s, final Object o) { + logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o); + } + + @Override + public void info(final Marker marker, final String s, final Object o, final Object o1) { + logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1); + } + + @Override + public void info(final Marker marker, final String s, final Object... objects) { + logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects); + } + + @Override + public void info(final Marker marker, final String s, final Throwable throwable) { + logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable); + } + + @Override + public void warn(final String format) { + logger.logIfEnabled(FQCN, Level.WARN, null, format); + } + + @Override + public void warn(final String format, final Object o) { + logger.logIfEnabled(FQCN, Level.WARN, null, format, o); + } + + @Override + public void warn(final String format, final Object arg1, final Object arg2) { + logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2); + } + + @Override + public void warn(final String format, final Object... args) { + logger.logIfEnabled(FQCN, Level.WARN, null, format, args); + } + + @Override + public void warn(final String format, final Throwable t) { + logger.logIfEnabled(FQCN, Level.WARN, null, format, t); + } + + @Override + public boolean isWarnEnabled() { + return logger.isEnabled(Level.WARN, null, null); + } + + @Override + public boolean isWarnEnabled(final Marker marker) { + return logger.isEnabled(Level.WARN, getMarker(marker), null); + } + + @Override + public void warn(final Marker marker, final String s) { + logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s); + } + + @Override + public void warn(final Marker marker, final String s, final Object o) { + logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o); + } + + @Override + public void warn(final Marker marker, final String s, final Object o, final Object o1) { + logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1); + } + + @Override + public void warn(final Marker marker, final String s, final Object... objects) { + logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects); + } + + @Override + public void warn(final Marker marker, final String s, final Throwable throwable) { + logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable); + } + + @Override + public void error(final String format) { + logger.logIfEnabled(FQCN, Level.ERROR, null, format); + } + + @Override + public void error(final String format, final Object o) { + logger.logIfEnabled(FQCN, Level.ERROR, null, format, o); + } + + @Override + public void error(final String format, final Object arg1, final Object arg2) { + logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2); + } + + @Override + public void error(final String format, final Object... args) { + logger.logIfEnabled(FQCN, Level.ERROR, null, format, args); + } + + @Override + public void error(final String format, final Throwable t) { + logger.logIfEnabled(FQCN, Level.ERROR, null, format, t); + } + + @Override + public boolean isErrorEnabled() { + return logger.isEnabled(Level.ERROR, null, null); + } + + @Override + public boolean isErrorEnabled(final Marker marker) { + return logger.isEnabled(Level.ERROR, getMarker(marker), null); + } + + @Override + public void error(final Marker marker, final String s) { + logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s); + } + + @Override + public void error(final Marker marker, final String s, final Object o) { + logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o); + } + + @Override + public void error(final Marker marker, final String s, final Object o, final Object o1) { + logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1); + } + + @Override + public void error(final Marker marker, final String s, final Object... objects) { + logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects); + } + + @Override + public void error(final Marker marker, final String s, final Throwable throwable) { + logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable); + } + + @Override + public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) { + final Level log4jLevel = getLevel(level); + final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker); + + if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) { + return; + } + final Message msg; + if (eventLogger && marker != null && marker.contains(EVENT_MARKER) && converter != null) { + msg = converter.convertEvent(message, params, throwable); + } else if (params == null) { + msg = new SimpleMessage(message); + } else { + msg = new ParameterizedMessage(message, params, throwable); + if (throwable != null) { + throwable = msg.getThrowable(); + } + } + logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable); + } + + private org.apache.logging.log4j.Marker getMarker(final Marker marker) { + if (marker == null) { + return null; + } else if (marker instanceof Log4jMarker) { + return ((Log4jMarker) marker).getLog4jMarker(); + } else { + return ((Log4jMarker) markerFactory.getMarker(marker)).getLog4jMarker(); + } + } + + @Override + public String getName() { + return name; + } + + /** + * Always treat de-serialization as a full-blown constructor, by validating the final state of + * the de-serialized object. + */ + private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException { + // always perform the default de-serialization first + aInputStream.defaultReadObject(); + logger = LogManager.getContext().getLogger(name); + converter = createConverter(); + markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory(); + } + + /** + * This is the default implementation of writeObject. Customise if necessary. + */ + private void writeObject(final ObjectOutputStream aOutputStream) throws IOException { + // perform the default serialization for all non-transient, non-static fields + aOutputStream.defaultWriteObject(); + } + + private static EventDataConverter createConverter() { + try { + LoaderUtil.loadClass("org.slf4j.ext.EventData"); + return new EventDataConverter(); + } catch (final ClassNotFoundException cnfe) { + return null; + } + } + + private static Level getLevel(final int i) { + switch (i) { + case TRACE_INT: + return Level.TRACE; + case DEBUG_INT: + return Level.DEBUG; + case INFO_INT: + return Level.INFO; + case WARN_INT: + return Level.WARN; + case ERROR_INT: + return Level.ERROR; + } + return Level.ERROR; + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java new file mode 100644 index 0000000..fcf1d66 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.spi.AbstractLoggerAdapter; +import org.apache.logging.log4j.spi.LoggerContext; +import org.apache.logging.log4j.util.StackLocatorUtil; +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; + +/** + * Log4j implementation of SLF4J ILoggerFactory interface. + */ +public class Log4jLoggerFactory extends AbstractLoggerAdapter<Logger> implements ILoggerFactory { + + private static final String FQCN = Log4jLoggerFactory.class.getName(); + private static final String PACKAGE = "org.slf4j"; + private final Log4jMarkerFactory markerFactory; + + public Log4jLoggerFactory(Log4jMarkerFactory markerFactory) { + this.markerFactory = markerFactory; + } + + + @Override + protected Logger newLogger(final String name, final LoggerContext context) { + final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name; + return new Log4jLogger(markerFactory, context.getLogger(key), name); + } + + @Override + protected LoggerContext getContext() { + final Class<?> anchor = StackLocatorUtil.getCallerClass(FQCN, PACKAGE); + return anchor == null ? LogManager.getContext() : getContext(StackLocatorUtil.getCallerClass(anchor)); + } + + + Log4jMarkerFactory getMarkerFactory() { + return markerFactory; + } + + +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java new file mode 100644 index 0000000..ba32dc6 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import java.util.Map; + +import org.apache.logging.log4j.ThreadContext; +import org.slf4j.spi.MDCAdapter; + +/** + * + */ +public class Log4jMDCAdapter implements MDCAdapter { + + @Override + public void put(final String key, final String val) { + ThreadContext.put(key, val); + } + + @Override + public String get(final String key) { + return ThreadContext.get(key); + } + + @Override + public void remove(final String key) { + ThreadContext.remove(key); + } + + @Override + public void clear() { + ThreadContext.clearMap(); + } + + @Override + public Map<String, String> getCopyOfContextMap() { + return ThreadContext.getContext(); + } + + @Override + @SuppressWarnings("unchecked") // nothing we can do about this, restricted by SLF4J API + public void setContextMap(@SuppressWarnings("rawtypes") final Map map) { + ThreadContext.clearMap(); + for (final Map.Entry<String, String> entry : ((Map<String, String>) map).entrySet()) { + ThreadContext.put(entry.getKey(), entry.getValue()); + } + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java new file mode 100644 index 0000000..00351f9 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.logging.log4j.MarkerManager; +import org.slf4j.IMarkerFactory; +import org.slf4j.Marker; + +/** + * Log4j/SLF4J {@link Marker} type bridge. + */ +class Log4jMarker implements Marker { + + public static final long serialVersionUID = 1590472L; + + private final IMarkerFactory factory; + + private final org.apache.logging.log4j.Marker marker; + + /** + * Constructs a Log4jMarker using an existing Log4j {@link org.apache.logging.log4j.Marker}. + * @param marker The Log4j Marker upon which to base this Marker. + */ + public Log4jMarker(final IMarkerFactory markerFactory, final org.apache.logging.log4j.Marker marker) { + this.factory = markerFactory; + this.marker = marker; + } + + @Override + public void add(final Marker marker) { + if (marker == null) { + throw new IllegalArgumentException(); + } + final Marker m = factory.getMarker(marker.getName()); + this.marker.addParents(((Log4jMarker)m).getLog4jMarker()); + } + + @Override + public boolean contains(final Marker marker) { + if (marker == null) { + throw new IllegalArgumentException(); + } + return this.marker.isInstanceOf(marker.getName()); + } + + @Override + public boolean contains(final String s) { + return s != null ? this.marker.isInstanceOf(s) : false; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof Log4jMarker)) { + return false; + } + final Log4jMarker other = (Log4jMarker) obj; + if (marker == null) { + if (other.marker != null) { + return false; + } + } else if (!marker.equals(other.marker)) { + return false; + } + return true; + } + + public org.apache.logging.log4j.Marker getLog4jMarker() { + return marker; + } + + @Override + public String getName() { + return marker.getName(); + } + + @Override + public boolean hasChildren() { + return marker.hasParents(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((marker == null) ? 0 : marker.hashCode()); + return result; + } + + @Override + public boolean hasReferences() { + return marker.hasParents(); + } + + @Override + public Iterator<Marker> iterator() { + final org.apache.logging.log4j.Marker[] log4jParents = this.marker.getParents(); + final List<Marker> parents = new ArrayList<>(log4jParents.length); + for (final org.apache.logging.log4j.Marker m : log4jParents) { + parents.add(factory.getMarker(m.getName())); + } + return parents.iterator(); + } + + @Override + public boolean remove(final Marker marker) { + return marker != null ? this.marker.remove(MarkerManager.getMarker(marker.getName())) : false; + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java new file mode 100644 index 0000000..69ea94b --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.status.StatusLogger; +import org.slf4j.IMarkerFactory; +import org.slf4j.Marker; + +/** + * Log4j/SLF4J bridge to create SLF4J Markers based on name or based on existing SLF4J Markers. + */ +public class Log4jMarkerFactory implements IMarkerFactory { + + private static final Logger LOGGER = StatusLogger.getLogger(); + + private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<>(); + + /** + * Returns a Log4j Marker that is compatible with SLF4J. + * @param name The name of the Marker. + * @return A Marker. + */ + @Override + public Marker getMarker(final String name) { + if (name == null) { + throw new IllegalArgumentException("Marker name must not be null"); + } + final Marker marker = markerMap.get(name); + if (marker != null) { + return marker; + } + final org.apache.logging.log4j.Marker log4jMarker = MarkerManager.getMarker(name); + return addMarkerIfAbsent(name, log4jMarker); + } + + private Marker addMarkerIfAbsent(final String name, final org.apache.logging.log4j.Marker log4jMarker) { + final Marker marker = new Log4jMarker(this, log4jMarker); + final Marker existing = markerMap.putIfAbsent(name, marker); + return existing == null ? marker : existing; + } + + /** + * Returns a Log4j Marker converted from an existing custom SLF4J Marker. + * @param marker The SLF4J Marker to convert. + * @return A converted Log4j/SLF4J Marker. + * @since 2.1 + */ + public Marker getMarker(final Marker marker) { + if (marker == null) { + throw new IllegalArgumentException("Marker must not be null"); + } + final Marker m = markerMap.get(marker.getName()); + if (m != null) { + return m; + } + return addMarkerIfAbsent(marker.getName(), convertMarker(marker)); + } + + private static org.apache.logging.log4j.Marker convertMarker(final Marker original) { + if (original == null) { + throw new IllegalArgumentException("Marker must not be null"); + } + return convertMarker(original, new ArrayList<Marker>()); + } + + private static org.apache.logging.log4j.Marker convertMarker(final Marker original, + final Collection<Marker> visited) { + final org.apache.logging.log4j.Marker marker = MarkerManager.getMarker(original.getName()); + if (original.hasReferences()) { + final Iterator<Marker> it = original.iterator(); + while (it.hasNext()) { + final Marker next = it.next(); + if (visited.contains(next)) { + LOGGER.warn("Found a cycle in Marker [{}]. Cycle will be broken.", next.getName()); + } else { + visited.add(next); + marker.addParents(convertMarker(next, visited)); + } + } + } + return marker; + } + + /** + * Returns true if the Marker exists. + * @param name The Marker name. + * @return {@code true} if the Marker exists, {@code false} otherwise. + */ + @Override + public boolean exists(final String name) { + return markerMap.containsKey(name); + } + + /** + * Log4j does not support detached Markers. This method always returns false. + * @param name The Marker name. + * @return {@code false} + */ + @Override + public boolean detachMarker(final String name) { + return false; + } + + /** + * Log4j does not support detached Markers for performance reasons. The returned Marker is attached. + * @param name The Marker name. + * @return The named Marker (unmodified). + */ + @Override + public Marker getDetachedMarker(final String name) { + LOGGER.warn("Log4j does not support detached Markers. Returned Marker [{}] will be unchanged.", name); + return getMarker(name); + } + + +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java new file mode 100644 index 0000000..0a41215 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +/** + * Exception thrown when the SLF4J adapter encounters a problem. + * + */ +public class SLF4JLoggingException extends RuntimeException { + + /** + * Generated serial version ID. + */ + private static final long serialVersionUID = -1618650972455089998L; + + public SLF4JLoggingException(final String msg) { + super(msg); + } + + public SLF4JLoggingException(final String msg, final Exception ex) { + super(msg, ex); + } + + public SLF4JLoggingException(final Exception ex) { + super(ex); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java new file mode 100644 index 0000000..561132f --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import org.slf4j.ILoggerFactory; +import org.slf4j.IMarkerFactory; +import org.slf4j.spi.MDCAdapter; + +public class SLF4JServiceProvider implements org.slf4j.spi.SLF4JServiceProvider { + + public static final String REQUESTED_API_VERSION = "1.8.99"; + + private ILoggerFactory loggerFactory; + private Log4jMarkerFactory markerFactory; + private MDCAdapter mdcAdapter; + + @Override + public ILoggerFactory getLoggerFactory() { + return loggerFactory; + } + + @Override + public IMarkerFactory getMarkerFactory() { + return markerFactory; + } + + @Override + public MDCAdapter getMDCAdapter() { + return mdcAdapter; + } + + @Override + public String getRequesteApiVersion() { + return REQUESTED_API_VERSION; + } + + @Override + public void initialize() { + markerFactory = new Log4jMarkerFactory(); + loggerFactory = new Log4jLoggerFactory(markerFactory); + mdcAdapter = new Log4jMDCAdapter(); + } + + +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/package-info.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/package-info.java b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/package-info.java new file mode 100644 index 0000000..ec0f031 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/java/org/apache/logging/slf4j/package-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +/** + * SLF4J support. Note that this does indeed share the same package namespace as the one found in log4j-to-slf4j; + * this is intentional. The two JARs should <em>not</em> be used at the same time! Thus, in an OSGi environment + * where split packages are not allowed, this error is prevented due to both JARs sharing an exported package name. + */ +package org.apache.logging.slf4j; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/log4j-slf4j18-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider new file mode 100644 index 0000000..1577f12 --- /dev/null +++ b/log4j-slf4j18-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider @@ -0,0 +1 @@ +org.apache.logging.slf4j.SLF4JServiceProvider \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/site/markdown/index.md ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/site/markdown/index.md b/log4j-slf4j18-impl/src/site/markdown/index.md new file mode 100644 index 0000000..6e3f3f6 --- /dev/null +++ b/log4j-slf4j18-impl/src/site/markdown/index.md @@ -0,0 +1,40 @@ +<!-- vim: set syn=markdown : --> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +# Log4j 2 SLF4J Binding + +The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use +Log4j 2 as the implementation. + +## Requirements + +The Log4j 2 SLF4J Binding has a dependency on the Log4j 2 API as well as the SLF4J API. +For more information, see [Runtime Dependencies](../runtime-dependencies.html). + +## Usage + +The SLF4J binding provided in this component cause all the SLF4J APIs to be routed to Log4j 2. Simply +include the Log4j 2 SLF4J Binding jar along with the Log4j 2 jars and SLF4J API jar to cause all SLF4J +logging to be handled by Log4j 2. + +<div class="alert alert-danger"> +Use of the Log4j 2 SLF4J Binding (log4j-slf4j-impl-2.0.jar) together with +the SLF4J adapter (log4j-to-slf4j-2.0.jar) should +never be attempted, as it will cause events to endlessly be routed between +SLF4J and Log4j 2. +</div> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/site/site.xml ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/site/site.xml b/log4j-slf4j18-impl/src/site/site.xml new file mode 100644 index 0000000..a1f9106 --- /dev/null +++ b/log4j-slf4j18-impl/src/site/site.xml @@ -0,0 +1,52 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<project name="SLF4J Binding Using Log4j" + xmlns="http://maven.apache.org/DECORATION/1.4.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd"> + <body> + <links> + <item name="Apache" href="http://www.apache.org/" /> + <item name="Logging Services" href="http://logging.apache.org/"/> + <item name="Log4j" href="../index.html"/> + </links> + + <!-- Component-specific reports --> + <menu ref="reports"/> + + <!-- Overall Project Info --> + <menu name="Log4j Project Information" img="icon-info-sign"> + <item name="Dependencies" href="../dependencies.html" /> + <item name="Dependency Convergence" href="../dependency-convergence.html" /> + <item name="Dependency Management" href="../dependency-management.html" /> + <item name="Project Team" href="../team-list.html" /> + <item name="Mailing Lists" href="../mail-lists.html" /> + <item name="Issue Tracking" href="../issue-tracking.html" /> + <item name="Project License" href="../license.html" /> + <item name="Source Repository" href="../source-repository.html" /> + <item name="Project Summary" href="../project-summary.html" /> + </menu> + + <menu name="Log4j Project Reports" img="icon-cog"> + <item name="Changes Report" href="../changes-report.html" /> + <item name="JIRA Report" href="../jira-report.html" /> + <item name="Surefire Report" href="../surefire-report.html" /> + <item name="RAT Report" href="../rat-report.html" /> + </menu> + </body> +</project> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java new file mode 100644 index 0000000..7efc0e5 --- /dev/null +++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.apache.logging.log4j.junit.LoggerContextRule; +import org.apache.logging.log4j.test.appender.ListAppender; +import org.junit.ClassRule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CallerInformationTest { + + // config from log4j-core test-jar + private static final String CONFIG = "log4j2-calling-class.xml"; + + @ClassRule + public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG); + + @Test + public void testClassLogger() throws Exception { + final ListAppender app = ctx.getListAppender("Class").clear(); + final Logger logger = LoggerFactory.getLogger("ClassLogger"); + logger.info("Ignored message contents."); + logger.warn("Verifying the caller class is still correct."); + logger.error("Hopefully nobody breaks me!"); + final List<String> messages = app.getMessages(); + assertEquals("Incorrect number of messages.", 3, messages.size()); + for (final String message : messages) { + assertEquals("Incorrect caller class name.", this.getClass().getName(), message); + } + } + + @Test + public void testMethodLogger() throws Exception { + final ListAppender app = ctx.getListAppender("Method").clear(); + final Logger logger = LoggerFactory.getLogger("MethodLogger"); + logger.info("More messages."); + logger.warn("CATASTROPHE INCOMING!"); + logger.error("ZOMBIES!!!"); + logger.warn("brains~~~"); + logger.info("Itchy. Tasty."); + final List<String> messages = app.getMessages(); + assertEquals("Incorrect number of messages.", 5, messages.size()); + for (final String message : messages) { + assertEquals("Incorrect caller method name.", "testMethodLogger", message); + } + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java new file mode 100644 index 0000000..0138cea --- /dev/null +++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ + +package org.apache.logging.slf4j; + +import java.util.Iterator; + +import org.slf4j.Marker; + +/** + * Test Marker that may contain no reference/parent Markers. + * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a> + */ +public class CustomFlatMarker implements Marker { + private static final long serialVersionUID = -4115520883240247266L; + + private final String name; + + public CustomFlatMarker(final String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void add(final Marker reference) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(final Marker reference) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasChildren() { + return hasReferences(); + } + + @Override + public boolean hasReferences() { + return false; + } + + @Override + public Iterator<Marker> iterator() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean contains(final Marker other) { + return false; + } + + @Override + public boolean contains(final String name) { + return false; + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java new file mode 100644 index 0000000..59f69e0 --- /dev/null +++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.*; + +/** + * Tests logging during shutdown. + */ +public class Log4j1222Test +{ + + @Test + public void homepageRendersSuccessfully() + { + System.setProperty("log4j.configurationFile", "log4j2-console.xml"); + Runtime.getRuntime().addShutdownHook(new ShutdownHook()); + } + + private static class ShutdownHook extends Thread { + + private static class Holder { + private static final Logger LOGGER = LoggerFactory.getLogger(Log4j1222Test.class); + } + + @Override + public void run() + { + super.run(); + trigger(); + } + + private void trigger() { + Holder.LOGGER.info("Attempt to trigger"); + assertTrue("Logger is of type " + Holder.LOGGER.getClass().getName(), Holder.LOGGER instanceof Log4jLogger); + + } + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java new file mode 100644 index 0000000..8934f29 --- /dev/null +++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ + +package org.apache.logging.slf4j; + +import org.apache.logging.log4j.core.layout.Log4j2_1482_Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tests https://issues.apache.org/jira/browse/LOG4J2-1482 + */ +public class Log4j2_1482_Slf4jTest extends Log4j2_1482_Test { + + @Override + protected void log(final int runNumber) { + if (runNumber == 2) { + // System.out.println("Set a breakpoint here."); + } + final Logger logger = LoggerFactory.getLogger("auditcsvfile"); + final int val1 = 9, val2 = 11, val3 = 12; + logger.info("Info Message!", val1, val2, val3); + logger.info("Info Message!", val1, val2, val3); + logger.info("Info Message!", val1, val2, val3); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java new file mode 100644 index 0000000..ac6ad22 --- /dev/null +++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class Log4jMarkerTest { + + private static Log4jMarkerFactory markerFactory; + + @BeforeClass + public static void startup() { + markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory(); + + } + + @Test + public void testEquals() { + final Marker markerA = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-A"); + final Marker markerB = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-B"); + final Log4jMarker marker1 = new Log4jMarker(markerFactory, markerA); + final Log4jMarker marker2 = new Log4jMarker(markerFactory, markerA); + final Log4jMarker marker3 = new Log4jMarker(markerFactory, markerB); + Assert.assertEquals(marker1, marker2); + Assert.assertNotEquals(marker1, null); + Assert.assertNotEquals(null, marker1); + Assert.assertNotEquals(marker1, marker3); + } +} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6467586f/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java ---------------------------------------------------------------------- diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java new file mode 100644 index 0000000..0524074 --- /dev/null +++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.slf4j; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Locale; + +import org.apache.logging.log4j.junit.LoggerContextRule; +import org.apache.logging.log4j.test.appender.ListAppender; +import org.apache.logging.log4j.util.Strings; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.Marker; +import org.slf4j.ext.EventData; +import org.slf4j.ext.EventLogger; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; +import org.slf4j.spi.LocationAwareLogger; + +/** + * + */ +public class LoggerTest { + + private static final String CONFIG = "log4j-test1.xml"; + + @ClassRule + public static LoggerContextRule ctx = new LoggerContextRule(CONFIG); + + Logger logger = LoggerFactory.getLogger("LoggerTest"); + XLogger xlogger = XLoggerFactory.getXLogger("LoggerTest"); + + @Test + public void basicFlow() { + xlogger.entry(); + verify("List", "o.a.l.s.LoggerTest entry MDC{}" + Strings.LINE_SEPARATOR); + xlogger.exit(); + verify("List", "o.a.l.s.LoggerTest exit MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void simpleFlow() { + xlogger.entry(CONFIG); + verify("List", "o.a.l.s.LoggerTest entry with (log4j-test1.xml) MDC{}" + Strings.LINE_SEPARATOR); + xlogger.exit(0); + verify("List", "o.a.l.s.LoggerTest exit with (0) MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void throwing() { + xlogger.throwing(new IllegalArgumentException("Test Exception")); + verify("List", "o.a.l.s.LoggerTest throwing MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void catching() { + try { + throw new NullPointerException(); + } catch (final Exception e) { + xlogger.catching(e); + verify("List", "o.a.l.s.LoggerTest catching MDC{}" + Strings.LINE_SEPARATOR); + } + } + + @Test + public void debug() { + logger.debug("Debug message"); + verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void debugNoParms() { + logger.debug("Debug message {}"); + verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR); + logger.debug("Debug message {}", (Object[]) null); + verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR); + ((LocationAwareLogger)logger).log(null, Log4jLogger.class.getName(), LocationAwareLogger.DEBUG_INT, + "Debug message {}", null, null); + verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR); + } + + + @Test + public void debugWithParms() { + logger.debug("Hello, {}", "World"); + verify("List", "o.a.l.s.LoggerTest Hello, World MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void mdc() { + + MDC.put("TestYear", "2010"); + logger.debug("Debug message"); + verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2010}" + Strings.LINE_SEPARATOR); + MDC.clear(); + logger.debug("Debug message"); + verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR); + } + + /** + * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a> + */ + @Test + public void supportsCustomSLF4JMarkers() { + final Marker marker = new CustomFlatMarker("TEST"); + logger.debug(marker, "Test"); + verify("List", "o.a.l.s.LoggerTest Test MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void testRootLogger() { + final Logger l = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + assertNotNull("No Root Logger", l); + assertEquals(Logger.ROOT_LOGGER_NAME, l.getName()); + } + + @Test + public void doubleSubst() { + logger.debug("Hello, {}", "Log4j {}"); + verify("List", "o.a.l.s.LoggerTest Hello, Log4j {} MDC{}" + Strings.LINE_SEPARATOR); + xlogger.debug("Hello, {}", "Log4j {}"); + verify("List", "o.a.l.s.LoggerTest Hello, Log4j Log4j {} MDC{}" + Strings.LINE_SEPARATOR); + } + + @Test + public void testEventLogger() { + MDC.put("loginId", "JohnDoe"); + MDC.put("ipAddress", "192.168.0.120"); + MDC.put("locale", Locale.US.getDisplayName()); + final EventData data = new EventData(); + data.setEventType("Transfer"); + data.setEventId("Audit@18060"); + data.setMessage("Transfer Complete"); + data.put("ToAccount", "123456"); + data.put("FromAccount", "123457"); + data.put("Amount", "200.00"); + EventLogger.logEvent(data); + MDC.clear(); + verify("EventLogger", "o.a.l.s.LoggerTest Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete" + Strings.LINE_SEPARATOR); + } + + private void verify(final String name, final String expected) { + final ListAppender listApp = ctx.getListAppender(name); + assertNotNull("Missing Appender", listApp); + final List<String> events = listApp.getMessages(); + assertTrue("Incorrect number of messages. Expected 1 Actual " + events.size(), events.size()== 1); + final String actual = events.get(0); + assertEquals("Incorrect message. Expected " + expected + ". Actual " + actual, expected, actual); + listApp.clear(); + } + + @Before + @After + public void cleanup() { + MDC.clear(); + ctx.getListAppender("List").clear(); + ctx.getListAppender("EventLogger").clear(); + } +}
