Commit 8dcdb7c7 authored by Piotr P. Karwasz's avatar Piotr P. Karwasz
Browse files

[LOG4J2-3370] Initial SLF4J 2.0.x support

parent 9fb2f4b0
Showing with 1873 additions and 0 deletions
+1873 -0
<?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>2.17.3-SNAPSHOT</version>
</parent>
<artifactId>log4j-slf4j20-impl</artifactId>
<packaging>jar</packaging>
<name>Apache Log4j SLF4J 2.0+ Binding</name>
<description>The Apache Log4j SLF4J 2.0 API binding to Log4j 2 Core</description>
<properties>
<log4jParentDir>${basedir}/..</log4jParentDir>
<docLabel>SLF4J Documentation</docLabel>
<projectDir>/slf4j18</projectDir>
<slf4j.version>2.0.0-alpha5</slf4j.version>
<module.name>org.apache.logging.log4j.slf4j</module.name>
<maven.doap.skip>true</maven.doap.skip>
</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>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<scope>test</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</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.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>loop-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/OverflowTest.java</include>
</includes>
</configuration>
</execution>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/OverflowTest.java</exclude>
</excludes>
<classpathDependencyExcludes>
<classpathDependencyExcludes>org.apache.logging.log4j:log4j-to-slf4j</classpathDependencyExcludes>
</classpathDependencyExcludes>
</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 &#169; {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>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
</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>
/*
* 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.slf4j.Marker;
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 transient ExtendedLogger logger;
private final String name;
private transient Log4jMarkerFactory markerFactory;
public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
this.markerFactory = markerFactory;
this.logger = logger;
this.name = name;
}
@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 (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);
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 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;
}
}
/*
* 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.LoggingException;
import org.apache.logging.log4j.spi.AbstractLoggerAdapter;
import org.apache.logging.log4j.spi.LoggerContext;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.StackLocatorUtil;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import java.util.function.Predicate;
/**
* Log4j implementation of SLF4J ILoggerFactory interface.
*/
public class Log4jLoggerFactory extends AbstractLoggerAdapter<Logger> implements ILoggerFactory {
private static final StatusLogger LOGGER = StatusLogger.getLogger();
private static final String SLF4J_PACKAGE = "org.slf4j";
private static final Predicate<Class<?>> CALLER_PREDICATE = clazz ->
!AbstractLoggerAdapter.class.equals(clazz) && !clazz.getName().startsWith(SLF4J_PACKAGE);
private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext";
private final Log4jMarkerFactory markerFactory;
public Log4jLoggerFactory(final 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, validateContext(context).getLogger(key), name);
}
@Override
protected LoggerContext getContext() {
final Class<?> anchor = LogManager.getFactory().isClassLoaderDependent()
? StackLocatorUtil.getCallerClass(Log4jLoggerFactory.class, CALLER_PREDICATE)
: null;
LOGGER.trace("Log4jLoggerFactory.getContext() found anchor {}", anchor);
return anchor == null
? LogManager.getContext(false)
: getContext(anchor);
}
Log4jMarkerFactory getMarkerFactory() {
return markerFactory;
}
private LoggerContext validateContext(final LoggerContext context) {
if (TO_SLF4J_CONTEXT.equals(context.getClass().getName())) {
throw new LoggingException("log4j-slf4j-impl cannot be present with log4j-to-slf4j");
}
return context;
}
}
/*
* 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();
ThreadContext.putAll(map);
}
}
/*
* 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 java.util.Objects;
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 (!Objects.equals(marker, 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() {
return 31 + Objects.hashCode(marker);
}
@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;
}
}
/*
* 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);
}
}
/*
* 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);
}
}
/*
* 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 = "2.0.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 getRequestedApiVersion() {
return REQUESTED_API_VERSION;
}
@Override
public void initialize() {
markerFactory = new Log4jMarkerFactory();
loggerFactory = new Log4jLoggerFactory(markerFactory);
mdcAdapter = new Log4jMDCAdapter();
}
}
/*
* 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;
org.apache.logging.slf4j.SLF4JServiceProvider
\ No newline at end of file
<!-- 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>
<!--
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>
/*
* 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.other.pkg;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.status.StatusData;
import org.apache.logging.log4j.status.StatusListener;
import org.apache.logging.log4j.status.StatusLogger;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import static org.junit.Assert.assertEquals;
/**
* Test LoggerContext lookups by verifying the anchor class representing calling code.
*/
public class LoggerContextAnchorTest {
private static final String PREFIX = "Log4jLoggerFactory.getContext() found anchor class ";
@Test
public void testLoggerFactoryLookupClass() {
String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger(LoggerContextAnchorTest.class));
assertEquals(getClass().getName(), fqcn);
}
@Test
public void testLoggerFactoryLookupString() {
String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger("custom.logger"));
assertEquals(getClass().getName(), fqcn);
}
@Test
public void testLoggerFactoryGetILoggerFactoryLookup() {
String fqcn = getAnchorFqcn(() -> LoggerFactory.getILoggerFactory().getLogger("custom.logger"));
assertEquals(getClass().getName(), fqcn);
}
private static String getAnchorFqcn(Runnable runnable) {
List<String> results = new CopyOnWriteArrayList<>();
StatusListener listener = new StatusListener() {
@Override
public void log(StatusData data) {
String formattedMessage = data.getMessage().getFormattedMessage();
if (formattedMessage.startsWith(PREFIX)) {
results.add(formattedMessage.substring(PREFIX.length()));
}
}
@Override
public Level getStatusLevel() {
return Level.TRACE;
}
@Override
public void close() {
// nop
}
};
StatusLogger statusLogger = StatusLogger.getLogger();
statusLogger.registerListener(listener);
try {
runnable.run();
if (results.isEmpty()) {
throw new AssertionError("Failed to locate an anchor lookup status message");
}
if (results.size() > 1) {
throw new AssertionError("Found multiple anchor lines: " + results);
}
return results.get(0);
} finally {
statusLogger.removeListener(listener);
}
}
}
/*
* 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);
}
}
}
/*
* 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;
}
}
/*
* 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);
}
}
}
/*
* 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
/*
* 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);
}
}
/*
* 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.LifeCycle;
import org.apache.logging.log4j.spi.LoggerContext;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.util.Set;
import static org.junit.Assert.assertTrue;
/**
* Tests cleanup of the LoggerContexts.
*/
public class LoggerContextTest {
@Test
public void testCleanup() throws Exception {
Log4jLoggerFactory factory = (Log4jLoggerFactory) LoggerFactory.getILoggerFactory();
factory.getLogger("test");
Set<LoggerContext> set = factory.getLoggerContexts();
LoggerContext ctx1 = set.toArray(LoggerContext.EMPTY_ARRAY)[0];
assertTrue("LoggerContext is not enabled for shutdown", ctx1 instanceof LifeCycle);
((LifeCycle) ctx1).stop();
set = factory.getLoggerContexts();
assertTrue("Expected no LoggerContexts", set.isEmpty());
}
}
/*
* 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 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.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 {} MDC{}" + 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();
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment