/* * Copyright (c) 2004-2005 SLF4J.ORG * Copyright (c) 2004-2005 QOS.ch * * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, and/or sell copies of the Software, and to permit persons * to whom the Software is furnished to do so, provided that the above * copyright notice(s) and this permission notice appear in all copies of * the Software and that both the above copyright notice(s) and this * permission notice appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Except as contained in this notice, the name of a copyright holder * shall not be used in advertising or otherwise to promote the sale, use * or other dealings in this Software without prior written authorization * of the copyright holder. * */ package org.slf4j.impl; import org.slf4j.helpers.FormattingTuple; import org.slf4j.helpers.MarkerIgnoringBase; import org.slf4j.helpers.MessageFormatter; /** * A simple (and direct) implementation that logs messages of level * INFO or higher on the console (System.err). * *

The 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.
304 [main] INFO examples.SortAlgo - Dump of integer array:
317 [main] INFO examples.SortAlgo - Element [0] = 0
331 [main] INFO examples.SortAlgo - Element [1] = 1
343 [main] INFO examples.Sort - The next log statement should be an error message.
346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array.
        at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
        at org.log4j.examples.Sort.main(Sort.java:64)
467 [main] INFO  examples.Sort - Exiting main method.
* * @author Ceki Gülcü */ public class SimpleLogger extends MarkerIgnoringBase { public static final String LOG_LEVEL_PROPERTY = "org.slf4j.LogLevel"; static final String TRACE_STR; static final String DEBUG_STR; static final String INFO_STR; static final String WARN_STR; static final String ERROR_STR; private static final long serialVersionUID = -6560244151660620173L; private static final long startTime; private static final String LINE_SEPARATOR; static String logLevel; private static final boolean isTraceEnabled; private static final boolean isDebugEnabled; private static final boolean isInfoEnabled; private static final boolean isWarnEnabled; static { /** * Mark the time when this class gets loaded into memory. */ startTime = System.currentTimeMillis(); /** * Get line separtator for plattform specific line end output. */ LINE_SEPARATOR = System.getProperty("line.separator"); /** * Initialize strings for log output. */ TRACE_STR = "TRACE"; DEBUG_STR = "DEBUG"; INFO_STR = "INFO"; WARN_STR = "WARN"; ERROR_STR = "ERROR"; /** * Initialize strings for log outp. */ logLevel = System.getProperty( LOG_LEVEL_PROPERTY, "INFO" ); if(TRACE_STR.equalsIgnoreCase(logLevel)){ isTraceEnabled = true; isDebugEnabled = true; isInfoEnabled = true; isWarnEnabled = true; } else if( DEBUG_STR.equalsIgnoreCase(logLevel) ){ isTraceEnabled = false; isDebugEnabled = true; isInfoEnabled = true; isWarnEnabled = true; } else if( INFO_STR.equalsIgnoreCase(logLevel) ){ isTraceEnabled = false; isDebugEnabled = false; isInfoEnabled = true; isWarnEnabled = true; } else if( WARN_STR.equalsIgnoreCase(logLevel) ){ isTraceEnabled = false; isDebugEnabled = false; isInfoEnabled = false; isWarnEnabled = true; } else if( ERROR_STR.equalsIgnoreCase(logLevel) ){ isTraceEnabled = false; isDebugEnabled = false; isInfoEnabled = false; isWarnEnabled = false; } else { System.err.println("ERROR - Property org.slf4j.LogLevel found but not recognized; Using INFO level! ( was: " + logLevel + " )"); logLevel = INFO_STR; isTraceEnabled = false; isDebugEnabled = false; isInfoEnabled = true; isWarnEnabled = true; } } /** * Package access allows only {@link SimpleLoggerFactory} to instantiate * SimpleLogger instances. */ SimpleLogger(String name) { this.name = name; } /** * This is our internal implementation for logging regular (non-parameterized) * log messages. * * @param level * @param message * @param t */ private void log(String level, String message, Throwable t) { StringBuffer buf = new StringBuffer(); long millis = System.currentTimeMillis(); buf.append(millis - startTime); buf.append(" ["); buf.append(Thread.currentThread().getName()); buf.append("] "); buf.append(level); buf.append(" "); buf.append(name); buf.append(" - "); buf.append(message); buf.append(LINE_SEPARATOR); System.err.print(buf.toString()); if (t != null) { t.printStackTrace(System.err); } System.err.flush(); } /** * For formatted messages, first substitute arguments and then log. * * @param level * @param format * @param param1 * @param param2 */ private void formatAndLog( String level, String format, Object arg1, Object arg2) { FormattingTuple tp = MessageFormatter.format(format, arg1, arg2); log(level, tp.getMessage(), tp.getThrowable()); } /** * For formatted messages, first substitute arguments and then log. * * @param level * @param format * @param argArray */ private void formatAndLog(String level, String format, Object[] argArray) { FormattingTuple tp = MessageFormatter.arrayFormat(format, argArray); log(level, tp.getMessage(), tp.getThrowable()); } /** * Determines if this Logger is enabled for logs of level TRACE. * @return true if enabled, false if not */ public boolean isTraceEnabled() { return isTraceEnabled; } /** * A simple implementation which always logs messages of level TRACE according * to the format outlined above. */ public void trace(String msg) { if(!isTraceEnabled){ return; } log(TRACE_STR, msg, null); } /** * Perform single parameter substitution before logging the message of level * TRACE according to the format outlined above. */ public void trace(String format, Object arg) { if(!isTraceEnabled){ return; } formatAndLog(TRACE_STR, format, arg, null); } /** * Perform double parameter substitution before logging the message of level * TRACE according to the format outlined above. */ public void trace(String format, Object arg1, Object arg2) { if(!isTraceEnabled){ return; } formatAndLog(TRACE_STR, format, arg1, arg2); } /** * Perform double parameter substitution before logging the message of level * TRACE according to the format outlined above. */ public void trace(String format, Object[] argArray) { if(!isTraceEnabled){ return; } formatAndLog(TRACE_STR, format, argArray); } /** * Log a message of level TRACE, including an exception. */ public void trace(String msg, Throwable t) { if(!isTraceEnabled){ return; } log(INFO_STR, msg, t); } /** * Determines if this Logger is enabled for logs of level DEBUG. * @return true if enabled, false if not */ public boolean isDebugEnabled() { return isDebugEnabled; } /** * A simple implementation which always logs messages of level DEBUG according * to the format outlined above. */ public void debug(String msg) { if(!isDebugEnabled){ return; } log(DEBUG_STR, msg, null); } /** * Perform single parameter substitution before logging the message of level * DEBUG according to the format outlined above. */ public void debug(String format, Object arg) { if(!isDebugEnabled){ return; } formatAndLog(DEBUG_STR, format, arg, null); } /** * Perform double parameter substitution before logging the message of level * DEBUG according to the format outlined above. */ public void debug(String format, Object arg1, Object arg2) { if(!isDebugEnabled){ return; } formatAndLog(DEBUG_STR, format, arg1, arg2); } /** * Perform double parameter substitution before logging the message of level * DEBUG according to the format outlined above. */ public void debug(String format, Object[] argArray) { if(!isDebugEnabled){ return; } formatAndLog(DEBUG_STR, format, argArray); } /** * Log a message of level DEBUG, including an exception. */ public void debug(String msg, Throwable t) { if(!isDebugEnabled){ return; } log(DEBUG_STR, msg, t); } /** * Determines if this Logger is enabled for logs of level INFO. * @return true if enabled, false if not */ public boolean isInfoEnabled() { return isInfoEnabled; } /** * A simple implementation which always logs messages of level INFO according * to the format outlined above. */ public void info(String msg) { if(!isInfoEnabled){ return; } log(INFO_STR, msg, null); } /** * Perform single parameter substitution before logging the message of level * INFO according to the format outlined above. */ public void info(String format, Object arg) { if(!isInfoEnabled){ return; } formatAndLog(INFO_STR, format, arg, null); } /** * Perform double parameter substitution before logging the message of level * INFO according to the format outlined above. */ public void info(String format, Object arg1, Object arg2) { if(!isInfoEnabled){ return; } formatAndLog(INFO_STR, format, arg1, arg2); } /** * Perform double parameter substitution before logging the message of level * INFO according to the format outlined above. */ public void info(String format, Object[] argArray) { if(!isInfoEnabled){ return; } formatAndLog(INFO_STR, format, argArray); } /** * Log a message of level INFO, including an exception. */ public void info(String msg, Throwable t) { if(!isInfoEnabled){ return; } log(INFO_STR, msg, t); } /** * Determines if this Logger is enabled for logs of level WARN. * @return true if enabled, false if not */ public boolean isWarnEnabled() { return isWarnEnabled; } /** * A simple implementation which always logs messages of level WARN according * to the format outlined above. */ public void warn(String msg) { if(!isWarnEnabled){ return; } log(WARN_STR, msg, null); } /** * Perform single parameter substitution before logging the message of level * WARN according to the format outlined above. */ public void warn(String format, Object arg) { if(!isWarnEnabled){ return; } formatAndLog(WARN_STR, format, arg, null); } /** * Perform double parameter substitution before logging the message of level * WARN according to the format outlined above. */ public void warn(String format, Object arg1, Object arg2) { if(!isWarnEnabled){ return; } formatAndLog(WARN_STR, format, arg1, arg2); } /** * Perform double parameter substitution before logging the message of level * WARN according to the format outlined above. */ public void warn(String format, Object[] argArray) { if(!isWarnEnabled){ return; } formatAndLog(WARN_STR, format, argArray); } /** * Log a message of level WARN, including an exception. */ public void warn(String msg, Throwable t) { if(!isWarnEnabled){ return; } log(WARN_STR, msg, t); } /** * Always returns true. */ public boolean isErrorEnabled() { return true; } /** * A simple implementation which always logs messages of level ERROR according * to the format outlined above. */ public void error(String msg) { log(ERROR_STR, msg, null); } /** * Perform single parameter substitution before logging the message of level * ERROR according to the format outlined above. */ public void error(String format, Object arg) { formatAndLog(ERROR_STR, format, arg, null); } /** * Perform double parameter substitution before logging the message of level * ERROR according to the format outlined above. */ public void error(String format, Object arg1, Object arg2) { formatAndLog(ERROR_STR, format, arg1, arg2); } /** * Perform double parameter substitution before logging the message of level * ERROR according to the format outlined above. */ public void error(String format, Object[] argArray) { formatAndLog(ERROR_STR, format, argArray); } /** * Log a message of level ERROR, including an exception. */ public void error(String msg, Throwable t) { log(ERROR_STR, msg, t); } }