val
parameter) as identified with
- * the key
parameter into the current thread's context map. The
- * key
parameter cannot be null. Log4j does not
- * support null for the val
parameter.
- *
- *
- * This method delegates all work to log4j's MDC.
- *
- * @throws IllegalArgumentException
- * in case the "key" or "val" parameter is null
- */
- public void put(String key, String val) {
- org.apache.log4j.MDC.put(key, val);
- }
+ public String get(String key) {
+ return (String) org.apache.log4j.MDC.get(key);
+ }
- public void remove(String key) {
- org.apache.log4j.MDC.remove(key);
- }
+ /**
+ * Put a context value (the val
parameter) as identified with
+ * the key
parameter into the current thread's context map. The
+ * key
parameter cannot be null. Log4j does not
+ * support null for the val
parameter.
+ *
+ *
+ * This method delegates all work to log4j's MDC.
+ *
+ * @throws IllegalArgumentException
+ * in case the "key" or "val" parameter is null
+ */
+ public void put(String key, String val) {
+ org.apache.log4j.MDC.put(key, val);
+ }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Map getCopyOfContextMap() {
- Map old = org.apache.log4j.MDC.getContext();
- if (old != null) {
- return new HashMap(old);
- } else {
- return null;
- }
- }
+ public void remove(String key) {
+ org.apache.log4j.MDC.remove(key);
+ }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void setContextMap(Map contextMap) {
- Map old = org.apache.log4j.MDC.getContext();
- if (old == null) {
- Iterator entrySetIterator = contextMap.entrySet().iterator();
- while (entrySetIterator.hasNext()) {
- Map.Entry mapEntry = (Map.Entry) entrySetIterator.next();
- org.apache.log4j.MDC.put((String) mapEntry.getKey(), mapEntry.getValue());
- }
- } else {
- old.clear();
- old.putAll(contextMap);
- }
- }
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Map getCopyOfContextMap() {
+ Map old = org.apache.log4j.MDC.getContext();
+ if (old != null) {
+ return new HashMap(old);
+ } else {
+ return null;
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void setContextMap(Map contextMap) {
+ Map old = org.apache.log4j.MDC.getContext();
+ if (old == null) {
+ Iterator entrySetIterator = contextMap.entrySet().iterator();
+ while (entrySetIterator.hasNext()) {
+ Map.Entry mapEntry = (Map.Entry) entrySetIterator.next();
+ org.apache.log4j.MDC.put((String) mapEntry.getKey(), mapEntry.getValue());
+ }
+ } else {
+ old.clear();
+ old.putAll(contextMap);
+ }
+ }
}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java
index bb0f065..aab9ee6 100644
--- a/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java
+++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/StaticMDCBinder.java
@@ -33,33 +33,33 @@
*/
public class StaticMDCBinder {
- /**
- * The unique instance of this class.
- */
- public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
+ /**
+ * The unique instance of this class.
+ */
+ public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
- private StaticMDCBinder() {
- }
+ private StaticMDCBinder() {
+ }
- /**
- * Return the singleton of this class.
- *
- * @return the StaticMDCBinder singleton
- * @since 1.7.14
- */
- public static final StaticMDCBinder getSingleton() {
- return SINGLETON;
- }
+ /**
+ * Return the singleton of this class.
+ *
+ * @return the StaticMDCBinder singleton
+ * @since 1.7.14
+ */
+ public static final StaticMDCBinder getSingleton() {
+ return SINGLETON;
+ }
- /**
- * Currently this method always returns an instance of
- * {@link StaticMDCBinder}.
- */
- public MDCAdapter getMDCA() {
- return new Log4jMDCAdapter();
- }
+ /**
+ * Currently this method always returns an instance of
+ * {@link StaticMDCBinder}.
+ */
+ public MDCAdapter getMDCA() {
+ return new Log4jMDCAdapter();
+ }
- public String getMDCAdapterClassStr() {
- return Log4jMDCAdapter.class.getName();
- }
+ public String getMDCAdapterClassStr() {
+ return Log4jMDCAdapter.class.getName();
+ }
}
diff --git a/slf4j-log4j12/src/main/java/org/slf4j/impl/VersionUtil.java b/slf4j-log4j12/src/main/java/org/slf4j/impl/VersionUtil.java
new file mode 100644
index 0000000..ee913ed
--- /dev/null
+++ b/slf4j-log4j12/src/main/java/org/slf4j/impl/VersionUtil.java
@@ -0,0 +1,33 @@
+package org.slf4j.impl;
+
+import java.lang.reflect.Method;
+
+import org.slf4j.helpers.Util;
+
+public class VersionUtil {
+ static final int MINIMAL_VERSION = 5;
+
+ static public int getJavaMajorVersion() {
+ String javaVersionString = Util.safeGetSystemProperty("java.version");
+ return getJavaMajorVersion(javaVersionString);
+ }
+
+ static int getJavaMajorVersion(String versionString) {
+ if (versionString == null)
+ return MINIMAL_VERSION;
+ if (versionString.startsWith("1.")) {
+ return versionString.charAt(2) - '0';
+ } else {
+ // we running under Java 9 or later
+ try {
+ Method versionMethod = Runtime.class.getMethod("version");
+ Object versionObj = versionMethod.invoke(null);
+ Method majorMethod = versionObj.getClass().getMethod("major");
+ Integer resultInteger = (Integer) majorMethod.invoke(versionObj);
+ return resultInteger.intValue();
+ } catch (Exception e) {
+ return MINIMAL_VERSION;
+ }
+ }
+ }
+}
diff --git a/slf4j-log4j12/src/test/java/org/apache/log4j/MDCFriendTest.java b/slf4j-log4j12/src/test/java/org/apache/log4j/MDCFriendTest.java
new file mode 100644
index 0000000..ffa17f5
--- /dev/null
+++ b/slf4j-log4j12/src/test/java/org/apache/log4j/MDCFriendTest.java
@@ -0,0 +1,32 @@
+package org.apache.log4j;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Random;
+
+import org.junit.Test;
+import org.slf4j.impl.VersionUtil;
+
+public class MDCFriendTest {
+
+
+ private static Random random = new Random();
+ int diff = random.nextInt(1024*8);
+
+ @Test
+ public void smoke() {
+ if(VersionUtil.getJavaMajorVersion() < 9)
+ return;
+
+ MDCFriend.fixForJava9();
+ String key = "MDCFriendTest.smoke"+diff;
+ String val = "val"+diff;
+ MDC.put(key, val);
+ assertEquals(val, MDC.get(key));
+ MDC.clear();
+ assertNull(MDC.get(key));
+
+ }
+
+}
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java b/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
index d687383..6c71a11 100644
--- a/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
+++ b/slf4j-log4j12/src/test/java/org/slf4j/InvocationTest.java
@@ -68,9 +68,9 @@
@Test
public void test2() {
- Integer i1 = new Integer(1);
- Integer i2 = new Integer(2);
- Integer i3 = new Integer(3);
+ Integer i1 = Integer.valueOf(1);
+ Integer i2 = Integer.valueOf(2);
+ Integer i3 = Integer.valueOf(3);
Exception e = new Exception("This is a test exception.");
Logger logger = LoggerFactory.getLogger("test2");
@@ -88,7 +88,7 @@
logger.warn("Hello world 3", e);
logger.error("Hello world 4.");
- logger.error("Hello world {}", new Integer(3));
+ logger.error("Hello world {}", Integer.valueOf(3));
logger.error("Hello world 4.", e);
assertEquals(11, listAppender.list.size());
}
diff --git a/slf4j-log4j12/src/test/java/org/slf4j/impl/UtilVersionTest.java b/slf4j-log4j12/src/test/java/org/slf4j/impl/UtilVersionTest.java
new file mode 100644
index 0000000..e84d5cf
--- /dev/null
+++ b/slf4j-log4j12/src/test/java/org/slf4j/impl/UtilVersionTest.java
@@ -0,0 +1,24 @@
+package org.slf4j.impl;
+
+import static org.junit.Assert.*;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class UtilVersionTest {
+
+ @Test
+ public void test() {
+ System.out.println(System.getProperty("java.version"));
+ assertEquals(6, VersionUtil.getJavaMajorVersion("1.6"));
+ assertEquals(7, VersionUtil.getJavaMajorVersion("1.7.0_21-b11"));
+ assertEquals(8, VersionUtil.getJavaMajorVersion("1.8.0_25"));
+ }
+
+ @Ignore
+ @Test // requires Java 9 to pass
+ public void testJava9() {
+ assertEquals(9, VersionUtil.getJavaMajorVersion("9ea"));
+ }
+
+}
diff --git a/slf4j-migrator/pom.xml b/slf4j-migrator/pom.xml
index e67c1d3..1762cc9 100644
--- a/slf4j-migrator/pom.xml
+++ b/slf4j-migrator/pom.xml
@@ -7,7 +7,7 @@
Simple implementation of {@link Logger} that sends all enabled log messages, - * for all defined loggers, to the console ({@code System.err}). - * The following system properties are supported to configure the behavior of this logger:
+ *+ * Simple implementation of {@link Logger} that sends all enabled log messages, + * for all defined loggers, to the console ({@code System.err}). The following + * system properties are supported to configure the behavior of this logger: + *
* *org.slf4j.simpleLogger.logFile
- The output target which can be the path to a file, or
- * the special values "System.out" and "System.err". Default is "System.err".
- *
- * org.slf4j.simpleLogger.defaultLogLevel
- Default log level for all instances of SimpleLogger.
- * Must be one of ("trace", "debug", "info", "warn", "error" or "off"). If not specified, defaults to "info". org.slf4j.simpleLogger.log.a.b.c
- Logging detail level for a SimpleLogger instance
- * named "a.b.c". Right-side value must be one of "trace", "debug", "info", "warn", "error" or "off". When a SimpleLogger
- * named "a.b.c" is initialized, its level is assigned from this property. If unspecified, the level of nearest parent
- * logger will be used, and if none is set, then the value specified by
+ * org.slf4j.simpleLogger.logFile
- The output target which can
+ * be the path to a file, or the special values "System.out" and
+ * "System.err". Default is "System.err".org.slf4j.simpleLogger.cacheOutputStream
- If the output
+ * target is set to "System.out" or "System.err" (see preceding entry), by
+ * default, logs will be output to the latest value referenced by
+ * System.out/err
variables. By setting this
+ * parameter to true, the output stream will be cached, i.e. assigned once at
+ * initialization time and re-used independently of the current value referenced by
+ * System.out/err
.
+ * org.slf4j.simpleLogger.defaultLogLevel
- Default log level
+ * for all instances of SimpleLogger. Must be one of ("trace", "debug", "info",
+ * "warn", "error" or "off"). If not specified, defaults to "info".org.slf4j.simpleLogger.log.a.b.c
- Logging detail
+ * level for a SimpleLogger instance named "a.b.c". Right-side value must be one
+ * of "trace", "debug", "info", "warn", "error" or "off". When a SimpleLogger
+ * named "a.b.c" is initialized, its level is assigned from this property. If
+ * unspecified, the level of nearest parent logger will be used, and if none is
+ * set, then the value specified by
* org.slf4j.simpleLogger.defaultLogLevel
will be used.org.slf4j.simpleLogger.showDateTime
- Set to true
if you want the current date and
- * time to be included in output messages. Default is false
org.slf4j.simpleLogger.dateTimeFormat
- The date and time format to be used in the output messages.
- * The pattern describing the date and time format is defined by
- * SimpleDateFormat
.
- * If the format is not specified or is invalid, the number of milliseconds since start up will be output. org.slf4j.simpleLogger.showThreadName
-Set to true
if you want to output the current
- * thread name. Defaults to true
.org.slf4j.simpleLogger.showLogName
- Set to true
if you want the Logger instance name
- * to be included in output messages. Defaults to true
.org.slf4j.simpleLogger.showShortLogName
- Set to true
if you want the last component
- * of the name to be included in output messages. Defaults to false
.org.slf4j.simpleLogger.levelInBrackets
- Should the level string be output in brackets? Defaults
- * to false
.org.slf4j.simpleLogger.warnLevelString
- The string value output for the warn level. Defaults
- * to WARN
.org.slf4j.simpleLogger.showDateTime
- Set to
+ * true
if you want the current date and time to be included in
+ * output messages. Default is false
org.slf4j.simpleLogger.dateTimeFormat
- The date and time
+ * format to be used in the output messages. The pattern describing the date and
+ * time format is defined by
+ * SimpleDateFormat
. If the format is not specified or is
+ * invalid, the number of milliseconds since start up will be output.org.slf4j.simpleLogger.showThreadName
-Set to
+ * true
if you want to output the current thread name. Defaults to
+ * true
.org.slf4j.simpleLogger.showLogName
- Set to
+ * true
if you want the Logger instance name to be included in
+ * output messages. Defaults to true
.org.slf4j.simpleLogger.showShortLogName
- Set to
+ * true
if you want the last component of the name to be included
+ * in output messages. Defaults to false
.org.slf4j.simpleLogger.levelInBrackets
- Should the level
+ * string be output in brackets? Defaults to false
.org.slf4j.simpleLogger.warnLevelString
- The string value
+ * output for the warn level. Defaults to WARN
.In addition to looking for system properties with the names specified above, this implementation also checks for
- * a class loader resource named "simplelogger.properties"
, and includes any matching definitions
- * from this resource (if it exists).
With no configuration, the default output includes the relative time in milliseconds, thread name, the level, - * logger name, and the message followed by the line separator for the host. In log4j terms it amounts to the "%r [%t] - * %level %logger - %m%n" pattern.
- *Sample output follows.
+ *
+ * In addition to looking for system properties with the names specified above,
+ * this implementation also checks for a class loader resource named
+ * "simplelogger.properties"
, and includes any matching definitions
+ * from this resource (if it exists).
+ *
+ * With no configuration, the default output includes the relative time in + * milliseconds, thread name, the level, logger name, and the message followed + * by the line separator for the host. In log4j terms it amounts to the "%r [%t] + * %level %logger - %m%n" pattern. + *
+ *+ * Sample output follows. + *
+ * ** 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order. * 225 [main] INFO examples.SortAlgo - Entered the sort method. @@ -107,11 +128,14 @@ * 467 [main] INFO examples.Sort - Exiting main method. ** - *
This implementation is heavily inspired by - * Apache Commons Logging's SimpleLog.
+ *+ * This implementation is heavily inspired by + * Apache Commons Logging's + * SimpleLog. + *
* * @author Ceki Gülcü - * @author Scott Sanders + * @author Scott Sanders * @author Rod Waldhoff * @author Robert Burrell Donkin * @author Cédrik LIME @@ -119,68 +143,21 @@ public class SimpleLogger extends MarkerIgnoringBase { private static final long serialVersionUID = -632788891211436180L; - private static final String CONFIGURATION_FILE = "simplelogger.properties"; private static long START_TIME = System.currentTimeMillis(); - private static final Properties SIMPLE_LOGGER_PROPS = new Properties(); - - private static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT; - private static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT; - private static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT; - private static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT; - private static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT; - // The OFF level can only be used in configuration files to disable logging. It has + + protected static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT; + protected static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT; + protected static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT; + protected static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT; + protected static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT; + // The OFF level can only be used in configuration files to disable logging. + // It has // no printing method associated with it in o.s.Logger interface. - private static final int LOG_LEVEL_OFF = LOG_LEVEL_ERROR + 10; + protected static final int LOG_LEVEL_OFF = LOG_LEVEL_ERROR + 10; private static boolean INITIALIZED = false; - - private static int DEFAULT_LOG_LEVEL = LOG_LEVEL_INFO; - private static boolean SHOW_DATE_TIME = false; - private static String DATE_TIME_FORMAT_STR = null; - private static DateFormat DATE_FORMATTER = null; - private static boolean SHOW_THREAD_NAME = true; - private static boolean SHOW_LOG_NAME = true; - private static boolean SHOW_SHORT_LOG_NAME = false; - private static String LOG_FILE = "System.err"; - private static PrintStream TARGET_STREAM = null; - private static boolean LEVEL_IN_BRACKETS = false; - private static String WARN_LEVEL_STRING = "WARN"; - - /** All system properties used bySimpleLogger
start with this prefix */
- public static final String SYSTEM_PREFIX = "org.slf4j.simpleLogger.";
-
- public static final String DEFAULT_LOG_LEVEL_KEY = SYSTEM_PREFIX + "defaultLogLevel";
- public static final String SHOW_DATE_TIME_KEY = SYSTEM_PREFIX + "showDateTime";
- public static final String DATE_TIME_FORMAT_KEY = SYSTEM_PREFIX + "dateTimeFormat";
- public static final String SHOW_THREAD_NAME_KEY = SYSTEM_PREFIX + "showThreadName";
- public static final String SHOW_LOG_NAME_KEY = SYSTEM_PREFIX + "showLogName";
- public static final String SHOW_SHORT_LOG_NAME_KEY = SYSTEM_PREFIX + "showShortLogName";
- public static final String LOG_FILE_KEY = SYSTEM_PREFIX + "logFile";
- public static final String LEVEL_IN_BRACKETS_KEY = SYSTEM_PREFIX + "levelInBrackets";
- public static final String WARN_LEVEL_STRING_KEY = SYSTEM_PREFIX + "warnLevelString";
-
- public static final String LOG_KEY_PREFIX = SYSTEM_PREFIX + "log.";
-
- private static String getStringProperty(String name) {
- String prop = null;
- try {
- prop = System.getProperty(name);
- } catch (SecurityException e) {
- ; // Ignore
- }
- return (prop == null) ? SIMPLE_LOGGER_PROPS.getProperty(name) : prop;
- }
-
- private static String getStringProperty(String name, String defaultValue) {
- String prop = getStringProperty(name);
- return (prop == null) ? defaultValue : prop;
- }
-
- private static boolean getBooleanProperty(String name, boolean defaultValue) {
- String prop = getStringProperty(name);
- return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
- }
+ static SimpleLoggerConfiguration CONFIG_PARAMS = null;
static void lazyInit() {
if (INITIALIZED) {
@@ -189,76 +166,12 @@
INITIALIZED = true;
init();
}
-
+
+ // external software might be invoking this method directly. Do not rename
+ // or change its semantics.
static void init() {
- loadProperties();
-
- String defaultLogLevelString = getStringProperty(DEFAULT_LOG_LEVEL_KEY, null);
- if (defaultLogLevelString != null)
- DEFAULT_LOG_LEVEL = stringToLevel(defaultLogLevelString);
-
- SHOW_LOG_NAME = getBooleanProperty(SHOW_LOG_NAME_KEY, SHOW_LOG_NAME);
- SHOW_SHORT_LOG_NAME = getBooleanProperty(SHOW_SHORT_LOG_NAME_KEY, SHOW_SHORT_LOG_NAME);
- SHOW_DATE_TIME = getBooleanProperty(SHOW_DATE_TIME_KEY, SHOW_DATE_TIME);
- SHOW_THREAD_NAME = getBooleanProperty(SHOW_THREAD_NAME_KEY, SHOW_THREAD_NAME);
- DATE_TIME_FORMAT_STR = getStringProperty(DATE_TIME_FORMAT_KEY, DATE_TIME_FORMAT_STR);
- LEVEL_IN_BRACKETS = getBooleanProperty(LEVEL_IN_BRACKETS_KEY, LEVEL_IN_BRACKETS);
- WARN_LEVEL_STRING = getStringProperty(WARN_LEVEL_STRING_KEY, WARN_LEVEL_STRING);
-
- LOG_FILE = getStringProperty(LOG_FILE_KEY, LOG_FILE);
- TARGET_STREAM = computeTargetStream(LOG_FILE);
-
- if (DATE_TIME_FORMAT_STR != null) {
- try {
- DATE_FORMATTER = new SimpleDateFormat(DATE_TIME_FORMAT_STR);
- } catch (IllegalArgumentException e) {
- Util.report("Bad date format in " + CONFIGURATION_FILE + "; will output relative time", e);
- }
- }
- }
-
- private static PrintStream computeTargetStream(String logFile) {
- if ("System.err".equalsIgnoreCase(logFile))
- return System.err;
- else if ("System.out".equalsIgnoreCase(logFile)) {
- return System.out;
- } else {
- try {
- FileOutputStream fos = new FileOutputStream(logFile);
- PrintStream printStream = new PrintStream(fos);
- return printStream;
- } catch (FileNotFoundException e) {
- Util.report("Could not open [" + logFile + "]. Defaulting to System.err", e);
- return System.err;
- }
- }
- }
-
- private static void loadProperties() {
- // Add props from the resource simplelogger.properties
- InputStream in = AccessController.doPrivileged(new PrivilegedActionSimpleLogger
start with this
+ * prefix
+ */
+ public static final String SYSTEM_PREFIX = "org.slf4j.simpleLogger.";
+
+ public static final String LOG_KEY_PREFIX = SimpleLogger.SYSTEM_PREFIX + "log.";
+
+ public static final String CACHE_OUTPUT_STREAM_STRING_KEY = SimpleLogger.SYSTEM_PREFIX + "cacheOutputStream";
+
+ public static final String WARN_LEVEL_STRING_KEY = SimpleLogger.SYSTEM_PREFIX + "warnLevelString";
+
+ public static final String LEVEL_IN_BRACKETS_KEY = SimpleLogger.SYSTEM_PREFIX + "levelInBrackets";
+
+ public static final String LOG_FILE_KEY = SimpleLogger.SYSTEM_PREFIX + "logFile";
+
+ public static final String SHOW_SHORT_LOG_NAME_KEY = SimpleLogger.SYSTEM_PREFIX + "showShortLogName";
+
+ public static final String SHOW_LOG_NAME_KEY = SimpleLogger.SYSTEM_PREFIX + "showLogName";
+
+ public static final String SHOW_THREAD_NAME_KEY = SimpleLogger.SYSTEM_PREFIX + "showThreadName";
+
+ public static final String DATE_TIME_FORMAT_KEY = SimpleLogger.SYSTEM_PREFIX + "dateTimeFormat";
+
+ public static final String SHOW_DATE_TIME_KEY = SimpleLogger.SYSTEM_PREFIX + "showDateTime";
+
+ public static final String DEFAULT_LOG_LEVEL_KEY = SimpleLogger.SYSTEM_PREFIX + "defaultLogLevel";
+
+ /**
* Package access allows only {@link SimpleLoggerFactory} to instantiate
* SimpleLogger instances.
*/
@@ -275,9 +216,9 @@
String levelString = recursivelyComputeLevelString();
if (levelString != null) {
- this.currentLogLevel = stringToLevel(levelString);
+ this.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(levelString);
} else {
- this.currentLogLevel = DEFAULT_LOG_LEVEL;
+ this.currentLogLevel = CONFIG_PARAMS.defaultLogLevel;
}
}
@@ -287,37 +228,22 @@
int indexOfLastDot = tempName.length();
while ((levelString == null) && (indexOfLastDot > -1)) {
tempName = tempName.substring(0, indexOfLastDot);
- levelString = getStringProperty(LOG_KEY_PREFIX + tempName, null);
+ levelString = CONFIG_PARAMS.getStringProperty(SimpleLogger.LOG_KEY_PREFIX + tempName, null);
indexOfLastDot = String.valueOf(tempName).lastIndexOf(".");
}
return levelString;
}
- private static int stringToLevel(String levelStr) {
- if ("trace".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_TRACE;
- } else if ("debug".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_DEBUG;
- } else if ("info".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_INFO;
- } else if ("warn".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_WARN;
- } else if ("error".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_ERROR;
- } else if ("off".equalsIgnoreCase(levelStr)) {
- return LOG_LEVEL_OFF;
- }
- // assume INFO by default
- return LOG_LEVEL_INFO;
- }
-
- /**
- * This is our internal implementation for logging regular (non-parameterized)
- * log messages.
+ /**
+ * This is our internal implementation for logging regular
+ * (non-parameterized) log messages.
*
- * @param level One of the LOG_LEVEL_XXX constants defining the log level
- * @param message The message itself
- * @param t The exception whose stack trace should be logged
+ * @param level
+ * One of the LOG_LEVEL_XXX constants defining the log level
+ * @param message
+ * The message itself
+ * @param t
+ * The exception whose stack trace should be logged
*/
private void log(int level, String message, Throwable t) {
if (!isLevelEnabled(level)) {
@@ -327,8 +253,8 @@
StringBuilder buf = new StringBuilder(32);
// Append date-time if so configured
- if (SHOW_DATE_TIME) {
- if (DATE_FORMATTER != null) {
+ if (CONFIG_PARAMS.showDateTime) {
+ if (CONFIG_PARAMS.dateFormatter != null) {
buf.append(getFormattedDate());
buf.append(' ');
} else {
@@ -338,43 +264,28 @@
}
// Append current thread name if so configured
- if (SHOW_THREAD_NAME) {
+ if (CONFIG_PARAMS.showThreadName) {
buf.append('[');
buf.append(Thread.currentThread().getName());
buf.append("] ");
}
- if (LEVEL_IN_BRACKETS)
+ if (CONFIG_PARAMS.levelInBrackets)
buf.append('[');
// Append a readable representation of the log level
- switch (level) {
- case LOG_LEVEL_TRACE:
- buf.append("TRACE");
- break;
- case LOG_LEVEL_DEBUG:
- buf.append("DEBUG");
- break;
- case LOG_LEVEL_INFO:
- buf.append("INFO");
- break;
- case LOG_LEVEL_WARN:
- buf.append(WARN_LEVEL_STRING);
- break;
- case LOG_LEVEL_ERROR:
- buf.append("ERROR");
- break;
- }
- if (LEVEL_IN_BRACKETS)
+ String levelStr = renderLevel(level);
+ buf.append(levelStr);
+ if (CONFIG_PARAMS.levelInBrackets)
buf.append(']');
buf.append(' ');
// Append the name of the log instance if so configured
- if (SHOW_SHORT_LOG_NAME) {
+ if (CONFIG_PARAMS.showShortLogName) {
if (shortLogName == null)
shortLogName = computeShortName();
buf.append(String.valueOf(shortLogName)).append(" - ");
- } else if (SHOW_LOG_NAME) {
+ } else if (CONFIG_PARAMS.showLogName) {
buf.append(String.valueOf(name)).append(" - ");
}
@@ -385,19 +296,41 @@
}
+ protected String renderLevel(int level) {
+ switch (level) {
+ case LOG_LEVEL_TRACE:
+ return "TRACE";
+ case LOG_LEVEL_DEBUG:
+ return ("DEBUG");
+ case LOG_LEVEL_INFO:
+ return "INFO";
+ case LOG_LEVEL_WARN:
+ return CONFIG_PARAMS.warnLevelString;
+ case LOG_LEVEL_ERROR:
+ return "ERROR";
+ }
+ throw new IllegalStateException("Unrecognized level [" + level + "]");
+ }
+
void write(StringBuilder buf, Throwable t) {
- TARGET_STREAM.println(buf.toString());
+ PrintStream targetStream = CONFIG_PARAMS.outputChoice.getTargetPrintStream();
+
+ targetStream.println(buf.toString());
+ writeThrowable(t, targetStream);
+ targetStream.flush();
+ }
+
+ protected void writeThrowable(Throwable t, PrintStream targetStream) {
if (t != null) {
- t.printStackTrace(TARGET_STREAM);
- }
- TARGET_STREAM.flush();
+ t.printStackTrace(targetStream);
+ }
}
private String getFormattedDate() {
Date now = new Date();
String dateText;
- synchronized (DATE_FORMATTER) {
- dateText = DATE_FORMATTER.format(now);
+ synchronized (CONFIG_PARAMS.dateFormatter) {
+ dateText = CONFIG_PARAMS.dateFormatter.format(now);
}
return dateText;
}
@@ -427,7 +360,8 @@
*
* @param level
* @param format
- * @param arguments a list of 3 ore more arguments
+ * @param arguments
+ * a list of 3 ore more arguments
*/
private void formatAndLog(int level, String format, Object... arguments) {
if (!isLevelEnabled(level)) {
@@ -440,7 +374,8 @@
/**
* Is the given log level currently enabled?
*
- * @param logLevel is this level enabled?
+ * @param logLevel
+ * is this level enabled?
*/
protected boolean isLevelEnabled(int logLevel) {
// log level are numerically ordered so can use simple numeric
@@ -454,8 +389,8 @@
}
/**
- * A simple implementation which logs messages of level TRACE according
- * to the format outlined above.
+ * A simple implementation which logs messages of level TRACE according to
+ * the format outlined above.
*/
public void trace(String msg) {
log(LOG_LEVEL_TRACE, msg, null);
@@ -496,8 +431,8 @@
}
/**
- * A simple implementation which logs messages of level DEBUG according
- * to the format outlined above.
+ * A simple implementation which logs messages of level DEBUG according to
+ * the format outlined above.
*/
public void debug(String msg) {
log(LOG_LEVEL_DEBUG, msg, null);
@@ -538,8 +473,8 @@
}
/**
- * A simple implementation which logs messages of level INFO according
- * to the format outlined above.
+ * A simple implementation which logs messages of level INFO according to
+ * the format outlined above.
*/
public void info(String msg) {
log(LOG_LEVEL_INFO, msg, null);
@@ -580,8 +515,8 @@
}
/**
- * A simple implementation which always logs messages of level WARN according
- * to the format outlined above.
+ * A simple implementation which always logs messages of level WARN
+ * according to the format outlined above.
*/
public void warn(String msg) {
log(LOG_LEVEL_WARN, msg, null);
@@ -622,8 +557,8 @@
}
/**
- * A simple implementation which always logs messages of level ERROR according
- * to the format outlined above.
+ * A simple implementation which always logs messages of level ERROR
+ * according to the format outlined above.
*/
public void error(String msg) {
log(LOG_LEVEL_ERROR, msg, null);
diff --git a/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerConfiguration.java b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerConfiguration.java
new file mode 100644
index 0000000..d538b0f
--- /dev/null
+++ b/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLoggerConfiguration.java
@@ -0,0 +1,186 @@
+package org.slf4j.impl;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Properties;
+
+import org.slf4j.helpers.Util;
+import org.slf4j.impl.OutputChoice.OutputChoiceType;
+
+/**
+ * This class holds configuration values for {@link SimpleLogger}. The
+ * values are computed at runtime. See {@link SimpleLogger} documentation for
+ * more information.
+ *
+ *
+ * @author Ceki Gülcü
+ * @author Scott Sanders
+ * @author Rod Waldhoff
+ * @author Robert Burrell Donkin
+ * @author Cédrik LIME
+ *
+ * @since 1.7.25
+ */
+public class SimpleLoggerConfiguration {
+
+ private static final String CONFIGURATION_FILE = "simplelogger.properties";
+
+ static int DEFAULT_LOG_LEVEL_DEFAULT = SimpleLogger.LOG_LEVEL_INFO;
+ int defaultLogLevel = DEFAULT_LOG_LEVEL_DEFAULT;
+
+ private static final boolean SHOW_DATE_TIME_DEFAULT = false;
+ boolean showDateTime = SHOW_DATE_TIME_DEFAULT;
+
+ private static final String DATE_TIME_FORMAT_STR_DEFAULT = null;
+ private static String dateTimeFormatStr = DATE_TIME_FORMAT_STR_DEFAULT;
+
+ DateFormat dateFormatter = null;
+
+ private static final boolean SHOW_THREAD_NAME_DEFAULT = true;
+ boolean showThreadName = SHOW_THREAD_NAME_DEFAULT;
+
+ final static boolean SHOW_LOG_NAME_DEFAULT = true;
+ boolean showLogName = SHOW_LOG_NAME_DEFAULT;
+
+ private static final boolean SHOW_SHORT_LOG_NAME_DEFAULT = false;
+ boolean showShortLogName = SHOW_SHORT_LOG_NAME_DEFAULT;
+
+ private static final boolean LEVEL_IN_BRACKETS_DEFAULT = false;
+ boolean levelInBrackets = LEVEL_IN_BRACKETS_DEFAULT;
+
+ private static String LOG_FILE_DEFAULT = "System.err";
+ private String logFile = LOG_FILE_DEFAULT;
+ OutputChoice outputChoice = null;
+
+ private static final boolean CACHE_OUTPUT_STREAM_DEFAULT = false;
+ private boolean cacheOutputStream = CACHE_OUTPUT_STREAM_DEFAULT;
+
+ private static final String WARN_LEVELS_STRING_DEFAULT = "WARN";
+ String warnLevelString = WARN_LEVELS_STRING_DEFAULT;
+
+ private final Properties properties = new Properties();
+
+ void init() {
+ loadProperties();
+
+ String defaultLogLevelString = getStringProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, null);
+ if (defaultLogLevelString != null)
+ defaultLogLevel = stringToLevel(defaultLogLevelString);
+
+ showLogName = getBooleanProperty(SimpleLogger.SHOW_LOG_NAME_KEY, SimpleLoggerConfiguration.SHOW_LOG_NAME_DEFAULT);
+ showShortLogName = getBooleanProperty(SimpleLogger.SHOW_SHORT_LOG_NAME_KEY, SHOW_SHORT_LOG_NAME_DEFAULT);
+ showDateTime = getBooleanProperty(SimpleLogger.SHOW_DATE_TIME_KEY, SHOW_DATE_TIME_DEFAULT);
+ showThreadName = getBooleanProperty(SimpleLogger.SHOW_THREAD_NAME_KEY, SHOW_THREAD_NAME_DEFAULT);
+ dateTimeFormatStr = getStringProperty(SimpleLogger.DATE_TIME_FORMAT_KEY, DATE_TIME_FORMAT_STR_DEFAULT);
+ levelInBrackets = getBooleanProperty(SimpleLogger.LEVEL_IN_BRACKETS_KEY, LEVEL_IN_BRACKETS_DEFAULT);
+ warnLevelString = getStringProperty(SimpleLogger.WARN_LEVEL_STRING_KEY, WARN_LEVELS_STRING_DEFAULT);
+
+ logFile = getStringProperty(SimpleLogger.LOG_FILE_KEY, logFile);
+
+ cacheOutputStream = getBooleanProperty(SimpleLogger.CACHE_OUTPUT_STREAM_STRING_KEY, CACHE_OUTPUT_STREAM_DEFAULT);
+ outputChoice = computeOutputChoice(logFile, cacheOutputStream);
+
+ if (dateTimeFormatStr != null) {
+ try {
+ dateFormatter = new SimpleDateFormat(dateTimeFormatStr);
+ } catch (IllegalArgumentException e) {
+ Util.report("Bad date format in " + CONFIGURATION_FILE + "; will output relative time", e);
+ }
+ }
+ }
+
+ private void loadProperties() {
+ // Add props from the resource simplelogger.properties
+ InputStream in = AccessController.doPrivileged(new PrivilegedAction