You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2018/07/06 05:41:05 UTC

[2/2] logging-log4j2 git commit: LOG4J2-2305 - Create separate implementation for SLF4J 1.8

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 <rg...@apache.org>
Authored: Thu Jul 5 22:40:43 2018 -0700
Committer: Ralph Goers <rg...@apache.org>
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 &#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>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();
+    }
+}