diff --git a/slf4j-api/src/main/java/org/slf4j/event/EventRecodingLogger.java b/slf4j-api/src/main/java/org/slf4j/event/EventRecodingLogger.java index 4a471f6fa..978d12de6 100755 --- a/slf4j-api/src/main/java/org/slf4j/event/EventRecodingLogger.java +++ b/slf4j-api/src/main/java/org/slf4j/event/EventRecodingLogger.java @@ -4,14 +4,28 @@ import org.slf4j.Logger; import org.slf4j.Marker; +import org.slf4j.helpers.MessageFormatter; import org.slf4j.helpers.SubstituteLogger; +/** + * + * This class is used to record events during the initialization phase of the + * underlying logging framework. It is called by {@link SubstituteLogger}. + * + * + * @author Ceki Gülcü + * @author Wessel van Norel + * + */ public class EventRecodingLogger implements Logger { String name; SubstituteLogger logger; Queue eventQueue; + // as an event recording logger we have no choice but to record all events + final static boolean RECORD_ALL_EVENTS = true; + public EventRecodingLogger(SubstituteLogger logger, Queue eventQueue) { this.logger = logger; this.name = logger.getName(); @@ -22,275 +36,288 @@ public String getName() { return name; } - private void recordEvent(Level level, String msg, Object[] args, Throwable throwable) { - recordEvent(level, null, msg, args, throwable); - } - - private void recordEvent(Level level, Marker marker, String msg, Object[] args, Throwable throwable) { - // System.out.println("recording logger:"+name+", msg:"+msg); - SubstituteLoggingEvent loggingEvent = new SubstituteLoggingEvent(); - loggingEvent.setTimeStamp(System.currentTimeMillis()); - loggingEvent.setLevel(level); - loggingEvent.setLogger(logger); - loggingEvent.setLoggerName(name); - loggingEvent.setMarker(marker); - loggingEvent.setMessage(msg); - loggingEvent.setArgumentArray(args); - loggingEvent.setThrowable(throwable); - loggingEvent.setThreadName(Thread.currentThread().getName()); - eventQueue.add(loggingEvent); - } - public boolean isTraceEnabled() { - return true; + return RECORD_ALL_EVENTS; } public void trace(String msg) { - recordEvent(Level.TRACE, msg, null, null); + recordEvent_0Args(Level.TRACE, null, msg, null); } public void trace(String format, Object arg) { - recordEvent(Level.TRACE, format, new Object[] { arg }, null); + recordEvent_1Args(Level.TRACE, null, format, arg); } public void trace(String format, Object arg1, Object arg2) { - recordEvent(Level.TRACE, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.TRACE, null, format, arg1, arg2); } public void trace(String format, Object... arguments) { - recordEvent(Level.TRACE, format, arguments, null); + recordEventArgArray(Level.TRACE, null, format, arguments); } public void trace(String msg, Throwable t) { - recordEvent(Level.TRACE, msg, null, t); + recordEvent_0Args(Level.TRACE, null, msg, t); } public boolean isTraceEnabled(Marker marker) { - return true; + return RECORD_ALL_EVENTS; } public void trace(Marker marker, String msg) { - recordEvent(Level.TRACE, marker, msg, null, null); - + recordEvent_0Args(Level.TRACE, marker, msg, null); } public void trace(Marker marker, String format, Object arg) { - recordEvent(Level.TRACE, marker, format, new Object[] { arg }, null); + recordEvent_1Args(Level.TRACE, marker, format, arg); } public void trace(Marker marker, String format, Object arg1, Object arg2) { - recordEvent(Level.TRACE, marker, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.TRACE, marker, format, arg1, arg2); } public void trace(Marker marker, String format, Object... argArray) { - recordEvent(Level.TRACE, marker, format, argArray, null); - + recordEventArgArray(Level.TRACE, marker, format, argArray); } public void trace(Marker marker, String msg, Throwable t) { - recordEvent(Level.TRACE, marker, msg, null, t); + recordEvent_0Args(Level.TRACE, marker, msg, t); } public boolean isDebugEnabled() { - return true; + return RECORD_ALL_EVENTS; } public void debug(String msg) { - recordEvent(Level.DEBUG, msg, null, null); + recordEvent_0Args(Level.DEBUG, null, msg, null); } public void debug(String format, Object arg) { - recordEvent(Level.DEBUG, format, new Object[] { arg }, null); - + recordEvent_1Args(Level.DEBUG, null, format, arg); } public void debug(String format, Object arg1, Object arg2) { - recordEvent(Level.DEBUG, format, new Object[] { arg1, arg2 }, null); - + recordEvent2Args(Level.DEBUG, null, format, arg1, arg2); } public void debug(String format, Object... arguments) { - recordEvent(Level.DEBUG, format, arguments, null); + recordEventArgArray(Level.DEBUG, null, format, arguments); } public void debug(String msg, Throwable t) { - recordEvent(Level.DEBUG, msg, null, t); + recordEvent_0Args(Level.DEBUG, null, msg, t); } public boolean isDebugEnabled(Marker marker) { - return true; + return RECORD_ALL_EVENTS; } public void debug(Marker marker, String msg) { - recordEvent(Level.DEBUG, marker, msg, null, null); + recordEvent_0Args(Level.DEBUG, marker, msg, null); } public void debug(Marker marker, String format, Object arg) { - recordEvent(Level.DEBUG, marker, format, new Object[] { arg }, null); + recordEvent_1Args(Level.DEBUG, marker, format, arg); } public void debug(Marker marker, String format, Object arg1, Object arg2) { - recordEvent(Level.DEBUG, marker, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.DEBUG, marker, format, arg1, arg2); } public void debug(Marker marker, String format, Object... arguments) { - recordEvent(Level.DEBUG, marker, format, arguments, null); + recordEventArgArray(Level.DEBUG, marker, format, arguments); } public void debug(Marker marker, String msg, Throwable t) { - recordEvent(Level.DEBUG, marker, msg, null, t); + recordEvent_0Args(Level.DEBUG, marker, msg, t); } public boolean isInfoEnabled() { - return true; + return RECORD_ALL_EVENTS; } public void info(String msg) { - recordEvent(Level.INFO, msg, null, null); + recordEvent_0Args(Level.INFO, null, msg, null); } public void info(String format, Object arg) { - recordEvent(Level.INFO, format, new Object[] { arg }, null); + recordEvent_1Args(Level.INFO, null, format, arg); } public void info(String format, Object arg1, Object arg2) { - recordEvent(Level.INFO, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.INFO, null, format, arg1, arg2); } public void info(String format, Object... arguments) { - recordEvent(Level.INFO, format, arguments, null); + recordEventArgArray(Level.INFO, null, format, arguments); } public void info(String msg, Throwable t) { - recordEvent(Level.INFO, msg, null, t); + recordEvent_0Args(Level.INFO, null, msg, t); } public boolean isInfoEnabled(Marker marker) { - return true; + return RECORD_ALL_EVENTS; } public void info(Marker marker, String msg) { - recordEvent(Level.INFO, marker, msg, null, null); + recordEvent_0Args(Level.INFO, marker, msg, null); } public void info(Marker marker, String format, Object arg) { - recordEvent(Level.INFO, marker, format, new Object[] { arg }, null); + recordEvent_1Args(Level.INFO, marker, format, arg); } public void info(Marker marker, String format, Object arg1, Object arg2) { - recordEvent(Level.INFO, marker, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.INFO, marker, format, arg1, arg2); } public void info(Marker marker, String format, Object... arguments) { - recordEvent(Level.INFO, marker, format, arguments, null); + recordEventArgArray(Level.INFO, marker, format, arguments); } public void info(Marker marker, String msg, Throwable t) { - recordEvent(Level.INFO, marker, msg, null, t); + recordEvent_0Args(Level.INFO, marker, msg, t); } public boolean isWarnEnabled() { - return true; + return RECORD_ALL_EVENTS; } public void warn(String msg) { - recordEvent(Level.WARN, msg, null, null); + recordEvent_0Args(Level.WARN, null, msg, null); } public void warn(String format, Object arg) { - recordEvent(Level.WARN, format, new Object[] { arg }, null); - + recordEvent_1Args(Level.WARN, null, format, arg); } public void warn(String format, Object arg1, Object arg2) { - recordEvent(Level.WARN, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.WARN, null, format, arg1, arg2); } public void warn(String format, Object... arguments) { - recordEvent(Level.WARN, format, arguments, null); + recordEventArgArray(Level.WARN, null, format, arguments); } public void warn(String msg, Throwable t) { - recordEvent(Level.WARN, msg, null, t); + recordEvent_0Args(Level.WARN, null, msg, t); } public boolean isWarnEnabled(Marker marker) { - return true; + return RECORD_ALL_EVENTS; } public void warn(Marker marker, String msg) { - recordEvent(Level.WARN, msg, null, null); + recordEvent_0Args(Level.WARN, marker, msg, null); } public void warn(Marker marker, String format, Object arg) { - recordEvent(Level.WARN, format, new Object[] { arg }, null); + recordEvent_1Args(Level.WARN, marker, format, arg); } public void warn(Marker marker, String format, Object arg1, Object arg2) { - recordEvent(Level.WARN, marker, format, new Object[] { arg1, arg2 }, null); - + recordEvent2Args(Level.WARN, marker, format, arg1, arg2); } public void warn(Marker marker, String format, Object... arguments) { - recordEvent(Level.WARN, marker, format, arguments, null); + recordEventArgArray(Level.WARN, marker, format, arguments); } public void warn(Marker marker, String msg, Throwable t) { - recordEvent(Level.WARN, marker, msg, null, t); + recordEvent_0Args(Level.WARN, marker, msg, t); } public boolean isErrorEnabled() { - return true; + return RECORD_ALL_EVENTS; } public void error(String msg) { - recordEvent(Level.ERROR, msg, null, null); + recordEvent_0Args(Level.ERROR, null, msg, null); } public void error(String format, Object arg) { - recordEvent(Level.ERROR, format, new Object[] { arg }, null); - + recordEvent_1Args(Level.ERROR, null, format, arg); } public void error(String format, Object arg1, Object arg2) { - recordEvent(Level.ERROR, format, new Object[] { arg1, arg2 }, null); - + recordEvent2Args(Level.ERROR, null, format, arg1, arg2); } public void error(String format, Object... arguments) { - recordEvent(Level.ERROR, format, arguments, null); - + recordEventArgArray(Level.ERROR, null, format, arguments); } public void error(String msg, Throwable t) { - recordEvent(Level.ERROR, msg, null, t); + recordEvent_0Args(Level.ERROR, null, msg, t); } public boolean isErrorEnabled(Marker marker) { - return true; + return RECORD_ALL_EVENTS; } public void error(Marker marker, String msg) { - recordEvent(Level.ERROR, marker, msg, null, null); - + recordEvent_0Args(Level.ERROR, marker, msg, null); } public void error(Marker marker, String format, Object arg) { - recordEvent(Level.ERROR, marker, format, new Object[] { arg }, null); - + recordEvent_1Args(Level.ERROR, marker, format, arg); } public void error(Marker marker, String format, Object arg1, Object arg2) { - recordEvent(Level.ERROR, marker, format, new Object[] { arg1, arg2 }, null); + recordEvent2Args(Level.ERROR, marker, format, arg1, arg2); } public void error(Marker marker, String format, Object... arguments) { - recordEvent(Level.ERROR, marker, format, arguments, null); + recordEventArgArray(Level.ERROR, marker, format, arguments); } public void error(Marker marker, String msg, Throwable t) { - recordEvent(Level.ERROR, marker, msg, null, t); + recordEvent_0Args(Level.ERROR, marker, msg, t); + } + + private void recordEvent_0Args(Level level, Marker marker, String msg, Throwable t) { + recordEvent(level, marker, msg, null, t); } + private void recordEvent_1Args(Level level, Marker marker, String msg, Object arg1) { + recordEvent(level, marker, msg, new Object[] { arg1 }, null); + } + + private void recordEvent2Args(Level level, Marker marker, String msg, Object arg1, Object arg2) { + if (arg2 instanceof Throwable) { + recordEvent(level, marker, msg, new Object[] { arg1 }, (Throwable) arg2); + } else { + recordEvent(level, marker, msg, new Object[] { arg1, arg2 }, null); + } + } + + private void recordEventArgArray(Level level, Marker marker, String msg, Object[] args) { + Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(args); + if (throwableCandidate != null) { + Object[] trimmedCopy = MessageFormatter.trimmedCopy(args); + recordEvent(level, marker, msg, trimmedCopy, throwableCandidate); + } else { + recordEvent(level, marker, msg, args, null); + } + } + + + // WARNING: this method assumes that any throwable is properly extracted + private void recordEvent(Level level, Marker marker, String msg, Object[] args, Throwable throwable) { + SubstituteLoggingEvent loggingEvent = new SubstituteLoggingEvent(); + loggingEvent.setTimeStamp(System.currentTimeMillis()); + loggingEvent.setLevel(level); + loggingEvent.setLogger(logger); + loggingEvent.setLoggerName(name); + loggingEvent.setMarker(marker); + loggingEvent.setMessage(msg); + loggingEvent.setThreadName(Thread.currentThread().getName()); + + loggingEvent.setArgumentArray(args); + loggingEvent.setThrowable(throwable); + + eventQueue.add(loggingEvent); + } } diff --git a/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java b/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java index bdbfb1906..d23a3a63c 100755 --- a/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java +++ b/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java @@ -152,37 +152,15 @@ final public static FormattingTuple format(final String messagePattern, Object a } - static final Throwable getThrowableCandidate(Object[] argArray) { - if (argArray == null || argArray.length == 0) { - return null; - } - - final Object lastEntry = argArray[argArray.length - 1]; - if (lastEntry instanceof Throwable) { - return (Throwable) lastEntry; - } - return null; - } - final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) { - Throwable throwableCandidate = getThrowableCandidate(argArray); + Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(argArray); Object[] args = argArray; if (throwableCandidate != null) { - args = trimmedCopy(argArray); + args = MessageFormatter.trimmedCopy(argArray); } return arrayFormat(messagePattern, args, throwableCandidate); } - private static Object[] trimmedCopy(Object[] argArray) { - if (argArray == null || argArray.length == 0) { - throw new IllegalStateException("non-sensical empty or null argument array"); - } - final int trimemdLen = argArray.length - 1; - Object[] trimmed = new Object[trimemdLen]; - System.arraycopy(argArray, 0, trimmed, 0, trimemdLen); - return trimmed; - } - final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray, Throwable throwable) { if (messagePattern == null) { @@ -411,4 +389,49 @@ private static void doubleArrayAppend(StringBuilder sbuf, double[] a) { sbuf.append(']'); } + /** + * Helper method to determine if an {@link Object} array contains a {@link Throwable} as last element + * + * @param argArray + * The arguments off which we want to know if it contains a {@link Throwable} as last element + * @return if the last {@link Object} in argArray is a {@link Throwable} this method will return it, + * otherwise it returns null + */ + public static Throwable getThrowableCandidate(final Object[] argArray) { + if (argArray == null || argArray.length == 0) { + return null; + } + + final Object lastEntry = argArray[argArray.length - 1]; + if (lastEntry instanceof Throwable) { + return (Throwable) lastEntry; + } + + return null; + } + + /** + * Helper method to get all but the last element of an array + * + * @param argArray + * The arguments from which we want to remove the last element + * + * @return a copy of the array without the last element + */ + public static Object[] trimmedCopy(final Object[] argArray) { + if (argArray == null || argArray.length == 0) { + throw new IllegalStateException("non-sensical empty or null argument array"); + } + + final int trimmedLen = argArray.length - 1; + + Object[] trimmed = new Object[trimmedLen]; + + if (trimmedLen > 0) { + System.arraycopy(argArray, 0, trimmed, 0, trimmedLen); + } + + return trimmed; + } + } diff --git a/slf4j-api/src/test/java/org/slf4j/event/EventRecodingLoggerTest.java b/slf4j-api/src/test/java/org/slf4j/event/EventRecodingLoggerTest.java new file mode 100644 index 000000000..fa47efb82 --- /dev/null +++ b/slf4j-api/src/test/java/org/slf4j/event/EventRecodingLoggerTest.java @@ -0,0 +1,525 @@ +package org.slf4j.event; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Marker; +import org.slf4j.helpers.BasicMarkerFactory; +import org.slf4j.helpers.SubstituteLogger; + +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +import static org.junit.Assert.*; + +public class EventRecodingLoggerTest { + private Queue queue; + private EventRecodingLogger logger; + private String message; + private Object param1; + private Object param2; + private Object param3; + private Object[] oneParam; + private Object[] twoParams; + private Object[] threeParams; + private Throwable exception; + private Marker marker; + + @Before + public void setUp() { + queue = new LinkedBlockingQueue(); + logger = new EventRecodingLogger(new SubstituteLogger("testLogger", queue, true), queue); + message = "Test message with 3 parameters {} {} {} {}"; + param1 = 1; + param2 = 2; + param3 = 3; + oneParam = new Object[] { param1 }; + twoParams = new Object[] { param1, param2 }; + threeParams = new Object[] { param1, param2, param3 }; + exception = new IllegalStateException("We just need an exception"); + marker = new BasicMarkerFactory().getMarker("testMarker"); + } + + @After + public void tearDown() { + assertTrue(queue.isEmpty()); + } + + @Test + public void singleMessage() { + for (Level level : Level.values()) { + singleMessageCheck(level); + } + } + + private void singleMessageCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message); + break; + case DEBUG: + logger.debug(message); + break; + case INFO: + logger.info(message); + break; + case WARN: + logger.warn(message); + break; + case ERROR: + logger.error(message); + break; + } + verifyMessageWithoutMarker(level, null, null); + } + + @Test + public void oneParameter() { + for (Level level : Level.values()) { + oneParameterCheck(level); + } + } + private void oneParameterCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message, param1); + break; + case DEBUG: + logger.debug(message, param1); + break; + case INFO: + logger.info(message, param1); + break; + case WARN: + logger.warn(message, param1); + break; + case ERROR: + logger.error(message, param1); + break; + } + verifyMessageWithoutMarker(level, oneParam, null); + } + + @Test + public void messageTwoParameters() { + for (Level level : Level.values()) { + messageTwoParametersCheck(level); + } + } + + private void messageTwoParametersCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message, param1, param2); + break; + case DEBUG: + logger.debug(message, param1, param2); + break; + case INFO: + logger.info(message, param1, param2); + break; + case WARN: + logger.warn(message, param1, param2); + break; + case ERROR: + logger.error(message, param1, param2); + break; + } + verifyMessageWithoutMarker(level, twoParams, null); + } + + @Test + public void traceMessageThreeParameters() { + for (Level level : Level.values()) { + threeParameterCheck(level); + } + } + + private void threeParameterCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message, param1, param2, param3); + break; + case DEBUG: + logger.debug(message, param1, param2, param3); + break; + case INFO: + logger.info(message, param1, param2, param3); + break; + case WARN: + logger.warn(message, param1, param2, param3); + break; + case ERROR: + logger.error(message, param1, param2, param3); + break; + } + verifyMessageWithoutMarker(level, threeParams, null); + } + + @Test + public void testMessageThrowable() { + for (Level level : Level.values()) { + throwableCheck(level); + } + } + + private void throwableCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message, exception); + break; + case DEBUG: + logger.debug(message, exception); + break; + case INFO: + logger.info(message, exception); + break; + case WARN: + logger.warn(message, exception); + break; + case ERROR: + logger.error(message, exception); + break; + } + verifyMessageWithoutMarker(level, null, exception); + } + + @Test + public void traceMessageOneParameterThrowable() { + for (Level level : Level.values()) { + oneParamThrowableCheck(level); + } + } + + private void oneParamThrowableCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message, param1, exception); + break; + case DEBUG: + logger.debug(message, param1, exception); + break; + case INFO: + logger.info(message, param1, exception); + break; + case WARN: + logger.warn(message, param1, exception); + break; + case ERROR: + logger.error(message, param1, exception); + break; + } + verifyMessageWithoutMarker(level, oneParam, exception); + } + + @Test + public void traceMessageTwoParametersThrowable() { + for (Level level : Level.values()) { + twoParamThrowableCheck(level); + } + } + + private void twoParamThrowableCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(message, param1, param2, exception); + break; + case DEBUG: + logger.debug(message, param1, param2, exception); + break; + case INFO: + logger.info(message, param1, param2, exception); + break; + case WARN: + logger.warn(message, param1, param2, exception); + break; + case ERROR: + logger.error(message, param1, param2, exception); + break; + } + verifyMessageWithoutMarker(level, twoParams, exception); + } + + @Test + public void testMessageThreeParametersThrowable() { + for (Level level : Level.values()) { + messageWith3ArgsPlusException(level); + } + } + + private void messageWith3ArgsPlusException(Level level) { + switch (level) { + case TRACE: + logger.trace(message, param1, param2, param3, exception); + break; + case DEBUG: + logger.debug(message, param1, param2, param3, exception); + break; + case INFO: + logger.info(message, param1, param2, param3, exception); + break; + case WARN: + logger.warn(message, param1, param2, param3, exception); + break; + case ERROR: + logger.error(message, param1, param2, param3, exception); + break; + } + verifyMessageWithoutMarker(level, threeParams, exception); + } + + @Test + public void markerMessage() { + for (Level level : Level.values()) { + markerMessageCheck(level); + } + } + private void markerMessageCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message); + break; + case DEBUG: + logger.debug(marker, message); + break; + case INFO: + logger.info(marker, message); + break; + case WARN: + logger.warn(marker, message); + break; + case ERROR: + logger.error(marker, message); + break; + } + verifyMessage(level, marker, null, null); + } + + @Test + public void markerMessageOneParameter() { + for (Level level : Level.values()) { + markerMessageOneParameter(level); + } + } + private void markerMessageOneParameter(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, param1); + break; + case DEBUG: + logger.debug(marker, message, param1); + break; + case INFO: + logger.info(marker, message, param1); + break; + case WARN: + logger.warn(marker, message, param1); + break; + case ERROR: + logger.error(marker, message, param1); + break; + } + verifyMessage(level, marker, oneParam, null); + } + + @Test + public void traceMarkerMessageTwoParameters() { + for (Level level : Level.values()) { + markerMessageTwoParameters(level); + } + } + + private void markerMessageTwoParameters(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, param1, param2); + break; + case DEBUG: + logger.debug(marker, message, param1, param2); + break; + case INFO: + logger.info(marker, message, param1, param2); + break; + case WARN: + logger.warn(marker, message, param1, param2); + break; + case ERROR: + logger.error(marker, message, param1, param2); + break; + } + verifyMessage(level, marker, twoParams, null); + } + + @Test + public void traceMarkerMessageThreeParameters() { + for (Level level : Level.values()) { + markerMessageThreeParameters(level); + } + } + + private void markerMessageThreeParameters(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, param1, param2, param3); + break; + case DEBUG: + logger.debug(marker, message, param1, param2, param3); + break; + case INFO: + logger.info(marker, message, param1, param2, param3); + break; + case WARN: + logger.warn(marker, message, param1, param2, param3); + break; + case ERROR: + logger.error(marker, message, param1, param2, param3); + break; + } + verifyMessage(level, marker, threeParams, null); + } + + @Test + public void markerMessageThrowable() { + for (Level level : Level.values()) { + markerMessageThrowable(level); + } + } + + private void markerMessageThrowable(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, exception); + break; + case DEBUG: + logger.debug(marker, message, exception); + break; + case INFO: + logger.info(marker, message, exception); + break; + case WARN: + logger.warn(marker, message, exception); + break; + case ERROR: + logger.error(marker, message, exception); + break; + } + verifyMessage(level, marker, null, exception); + } + + @Test + public void markerMessageOneParameterThrowable() { + for (Level level : Level.values()) { + markerMessageOneParameterThrowableCheck(level); + } + } + + private void markerMessageOneParameterThrowableCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, param1, exception); + break; + case DEBUG: + logger.debug(marker, message, param1, exception); + break; + case INFO: + logger.info(marker, message, param1, exception); + break; + case WARN: + logger.warn(marker, message, param1, exception); + break; + case ERROR: + logger.error(marker, message, param1, exception); + break; + } + verifyMessage(level, marker, oneParam, exception); + } + + @Test + public void traceMarkerMessageTwoParametersThrowable() { + for (Level level : Level.values()) { + markerMessageTwoParametersThrowableCheck(level); + } + } + + private void markerMessageTwoParametersThrowableCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, param1, param2, exception); + break; + case DEBUG: + logger.debug(marker, message, param1, param2, exception); + break; + case INFO: + logger.info(marker, message, param1, param2, exception); + break; + case WARN: + logger.warn(marker, message, param1, param2, exception); + break; + case ERROR: + logger.error(marker, message, param1, param2, exception); + break; + } + verifyMessage(level, marker, twoParams, exception); + } + + @Test + public void traceMarkerMessageThreeParametersThrowable() { + for (Level level : Level.values()) { + markerMessageThreeParametersThrowableCheck(level); + } + } + + private void markerMessageThreeParametersThrowableCheck(Level level) { + switch (level) { + case TRACE: + logger.trace(marker, message, param1, param2, param3, exception); + break; + case DEBUG: + logger.debug(marker, message, param1, param2, param3, exception); + break; + case INFO: + logger.info(marker, message, param1, param2, param3, exception); + break; + case WARN: + logger.warn(marker, message, param1, param2, param3, exception); + break; + case ERROR: + logger.error(marker, message, param1, param2, param3, exception); + break; + } + verifyMessage(level, marker, threeParams, exception); + } + + private void verifyMessageWithoutMarker(Level level, Object[] arguments, Throwable exception) { + verifyMessage(level, null, arguments, exception); + } + + private void verifyMessage(Level level, Marker marker, Object[] arguments, Throwable exception) { + + assertEquals("missing event: ", 1, queue.size()); + SubstituteLoggingEvent event = queue.poll(); + assertNotNull(event); + + if (marker == null) { + assertNull(event.getMarker()); + } else { + assertEquals(marker, event.getMarker()); + } + + assertEquals(message, event.getMessage()); + + if (arguments == null) { + assertNull(event.getArgumentArray()); + } else { + assertArrayEquals(arguments, event.getArgumentArray()); + } + + assertEquals("wrong level: ", level, event.getLevel()); + + if (exception == null) { + assertNull(event.getThrowable()); + } else { + assertEquals(exception, event.getThrowable()); + } + } +}