You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2015/08/08 07:40:43 UTC

logging-log4j2 git commit: First branch commit of LevelLogger idea.

Repository: logging-log4j2
Updated Branches:
  refs/heads/level-logger [created] 3771398e3


First branch commit of LevelLogger idea.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/3771398e
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/3771398e
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/3771398e

Branch: refs/heads/level-logger
Commit: 3771398e35183588b4670e40bf7f40eeb82a87d1
Parents: e579cf7
Author: ggregory <gg...@apache.org>
Authored: Fri Aug 7 22:36:13 2015 -0700
Committer: ggregory <gg...@apache.org>
Committed: Fri Aug 7 22:36:13 2015 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/LogManager.java    |   5 +
 .../logging/log4j/levellogger/LevelLogger.java  | 351 +++++++++
 .../log4j/levellogger/LevelLoggerImpl.java      | 178 +++++
 .../logging/log4j/levellogger/LevelLoggers.java |  78 ++
 .../org/apache/logging/log4j/LoggerTest.java    | 786 ++++++++++---------
 5 files changed, 1011 insertions(+), 387 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3771398e/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
index d5ad911..d638180 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import org.apache.logging.log4j.levellogger.LevelLoggers;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.message.StringFormatterMessageFactory;
 import org.apache.logging.log4j.simple.SimpleLoggerContextFactory;
@@ -415,6 +416,10 @@ public class LogManager {
             StringFormatterMessageFactory.INSTANCE);
     }
 
+    public static LevelLoggers getLevelLoggers(final String name) {
+        return new LevelLoggers(getLogger(name));
+    }
+
     /**
      * Returns a Logger with the name of the calling class.
      * @return The Logger for the calling class.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3771398e/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLogger.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLogger.java b/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLogger.java
new file mode 100644
index 0000000..89412c0
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLogger.java
@@ -0,0 +1,351 @@
+/*
+ * 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.log4j.levellogger;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+
+/**
+ * This is the central interface in the log4j package. Most logging operations, except configuration, are done through
+ * this interface.
+ *
+ * <p>
+ * The canonical way to obtain a Logger for a class is through {@link LogManager#getLogger()}. Typically, each class
+ * gets its own Logger named after its fully qualified class name (the default Logger name when obtained through the
+ * {@link LogManager#getLogger()} method). Thus, the simplest way to use this would be like so:
+ * </p>
+ * 
+ * <pre>
+ * public class MyClass {
+ *     private static final LevelLogger LOGGER = LogManager.getLevelLogger();
+ *     // ...
+ * }
+ * </pre>
+ * <p>
+ * For ease of filtering, searching, sorting, etc., it is generally a good idea to create Loggers for each class rather
+ * than sharing Loggers. Instead, {@link Marker Markers} should be used for shared, filterable identification.
+ * </p>
+ * <p>
+ * For service provider implementations, it is recommended to extend the
+ * {@link org.apache.logging.log4j.spi.AbstractLogger} class rather than implementing this interface directly.
+ * </p>
+ */
+public interface LevelLogger {
+
+    /**
+     * Logs an exception or error that has been caught. Normally, one may wish to provide additional information with an
+     * exception while logging it; in these cases, one would not use this method. In other cases where simply logging
+     * the fact that an exception was swallowed somewhere (e.g., at the top of the stack trace in a {@code main()}
+     * method), this method is ideal for it.
+     *
+     * @param t
+     *        The Throwable.
+     */
+    void catching(Throwable t);
+
+    /**
+     * Logs entry to a method. Used when the method in question has no parameters or when the parameters should not be
+     * logged.
+     */
+    void entry();
+
+    /**
+     * Logs entry to a method along with its parameters. For example,
+     * 
+     * <pre>
+     * public void doSomething(String foo, int bar) {
+     *     LOGGER.entry(foo, bar);
+     *     // do something
+     * }
+     * </pre>
+     * <p>
+     * The use of methods such as this are more effective when combined with aspect-oriented programming or other
+     * bytecode manipulation tools. It can be rather tedious (and messy) to use this type of method manually.
+     * </p>
+     *
+     * @param params
+     *        The parameters to the method. TODO Use of varargs results in array creation which can be a substantial
+     *        portion of no-op case. LogMF/LogSF provides several overrides to avoid vararg except in edge cases. (RG)
+     *        LogMF and LogSF implement these in LogXF which calls logger.callAppenders. callAppenders is part of the
+     *        implementation and cannot be used by the API. Adding more methods here and in AbstractLogger is
+     *        sufficient.
+     */
+    void entry(Object... params);
+
+    /**
+     * Logs exit from a method. Used for methods that do not return anything.
+     */
+    void exit();
+
+    /**
+     * Logs exiting from a method with the result. This may be coded as:
+     * 
+     * <pre>
+     * return LOGGER.exit(myResult);
+     * </pre>
+     *
+     * @param <R>
+     *        The type of the parameter and object being returned.
+     * @param result
+     *        The result being returned from the method call.
+     * @return the result.
+     */
+    <R> R exit(R result);
+
+    /**
+     * Gets the Level associated with the Logger.
+     *
+     * @return the Level associate with the Logger.
+     */
+    Level getLevel();
+
+    /**
+     * Gets the message factory used to convert message Objects and Strings into actual log Messages.
+     *
+     * @return the message factory.
+     */
+    MessageFactory getMessageFactory();
+
+    /**
+     * Gets the logger name.
+     *
+     * @return the logger name.
+     */
+    String getName();
+
+    /**
+     * Checks whether this Logger is enabled for the {@link Level#DEBUG DEBUG} Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level DEBUG, {@code false} otherwise.
+     */
+    boolean isEnabled();
+
+    /**
+     * Checks whether this Logger is enabled for the the given Level.
+     * <p>
+     * Note that passing in {@link Level#OFF OFF} always returns {@code true}.
+     * </p>
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level, {@code false} otherwise.
+     */
+    boolean isEnabled(Level level);
+
+    /**
+     * Checks whether this logger is enabled at the specified level and an optional Marker.
+     *
+     * @param marker
+     *        The marker data specific to this log statement.
+     * @return boolean - {@code true} if this Logger is enabled for level {@link Level#WARN WARN}, {@code false}
+     *         otherwise.
+     */
+    boolean isEnabled(Marker marker);
+
+    /**
+     * Logs a message with the specific Marker at the given level.
+     *
+     * 
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param msg
+     *        the message string to be logged
+     */
+    void log(Marker marker, Message msg);
+
+    /**
+     * Logs a message with the specific Marker at the given level.
+     *
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param msg
+     *        the message string to be logged
+     * @param t
+     *        A Throwable or null.
+     */
+    void log(Marker marker, Message msg, Throwable t);
+
+    /**
+     * Logs a message object with the given level.
+     *
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param message
+     *        the message object to log.
+     */
+    void log(Marker marker, Object message);
+
+    /**
+     * Logs a message at the given level including the stack trace of the {@link Throwable} <code>t</code> passed as
+     * parameter.
+     *
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param message
+     *        the message to log.
+     * @param t
+     *        the exception to log, including its stack trace.
+     */
+    void log(Marker marker, Object message, Throwable t);
+
+    /**
+     * Logs a message object with the given level.
+     *
+     * 
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param message
+     *        the message object to log.
+     */
+    void log(Marker marker, String message);
+
+    /**
+     * Logs a message with parameters at the given level.
+     *
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param message
+     *        the message to log; the format depends on the message factory.
+     * @param params
+     *        parameters to the message.
+     * @see #getMessageFactory()
+     */
+    void log(Marker marker, String message, Object... params);
+
+    /**
+     * Logs a message at the given level including the stack trace of the {@link Throwable} <code>t</code> passed as
+     * parameter.
+     *
+     * @param marker
+     *        the marker data specific to this log statement
+     * @param message
+     *        the message to log.
+     * @param t
+     *        the exception to log, including its stack trace.
+     */
+    void log(Marker marker, String message, Throwable t);
+
+    /**
+     * Logs a message with the specific Marker at the given level.
+     *
+     * @param msg
+     *        the message string to be logged
+     */
+    void log(Message msg);
+
+    /**
+     * Logs a message with the specific Marker at the given level.
+     *
+     * @param msg
+     *        the message string to be logged
+     * @param t
+     *        A Throwable or null.
+     */
+    void log(Message msg, Throwable t);
+
+    /**
+     * Logs a message object with the given level.
+     *
+     * @param message
+     *        the message object to log.
+     */
+    void log(Object message);
+
+    /**
+     * Logs a message at the given level including the stack trace of the {@link Throwable} <code>t</code> passed as
+     * parameter.
+     *
+     * @param message
+     *        the message to log.
+     * @param t
+     *        the exception to log, including its stack trace.
+     */
+    void log(Object message, Throwable t);
+
+    /**
+     * Logs a message object with the given level.
+     *
+     * @param message
+     *        the message string to log.
+     */
+    void log(String message);
+
+    /**
+     * Logs a message with parameters at the given level.
+     *
+     * 
+     * @param message
+     *        the message to log; the format depends on the message factory.
+     * @param params
+     *        parameters to the message.
+     * @see #getMessageFactory()
+     */
+    void log(String message, Object... params);
+
+    /**
+     * Logs a message at the given level including the stack trace of the {@link Throwable} <code>t</code> passed as
+     * parameter.
+     *
+     * 
+     * @param message
+     *        the message to log.
+     * @param t
+     *        the exception to log, including its stack trace.
+     */
+    void log(String message, Throwable t);
+
+    /**
+     * Logs a formatted message using the specified format string and arguments.
+     *
+     * 
+     * @param marker
+     *        the marker data specific to this log statement.
+     * @param format
+     *        The format String.
+     * @param params
+     *        Arguments specified by the format.
+     */
+    void printf(Marker marker, String format, Object... params);
+
+    /**
+     * Logs a formatted message using the specified format string and arguments.
+     *
+     * 
+     * @param format
+     *        The format String.
+     * @param params
+     *        Arguments specified by the format.
+     */
+    void printf(String format, Object... params);
+
+    /**
+     * Logs an exception or error to be thrown. This may be coded as:
+     * 
+     * <pre>
+     * throw logger.throwing(myException);
+     * </pre>
+     *
+     * @param <T>
+     *        the Throwable type.
+     * @param t
+     *        The Throwable.
+     * @return the Throwable.
+     */
+    <T extends Throwable> T throwing(T t);
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3771398e/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggerImpl.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggerImpl.java b/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggerImpl.java
new file mode 100644
index 0000000..3e9f71f
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggerImpl.java
@@ -0,0 +1,178 @@
+/*
+ * 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.log4j.levellogger;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+
+class LevelLoggerImpl implements LevelLogger {
+
+	private final Level level;
+
+	private final Logger logger;
+
+	LevelLoggerImpl(final Level level, final Logger logger) {
+		super();
+		this.level = level;
+		this.logger = logger;
+	}
+
+	@Override
+	public void catching(final Throwable t) {
+		logger.catching(level, t);
+	}
+
+	@Override
+	public void entry() {
+		logger.entry();
+	}
+
+	@Override
+	public void entry(final Object... params) {
+		logger.entry(params);
+	}
+
+	@Override
+	public void exit() {
+		logger.exit();
+	}
+
+	@Override
+	public <R> R exit(final R result) {
+		return logger.exit(result);
+	}
+
+	@Override
+	public Level getLevel() {
+		return level;
+	}
+
+	@Override
+	public MessageFactory getMessageFactory() {
+		return logger.getMessageFactory();
+	}
+
+	@Override
+	public String getName() {
+		return logger.getName();
+	}
+
+	@Override
+	public boolean isEnabled() {
+		return logger.isEnabled(level);
+	}
+
+	@Override
+	public boolean isEnabled(final Level level) {
+		return this.level.isLessSpecificThan(level);
+	}
+
+	@Override
+	public boolean isEnabled(final Marker marker) {
+		return logger.isEnabled(level, marker);
+	}
+
+	@Override
+	public void log(final Marker marker, final Message msg) {
+		logger.log(level, marker, msg);
+	}
+
+	@Override
+	public void log(final Marker marker, final Message msg, final Throwable t) {
+		logger.log(level, marker, msg, t);
+	}
+
+	@Override
+	public void log(final Marker marker, final Object message) {
+		logger.log(level, marker, message);
+	}
+
+	@Override
+	public void log(final Marker marker, final Object message, final Throwable t) {
+		logger.log(level, marker, message, t);
+	}
+
+	@Override
+	public void log(final Marker marker, final String message) {
+		logger.log(level, marker, message);
+	}
+
+	@Override
+	public void log(final Marker marker, final String message, final Object... params) {
+		logger.log(level, marker, message, params);
+	}
+
+	@Override
+	public void log(final Marker marker, final String message, final Throwable t) {
+		logger.log(level, marker, message, t);
+	}
+
+	@Override
+	public void log(final Message msg) {
+		logger.log(level, msg);
+	}
+
+	@Override
+	public void log(final Message msg, final Throwable t) {
+		logger.log(level, msg, t);
+	}
+
+	@Override
+	public void log(final Object message) {
+		logger.log(level, message);
+	}
+
+	@Override
+	public void log(final Object message, final Throwable t) {
+		logger.log(level, message, t);
+	}
+
+	@Override
+	public void log(final String message) {
+		logger.log(level, message);
+	}
+
+	@Override
+	public void log(final String message, final Object... params) {
+		logger.log(level, message, params);
+	}
+
+	@Override
+	public void log(final String message, final Throwable t) {
+		logger.log(level, message, t);
+	}
+
+	@Override
+	public void printf(final Marker marker, final String format, final Object... params) {
+		logger.printf(level, marker, format, params);
+	}
+
+	@Override
+	public void printf(final String format, final Object... params) {
+		logger.printf(level, format, params);
+	}
+
+	@Override
+	public <T extends Throwable> T throwing(final T t) {
+		return logger.throwing(t);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3771398e/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggers.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggers.java b/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggers.java
new file mode 100644
index 0000000..1104de2
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/levellogger/LevelLoggers.java
@@ -0,0 +1,78 @@
+/*
+ * 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.log4j.levellogger;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+
+public class LevelLoggers {
+
+	public LevelLogger all;
+	public LevelLogger debug;
+	public LevelLogger error;
+	public LevelLogger fatal;
+	public LevelLogger info;
+	public LevelLogger off;
+	public LevelLogger trace;
+	public LevelLogger warn;
+
+	public LevelLoggers(final Logger logger) {
+		super();
+		all = new LevelLoggerImpl(Level.ALL, logger);
+		trace = new LevelLoggerImpl(Level.TRACE, logger);
+		debug = new LevelLoggerImpl(Level.DEBUG, logger);
+		info = new LevelLoggerImpl(Level.INFO, logger);
+		warn = new LevelLoggerImpl(Level.WARN, logger);
+		error = new LevelLoggerImpl(Level.ERROR, logger);
+		fatal = new LevelLoggerImpl(Level.FATAL, logger);
+		off = new LevelLoggerImpl(Level.OFF, logger);
+	}
+
+	public LevelLogger all() {
+		return all;
+	}
+
+	public LevelLogger debug() {
+		return debug;
+	}
+
+	public LevelLogger error() {
+		return error;
+	}
+
+	public LevelLogger fatal() {
+		return fatal;
+	}
+
+	public LevelLogger info() {
+		return info;
+	}
+
+	public LevelLogger off() {
+		return off;
+	}
+
+	public LevelLogger trace() {
+		return trace;
+	}
+
+	public LevelLogger warn() {
+		return warn;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3771398e/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
index 5679331..63126be 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
@@ -1,387 +1,399 @@
-/*
- * 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.log4j;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.logging.log4j.message.ParameterizedMessageFactory;
-import org.apache.logging.log4j.message.StringFormatterMessageFactory;
-import org.apache.logging.log4j.message.StructuredDataMessage;
-import org.apache.logging.log4j.util.Strings;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.hamcrest.CoreMatchers.*;
-
-import static org.junit.Assert.*;
-
-/**
- *
- */
-public class LoggerTest {
-
-    private static class TestParameterizedMessageFactory {
-        // empty
-    }
-
-    private static class TestStringFormatterMessageFactory {
-        // empty
-    }
-
-    TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");
-    List<String> results = logger.getEntries();
-
-    @Test
-    public void basicFlow() {
-        logger.entry();
-        logger.exit();
-        assertEquals(2, results.size());
-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTRY[ FLOW ] TRACE entry"));
-        assertThat("incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE exit"));
-
-    }
-
-    @Test
-    public void catching() {
-        try {
-            throw new NullPointerException();
-        } catch (final Exception e) {
-            logger.catching(e);
-            assertEquals(1, results.size());
-            assertThat("Incorrect Catching",
-                    results.get(0), startsWith("CATCHING[ EXCEPTION ] ERROR catching java.lang.NullPointerException"));
-        }
-    }
-
-    @Test
-    public void debug() {
-        logger.debug("Debug message");
-        assertEquals(1, results.size());
-        assertTrue("Incorrect message", results.get(0).startsWith(" DEBUG Debug message"));
-    }
-
-    @Test
-    public void debugObject() {
-        logger.debug(new Date());
-        assertEquals(1, results.size());
-        assertTrue("Invalid length", results.get(0).length() > 7);
-    }
-
-    @Test
-    public void debugWithParms() {
-        logger.debug("Hello, {}", "World");
-        assertEquals(1, results.size());
-        assertTrue("Incorrect substitution", results.get(0).startsWith(" DEBUG Hello, World"));
-    }
-
-    @Test
-    public void debugWithParmsAndThrowable() {
-        logger.debug("Hello, {}", "World", new RuntimeException("Test Exception"));
-        assertEquals(1, results.size());
-        assertTrue("Unexpected results: " + results.get(0),
-            results.get(0).startsWith(" DEBUG Hello, World java.lang.RuntimeException: Test Exception"));
-    }
-
-    @Test
-    public void getFormatterLogger() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger();
-        final TestLogger altLogger = (TestLogger) LogManager.getFormatterLogger(getClass());
-        assertEquals(testLogger.getName(), altLogger.getName());
-        assertNotNull(testLogger);
-        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
-        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getFormatterLogger_Class() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(TestStringFormatterMessageFactory.class);
-        assertNotNull(testLogger);
-        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
-        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getFormatterLogger_Object() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(new TestStringFormatterMessageFactory());
-        assertNotNull(testLogger);
-        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
-        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getFormatterLogger_String() {
-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger("getLogger_String_StringFormatterMessageFactory");
-        assertNotNull(testLogger);
-        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_Class_ParameterizedMessageFactory() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestParameterizedMessageFactory.class,
-                messageFactory);
-        assertNotNull(testLogger);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        testLogger.debug("{}", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_Class_StringFormatterMessageFactory() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestStringFormatterMessageFactory.class,
-                StringFormatterMessageFactory.INSTANCE);
-        assertNotNull(testLogger);
-        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_Object_ParameterizedMessageFactory() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestParameterizedMessageFactory(),
-                messageFactory);
-        assertNotNull(testLogger);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        testLogger.debug("{}", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_Object_StringFormatterMessageFactory() {
-        // The TestLogger logger was already created in an instance variable for this class.
-        // The message factory is only used when the logger is created.
-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestStringFormatterMessageFactory(),
-                messageFactory);
-        assertNotNull(testLogger);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_String_MessageFactoryMismatch() {
-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
-                messageFactory);
-        assertNotNull(testLogger);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        final TestLogger testLogger2 = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
-                ParameterizedMessageFactory.INSTANCE);
-        //TODO: How to test?
-        //This test context always creates new loggers, other test context impls I tried fail other tests.
-        //assertEquals(messageFactory, testLogger2.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_String_ParameterizedMessageFactory() {
-        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_ParameterizedMessageFactory",
-                messageFactory);
-        assertNotNull(testLogger);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        testLogger.debug("{}", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLogger_String_StringFormatterMessageFactory() {
-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",
-                messageFactory);
-        assertNotNull(testLogger);
-        assertEquals(messageFactory, testLogger.getMessageFactory());
-        testLogger.debug("%,d", Integer.MAX_VALUE);
-        assertEquals(1, testLogger.getEntries().size());
-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
-    }
-
-    @Test
-    public void getLoggerByClass() {
-        final Logger classLogger = LogManager.getLogger(LoggerTest.class);
-        assertNotNull(classLogger);
-    }
-
-    @Test
-    public void getLoggerByNullClass() {
-        // Returns a SimpleLogger
-        assertNotNull(LogManager.getLogger((Class<?>) null));
-    }
-
-    @Test
-    public void getLoggerByNullObject() {
-        // Returns a SimpleLogger
-        assertNotNull(LogManager.getLogger((Object) null));
-    }
-
-    @Test
-    public void getLoggerByNullString() {
-        // Returns a SimpleLogger
-        assertNotNull(LogManager.getLogger((String) null));
-    }
-
-    @Test
-    public void getLoggerByObject() {
-        final Logger classLogger = LogManager.getLogger(this);
-        assertNotNull(classLogger);
-        assertEquals(classLogger, LogManager.getLogger(LoggerTest.class));
-    }
-
-    @Test
-    public void getRootLogger() {
-        assertNotNull(LogManager.getRootLogger());
-        assertNotNull(LogManager.getLogger(Strings.EMPTY));
-        assertNotNull(LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
-        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(Strings.EMPTY));
-        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
-    }
-
-    @Test
-    public void isAllEnabled() {
-        assertTrue("Incorrect level", logger.isEnabled(Level.ALL));
-    }
-
-    @Test
-    public void isDebugEnabled() {
-        assertTrue("Incorrect level", logger.isDebugEnabled());
-        assertTrue("Incorrect level", logger.isEnabled(Level.DEBUG));
-    }
-
-    @Test
-    public void isErrorEnabled() {
-        assertTrue("Incorrect level", logger.isErrorEnabled());
-        assertTrue("Incorrect level", logger.isEnabled(Level.ERROR));
-    }
-
-    @Test
-    public void isFatalEnabled() {
-        assertTrue("Incorrect level", logger.isFatalEnabled());
-        assertTrue("Incorrect level", logger.isEnabled(Level.FATAL));
-    }
-
-    @Test
-    public void isInfoEnabled() {
-        assertTrue("Incorrect level", logger.isInfoEnabled());
-        assertTrue("Incorrect level", logger.isEnabled(Level.INFO));
-    }
-
-    @Test
-    public void isOffEnabled() {
-        assertTrue("Incorrect level", logger.isEnabled(Level.OFF));
-    }
-
-    @Test
-    public void isTraceEnabled() {
-        assertTrue("Incorrect level", logger.isTraceEnabled());
-        assertTrue("Incorrect level", logger.isEnabled(Level.TRACE));
-    }
-
-    @Test
-    public void isWarnEnabled() {
-        assertTrue("Incorrect level", logger.isWarnEnabled());
-        assertTrue("Incorrect level", logger.isEnabled(Level.WARN));
-    }
-
-    @Test
-    public void mdc() {
-
-        ThreadContext.put("TestYear", Integer.valueOf(2010).toString());
-        logger.debug("Debug message");
-        ThreadContext.clearMap();
-        logger.debug("Debug message");
-        assertEquals(2, results.size());
-        assertTrue("Incorrect MDC: " + results.get(0),
-            results.get(0).startsWith(" DEBUG Debug message {TestYear=2010}"));
-        assertTrue("MDC not cleared?: " + results.get(1),
-            results.get(1).startsWith(" DEBUG Debug message"));
-    }
-
-    @Test
-    public void printf() {
-        logger.printf(Level.DEBUG, "Debug message %d", 1);
-        logger.printf(Level.DEBUG, MarkerManager.getMarker("Test"), "Debug message %d", 2);
-        assertEquals(2, results.size());
-        assertThat("Incorrect message", results.get(0), startsWith(" DEBUG Debug message 1"));
-        assertThat("Incorrect message", results.get(1), startsWith("Test DEBUG Debug message 2"));
-    }
-
-    @Before
-    public void setup() {
-        results.clear();
-    }
-
-    @Test
-    public void structuredData() {
-        ThreadContext.put("loginId", "JohnDoe");
-        ThreadContext.put("ipAddress", "192.168.0.120");
-        ThreadContext.put("locale", Locale.US.getDisplayName());
-        final StructuredDataMessage msg = new StructuredDataMessage("Audit@18060", "Transfer Complete", "Transfer");
-        msg.put("ToAccount", "123456");
-        msg.put("FromAccount", "123457");
-        msg.put("Amount", "200.00");
-        logger.info(MarkerManager.getMarker("EVENT"), msg);
-        ThreadContext.clearMap();
-        assertEquals(1, results.size());
-        assertThat("Incorrect structured data: ", results.get(0), startsWith(
-                "EVENT INFO Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete"));
-    }
-
-    @Test
-    public void throwing() {
-        logger.throwing(new IllegalArgumentException("Test Exception"));
-        assertEquals(1, results.size());
-        assertThat("Incorrect Throwing",
-                results.get(0), startsWith("THROWING[ EXCEPTION ] ERROR throwing java.lang.IllegalArgumentException: Test Exception"));
-    }
-}
+/*
+ * 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.log4j;
+
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.logging.log4j.levellogger.LevelLoggers;
+import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.StringFormatterMessageFactory;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.util.Strings;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class LoggerTest {
+
+    private static class TestParameterizedMessageFactory {
+        // empty
+    }
+
+    private static class TestStringFormatterMessageFactory {
+        // empty
+    }
+
+    TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");
+    List<String> results = logger.getEntries();
+
+    @Test
+    public void basicFlow() {
+        logger.entry();
+        logger.exit();
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTRY[ FLOW ] TRACE entry"));
+        assertThat("incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE exit"));
+
+    }
+
+    @Test
+    public void catching() {
+        try {
+            throw new NullPointerException();
+        } catch (final Exception e) {
+            logger.catching(e);
+            assertEquals(1, results.size());
+            assertThat("Incorrect Catching",
+                    results.get(0), startsWith("CATCHING[ EXCEPTION ] ERROR catching java.lang.NullPointerException"));
+        }
+    }
+
+    @Test
+    public void debug() {
+        logger.debug("Debug message");
+        assertEquals(1, results.size());
+        assertTrue("Incorrect message", results.get(0).startsWith(" DEBUG Debug message"));
+    }
+
+    // Should be in own class
+    @Test
+    public void loggerLevelDebug() {
+    	LevelLoggers loggers = LogManager.getLevelLoggers(logger.getName());
+    	loggers.debug.log("Debug message");
+        assertEquals(1, results.size());
+        assertTrue("Incorrect message", results.get(0).startsWith(" DEBUG Debug message"));
+    }
+
+    @Test
+    public void debugObject() {
+        logger.debug(new Date());
+        assertEquals(1, results.size());
+        assertTrue("Invalid length", results.get(0).length() > 7);
+    }
+
+    @Test
+    public void debugWithParms() {
+        logger.debug("Hello, {}", "World");
+        assertEquals(1, results.size());
+        assertTrue("Incorrect substitution", results.get(0).startsWith(" DEBUG Hello, World"));
+    }
+
+    @Test
+    public void debugWithParmsAndThrowable() {
+        logger.debug("Hello, {}", "World", new RuntimeException("Test Exception"));
+        assertEquals(1, results.size());
+        assertTrue("Unexpected results: " + results.get(0),
+            results.get(0).startsWith(" DEBUG Hello, World java.lang.RuntimeException: Test Exception"));
+    }
+
+    @Test
+    public void getFormatterLogger() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger();
+        final TestLogger altLogger = (TestLogger) LogManager.getFormatterLogger(getClass());
+        assertEquals(testLogger.getName(), altLogger.getName());
+        assertNotNull(testLogger);
+        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
+        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getFormatterLogger_Class() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(TestStringFormatterMessageFactory.class);
+        assertNotNull(testLogger);
+        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
+        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getFormatterLogger_Object() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(new TestStringFormatterMessageFactory());
+        assertNotNull(testLogger);
+        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
+        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getFormatterLogger_String() {
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger("getLogger_String_StringFormatterMessageFactory");
+        assertNotNull(testLogger);
+        assertTrue(testLogger.getMessageFactory() instanceof StringFormatterMessageFactory);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Class_ParameterizedMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestParameterizedMessageFactory.class,
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        testLogger.debug("{}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Class_StringFormatterMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestStringFormatterMessageFactory.class,
+                StringFormatterMessageFactory.INSTANCE);
+        assertNotNull(testLogger);
+        assertEquals(StringFormatterMessageFactory.INSTANCE, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Object_ParameterizedMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestParameterizedMessageFactory(),
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        testLogger.debug("{}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Object_StringFormatterMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestStringFormatterMessageFactory(),
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_MessageFactoryMismatch() {
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        final TestLogger testLogger2 = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
+                ParameterizedMessageFactory.INSTANCE);
+        //TODO: How to test?
+        //This test context always creates new loggers, other test context impls I tried fail other tests.
+        //assertEquals(messageFactory, testLogger2.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_ParameterizedMessageFactory() {
+        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_ParameterizedMessageFactory",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        testLogger.debug("{}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_StringFormatterMessageFactory() {
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEquals(messageFactory, testLogger.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLoggerByClass() {
+        final Logger classLogger = LogManager.getLogger(LoggerTest.class);
+        assertNotNull(classLogger);
+    }
+
+    @Test
+    public void getLoggerByNullClass() {
+        // Returns a SimpleLogger
+        assertNotNull(LogManager.getLogger((Class<?>) null));
+    }
+
+    @Test
+    public void getLoggerByNullObject() {
+        // Returns a SimpleLogger
+        assertNotNull(LogManager.getLogger((Object) null));
+    }
+
+    @Test
+    public void getLoggerByNullString() {
+        // Returns a SimpleLogger
+        assertNotNull(LogManager.getLogger((String) null));
+    }
+
+    @Test
+    public void getLoggerByObject() {
+        final Logger classLogger = LogManager.getLogger(this);
+        assertNotNull(classLogger);
+        assertEquals(classLogger, LogManager.getLogger(LoggerTest.class));
+    }
+
+    @Test
+    public void getRootLogger() {
+        assertNotNull(LogManager.getRootLogger());
+        assertNotNull(LogManager.getLogger(Strings.EMPTY));
+        assertNotNull(LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
+        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(Strings.EMPTY));
+        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
+    }
+
+    @Test
+    public void isAllEnabled() {
+        assertTrue("Incorrect level", logger.isEnabled(Level.ALL));
+    }
+
+    @Test
+    public void isDebugEnabled() {
+        assertTrue("Incorrect level", logger.isDebugEnabled());
+        assertTrue("Incorrect level", logger.isEnabled(Level.DEBUG));
+    }
+
+    @Test
+    public void isErrorEnabled() {
+        assertTrue("Incorrect level", logger.isErrorEnabled());
+        assertTrue("Incorrect level", logger.isEnabled(Level.ERROR));
+    }
+
+    @Test
+    public void isFatalEnabled() {
+        assertTrue("Incorrect level", logger.isFatalEnabled());
+        assertTrue("Incorrect level", logger.isEnabled(Level.FATAL));
+    }
+
+    @Test
+    public void isInfoEnabled() {
+        assertTrue("Incorrect level", logger.isInfoEnabled());
+        assertTrue("Incorrect level", logger.isEnabled(Level.INFO));
+    }
+
+    @Test
+    public void isOffEnabled() {
+        assertTrue("Incorrect level", logger.isEnabled(Level.OFF));
+    }
+
+    @Test
+    public void isTraceEnabled() {
+        assertTrue("Incorrect level", logger.isTraceEnabled());
+        assertTrue("Incorrect level", logger.isEnabled(Level.TRACE));
+    }
+
+    @Test
+    public void isWarnEnabled() {
+        assertTrue("Incorrect level", logger.isWarnEnabled());
+        assertTrue("Incorrect level", logger.isEnabled(Level.WARN));
+    }
+
+    @Test
+    public void mdc() {
+
+        ThreadContext.put("TestYear", Integer.valueOf(2010).toString());
+        logger.debug("Debug message");
+        ThreadContext.clearMap();
+        logger.debug("Debug message");
+        assertEquals(2, results.size());
+        assertTrue("Incorrect MDC: " + results.get(0),
+            results.get(0).startsWith(" DEBUG Debug message {TestYear=2010}"));
+        assertTrue("MDC not cleared?: " + results.get(1),
+            results.get(1).startsWith(" DEBUG Debug message"));
+    }
+
+    @Test
+    public void printf() {
+        logger.printf(Level.DEBUG, "Debug message %d", 1);
+        logger.printf(Level.DEBUG, MarkerManager.getMarker("Test"), "Debug message %d", 2);
+        assertEquals(2, results.size());
+        assertThat("Incorrect message", results.get(0), startsWith(" DEBUG Debug message 1"));
+        assertThat("Incorrect message", results.get(1), startsWith("Test DEBUG Debug message 2"));
+    }
+
+    @Before
+    public void setup() {
+        results.clear();
+    }
+
+    @Test
+    public void structuredData() {
+        ThreadContext.put("loginId", "JohnDoe");
+        ThreadContext.put("ipAddress", "192.168.0.120");
+        ThreadContext.put("locale", Locale.US.getDisplayName());
+        final StructuredDataMessage msg = new StructuredDataMessage("Audit@18060", "Transfer Complete", "Transfer");
+        msg.put("ToAccount", "123456");
+        msg.put("FromAccount", "123457");
+        msg.put("Amount", "200.00");
+        logger.info(MarkerManager.getMarker("EVENT"), msg);
+        ThreadContext.clearMap();
+        assertEquals(1, results.size());
+        assertThat("Incorrect structured data: ", results.get(0), startsWith(
+                "EVENT INFO Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete"));
+    }
+
+    @Test
+    public void throwing() {
+        logger.throwing(new IllegalArgumentException("Test Exception"));
+        assertEquals(1, results.size());
+        assertThat("Incorrect Throwing",
+                results.get(0), startsWith("THROWING[ EXCEPTION ] ERROR throwing java.lang.IllegalArgumentException: Test Exception"));
+    }
+}