- decoupling slf4j version numbers from slf4j-ext version

- moved the NOPLoger class from slf4j-nop module to slf4j-api. An NOPLogger came in handy in slf4j-ext 
- ongoing work on XLogger.java
- other minor improvements in the docs
This commit is contained in:
Ceki Gulcu 2008-08-02 19:24:58 +00:00
parent 98f51c88c1
commit 053a98b2a0
8 changed files with 401 additions and 73 deletions

View File

@ -19,8 +19,7 @@
<inceptionYear>2005</inceptionYear>
<properties>
<!-- <project_version_for_osgi>1.3.0</project_version_for_osgi> -->
<pv4osgi>1.4.3</pv4osgi>
<slf4j-ext-version>1.0-alpha0</slf4j-ext-version>
</properties>
<modules>
@ -53,7 +52,7 @@
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${project.version}</version>
</dependency>

View File

@ -0,0 +1,238 @@
/*
* 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.helpers;
import org.slf4j.Logger;
import org.slf4j.helpers.MarkerIgnoringBase;
/**
* A direct NOP (no operation) implementation of {@link Logger}.
*
* @author Ceki G&uuml;lc&uuml;
*/
public class NOPLogger extends MarkerIgnoringBase {
private static final long serialVersionUID = -517220405410904473L;
/**
* The unique instance of NOPLogger.
*/
public static final NOPLogger NOP_LOGGER = new NOPLogger();
/**
* There is no point in creating multiple instances of NOPLOgger,
* except by derived classes, hence the protected access for the constructor.
*/
protected NOPLogger() {
}
/**
* Always returns the string value "NOP".
*/
public String getName() {
return "NOP";
}
/**
* Always returns false.
* @return always false
*/
final public boolean isTraceEnabled() {
return false;
}
/** A NOP implementation. */
final public void trace(String msg) {
// NOP
}
/** A NOP implementation. */
final public void trace(String format, Object arg) {
// NOP
}
/** A NOP implementation. */
public final void trace(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
public final void trace(String format, Object[] argArray) {
// NOP
}
/** A NOP implementation. */
final public void trace(String msg, Throwable t) {
// NOP
}
/**
* Always returns false.
* @return always false
*/
final public boolean isDebugEnabled() {
return false;
}
/** A NOP implementation. */
final public void debug(String msg) {
// NOP
}
/** A NOP implementation. */
final public void debug(String format, Object arg) {
// NOP
}
/** A NOP implementation. */
public final void debug(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
public final void debug(String format, Object[] argArray) {
// NOP
}
/** A NOP implementation. */
final public void debug(String msg, Throwable t) {
// NOP
}
/**
* Always returns false.
* @return always false
*/
final public boolean isInfoEnabled() {
// NOP
return false;
}
/** A NOP implementation. */
final public void info(String msg) {
// NOP
}
/** A NOP implementation. */
final public void info(String format, Object arg1) {
// NOP
}
/** A NOP implementation. */
final public void info(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
public final void info(String format, Object[] argArray) {
// NOP
}
/** A NOP implementation. */
final public void info(String msg, Throwable t) {
// NOP
}
/**
* Always returns false.
* @return always false
*/
final public boolean isWarnEnabled() {
return false;
}
/** A NOP implementation. */
final public void warn(String msg) {
// NOP
}
/** A NOP implementation. */
final public void warn(String format, Object arg1) {
// NOP
}
/** A NOP implementation. */
final public void warn(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
public final void warn(String format, Object[] argArray) {
// NOP
}
/** A NOP implementation. */
final public void warn(String msg, Throwable t) {
// NOP
}
/** A NOP implementation. */
final public boolean isErrorEnabled() {
return false;
}
/** A NOP implementation. */
final public void error(String msg) {
// NOP
}
/** A NOP implementation. */
final public void error(String format, Object arg1) {
// NOP
}
/** A NOP implementation. */
final public void error(String format, Object arg1, Object arg2) {
// NOP
}
/** A NOP implementation. */
public final void error(String format, Object[] argArray) {
// NOP
}
/** A NOP implementation. */
final public void error(String msg, Throwable t) {
// NOP
}
}

View File

@ -12,6 +12,7 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>${slf4j-ext-version}</version>
<packaging>jar</packaging>
<name>SLF4J Extensions Module</name>
@ -22,11 +23,12 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${parent.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${project.version}</version>
<version>${parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@ -1,61 +0,0 @@
package org.slf4j;
import org.slf4j.helpers.MessageFormatter;
import org.slf4j.spi.LocationAwareLogger;
/**
* A utility that provides standard mechanisms for logging certain kinds of
* activities.
*
* @author Ralph Goers
* @author Ceki Gulcu
*/
public class LoggerX {
private static final String FQCN = LoggerX.class.getName();
static Marker FLOW_MARKER = MarkerFactory.getMarker("FLOW");
static Marker ENTRY_MARKER = MarkerFactory.getMarker("ENTER");
static Marker EXIT_MARKER = MarkerFactory.getMarker("EXIT");
static Marker EXCEPTION_MARKER = MarkerFactory.getMarker("EXCEPTION");
static Marker DIAG_MARKER = MarkerFactory.getMarker("DIAG");
static String ENTRY_MESSAGE_0 = "entry";
static String ENTRY_MESSAGE_1 = "entry with params ({})";
static String ENTRY_MESSAGE_2 = "entry with params ({}, {})";
static String ENTRY_MESSAGE_3 = "entry with params ({}, {}, {})";
static String ENTRY_MESSAGE_4 = "entry with params ({}, {}, {}, {})";
static int ENTRY_MESSAGE_ARRAY_LEN = 5;
static String[] ENTRY_MESSAGE_ARRAY = new String[ENTRY_MESSAGE_ARRAY_LEN];
static {
ENTRY_MARKER.add(FLOW_MARKER);
EXIT_MARKER.add(FLOW_MARKER);
ENTRY_MESSAGE_ARRAY[0] = ENTRY_MESSAGE_0;
ENTRY_MESSAGE_ARRAY[1] = ENTRY_MESSAGE_1;
ENTRY_MESSAGE_ARRAY[2] = ENTRY_MESSAGE_2;
ENTRY_MESSAGE_ARRAY[3] = ENTRY_MESSAGE_3;
ENTRY_MESSAGE_ARRAY[4] = ENTRY_MESSAGE_4;
}
/**
* Log entry to a method
*
* @param logger
* the Logger to log with.
*/
public static void entering(Logger logger, Object... argArray) {
if (logger.isDebugEnabled(ENTRY_MARKER)
&& logger instanceof LocationAwareLogger) {
String messagePattern = "";
if(argArray.length <= ENTRY_MESSAGE_ARRAY_LEN) {
messagePattern = ENTRY_MESSAGE_ARRAY[argArray.length];
}
String msg = MessageFormatter.arrayFormat(messagePattern, argArray);
((LocationAwareLogger) logger).log(ENTRY_MARKER, FQCN,
LocationAwareLogger.ERROR_INT, msg, null);
}
}
}

View File

@ -0,0 +1,140 @@
package org.slf4j;
import org.slf4j.helpers.MessageFormatter;
import org.slf4j.helpers.NOPLogger;
import org.slf4j.spi.LocationAwareLogger;
/**
* A utility that provides standard mechanisms for logging certain kinds of
* activities.
*
* @author Ralph Goers
* @author Ceki Gulcu
*/
public class XLogger {
private static final String FQCN = XLogger.class.getName();
static Marker FLOW_MARKER = MarkerFactory.getMarker("FLOW");
static Marker ENTRY_MARKER = MarkerFactory.getMarker("ENTER");
static Marker EXIT_MARKER = MarkerFactory.getMarker("EXIT");
static Marker EXCEPTION_MARKER = MarkerFactory.getMarker("EXCEPTION");
static Marker THROWING_MARKER = MarkerFactory.getMarker("EXCEPTION");
static Marker CATCHING_MARKER = MarkerFactory.getMarker("EXCEPTION");
static String EXIT_MESSAGE_0 = "exit";
static String EXIT_MESSAGE_1 = "exit with {}";
static String ENTRY_MESSAGE_0 = "entry";
static String ENTRY_MESSAGE_1 = "entry with ({})";
static String ENTRY_MESSAGE_2 = "entry with ({}, {})";
static String ENTRY_MESSAGE_3 = "entry with ({}, {}, {})";
static String ENTRY_MESSAGE_4 = "entry with ({}, {}, {}, {})";
static int ENTRY_MESSAGE_ARRAY_LEN = 5;
static String[] ENTRY_MESSAGE_ARRAY = new String[ENTRY_MESSAGE_ARRAY_LEN];
static {
ENTRY_MARKER.add(FLOW_MARKER);
EXIT_MARKER.add(FLOW_MARKER);
THROWING_MARKER.add(EXCEPTION_MARKER);
CATCHING_MARKER.add(EXCEPTION_MARKER);
ENTRY_MESSAGE_ARRAY[0] = ENTRY_MESSAGE_0;
ENTRY_MESSAGE_ARRAY[1] = ENTRY_MESSAGE_1;
ENTRY_MESSAGE_ARRAY[2] = ENTRY_MESSAGE_2;
ENTRY_MESSAGE_ARRAY[3] = ENTRY_MESSAGE_3;
ENTRY_MESSAGE_ARRAY[4] = ENTRY_MESSAGE_4;
}
final Logger logger;
public XLogger(Logger logger) {
if (logger instanceof LocationAwareLogger) {
this.logger = logger;
} else {
// if the logger is not location aware, assume that
// there is no point in further effort
this.logger = NOPLogger.NOP_LOGGER;
}
}
/**
* Log method entry.
*
* @param argArray
* supplied parameters
*/
public void entry(Object... argArray) {
if (logger.isTraceEnabled(ENTRY_MARKER)) {
String messagePattern = null;
if (argArray.length <= ENTRY_MESSAGE_ARRAY_LEN) {
messagePattern = ENTRY_MESSAGE_ARRAY[argArray.length];
} else {
messagePattern = buildMessagePattern(argArray.length);
}
String formattedMessage = MessageFormatter.arrayFormat(messagePattern,
argArray);
((LocationAwareLogger) logger).log(ENTRY_MARKER, FQCN,
LocationAwareLogger.TRACE_INT, formattedMessage, null);
}
}
/**
* Log method exit
*/
public void exit() {
if (logger.isTraceEnabled(ENTRY_MARKER)) {
((LocationAwareLogger) logger).log(EXIT_MARKER, FQCN,
LocationAwareLogger.TRACE_INT, EXIT_MESSAGE_0, null);
}
}
/**
* Log method exit
*
* @param result
* The result of the method being exited
*/
public void exit(Object result) {
if (logger.isTraceEnabled(ENTRY_MARKER)) {
String formattedMessage = MessageFormatter.format(EXIT_MESSAGE_0, result);
((LocationAwareLogger) logger).log(EXIT_MARKER, FQCN,
LocationAwareLogger.TRACE_INT, formattedMessage, null);
}
}
/**
* Log an exception being thrown
*
* @param throwable
* the exception being caught.
*/
public void throwing(Throwable throwable) {
((LocationAwareLogger) logger).log(THROWING_MARKER, FQCN,
LocationAwareLogger.ERROR_INT, "throwing", throwable);
}
/**
* Log an exception being caught
*
* @param throwable
* the exception being caught.
*/
public void catching(Throwable throwable) {
((LocationAwareLogger) logger).log(CATCHING_MARKER, FQCN,
LocationAwareLogger.ERROR_INT, "catching", throwable);
}
private static String buildMessagePattern(int len) {
StringBuilder sb = new StringBuilder();
sb.append(" entry with (");
for (int i = 0; i < len; i++) {
sb.append("{}");
if (i != len - 1)
sb.append(", ");
}
sb.append(')');
return sb.toString();
}
}

View File

@ -7,6 +7,7 @@ public class LoggerXTest extends TestCase {
Logger logger = LoggerFactory.getLogger(this.getClass());
public void testSmoke() {
LoggerX.entering(logger);
XLogger xLogger = new XLogger(logger);
xLogger.entry(logger);
}
}

View File

@ -597,8 +597,7 @@ debug(String msg, Throwable t);</p>
less than 1% of the time it takes to actually log a statement.
</p>
<p><b>Better alternative based on parameterized
messages</b></p>
<p><b>Better yet, use parameterized messages</b></p>
<p>There exists a very convenient alternative based on message
formats. Assuming <code>entry</code> is an object, you can write:
@ -642,7 +641,13 @@ logger.debug("The new entry is {}.", entry);</p>
<p class="source">logger.debug("Value {} was inserted between {} and {}.",
new Object[] {newVal, below, above});</p>
<p></p>
<p></p>
<p>Array type arguments, including multi-dimensional arrays,
are also supported. However, cyclical or recursive arrays are
<em>not</em> suported and will result in a stack overflow
error.</p>
<p>SLF4J uses its own message formatting implementation which
differs from that of the Java platform. This is justified by
the fact that SLF4J's implementation performs several orders

View File

@ -55,12 +55,16 @@ prefix='';
</p>
<p>Added support for array values in parameters. For example,</p>
<p class="source">log.debug("a:{},i:{}", "A", new int[] {1, 2}});</p>
<p>will print as "a:A,i:[1, 2]" instead of "a:A,i:[I@6ca1c" as
previously. This enhancement was proposed by "lizongbo"
<p>Added support for array values, including multi-dimensional
arrays, as parameters. For example,</p>
<p class="source">log.debug("{} {}", "A", new int[] {1, 2}});</p>
<p>will print as "A [1, 2]" instead of "A [I@6ca1c" as
previously. This enhancement was proposed by "lizongbo". Cyclical or
recursive arrays are <em>not</em> supported. Such arrays will cause
a stack overflow error.
</p>
<p>Added missing <code>getInstance</code> methods to the
<code>Category</code> class in the log4j-over-slf4j module, fixing
<a href="http://bugzilla.slf4j.org/show_bug.cgi?id=95">bug 95</a>