Skip to content

Commit

Permalink
SPY-120: Adding support for SLF4J logging.
Browse files Browse the repository at this point in the history
This changeset adds support for SLF4J logging. The Logger API
has been modified to contain only very small backwards breaking
changes, it only adds TRACE support to the interface. People
not implementing the Interface directly but just implementing
the AbstractLogger only need to add the new isTraceEnabled()
method and inside the log() method also check for the TRACE
level.

As SLF4J implies, this changeset does not ship with an
actual SLF4J implementation but lets you choose it at runtime
with just adding the impl to the classpath.

Change-Id: I178ef8c8dd7417a33d0e3914a644632b98c4a265
Reviewed-on: http://review.couchbase.org/26149
Reviewed-by: Matt Ingenthron <matt@couchbase.com>
Reviewed-by: Michael Nitschinger <michael.nitschinger@couchbase.com>
Tested-by: Michael Nitschinger <michael.nitschinger@couchbase.com>
  • Loading branch information
daschl authored and Michael Nitschinger committed Jun 4, 2013
1 parent b90bc11 commit 730fe4f
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 21 deletions.
2 changes: 2 additions & 0 deletions build.xml
Expand Up @@ -472,6 +472,7 @@
<mapping conf="default" scope="compile" />
<mapping conf="runtime" scope="runtime" />
<dependency group="log4j" artifact="log4j" version="${log4j.version}" optional="true" />
<dependency group="org.slf4j" artifact="slf4j-api" version="${slf4j.version}" optional="true" />
<dependency group="org.springframework" artifact="spring-beans" version="${spring-beans.version}" optional="true" />
</ivy:makepom>

Expand All @@ -481,6 +482,7 @@
<mapping conf="default" scope="compile" />
<mapping conf="runtime" scope="runtime" />
<dependency group="log4j" artifact="log4j" version="${log4j.version}" optional="true" />
<dependency group="org.slf4j" artifact="slf4j-api" version="${slf4j.version}" optional="true" />
<dependency group="org.springframework" artifact="spring-beans" version="${spring-beans.version}" optional="true" />
</ivy:makepom>

Expand Down
2 changes: 2 additions & 0 deletions ivy.xml
Expand Up @@ -54,6 +54,8 @@ SOFTWARE.
conf="common->master" />
<dependency org="junit" name="junit" rev="${junit.version}"
conf="common->master" />
<dependency org="org.slf4j" name="slf4j-api" rev="${slf4j.version}"
conf="common->master" />
<dependency org="org.springframework" name="spring-beans"
rev="${spring-beans.version}" conf="common->master" />
<dependency org="checkstyle" name="checkstyle" rev="${checkstyle.version}"
Expand Down
1 change: 1 addition & 0 deletions ivy/libraries.properties
Expand Up @@ -28,4 +28,5 @@ mvn.version=2.0.10
jmock.version=1.2.0
junit.version=4.7
log4j.version=1.2.16
slf4j.version=1.7.5
spring-beans.version=3.0.3.RELEASE
32 changes: 32 additions & 0 deletions src/main/java/net/spy/memcached/compat/log/AbstractLogger.java
@@ -1,5 +1,6 @@
/**
* Copyright (C) 2006-2009 Dustin Sallings
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -77,6 +78,37 @@ public Throwable getThrowable(Object[] args) {
*/
public abstract boolean isInfoEnabled();

/**
* Log a message at trace level.
*
* @param message the message to log
* @param exception the exception that caused the message to be generated
*/
public void trace(Object message, Throwable exception) {
log(Level.TRACE, message, exception);
}

/**
* Log a formatted message at trace level.
*
* @param message the message to log
* @param args the arguments for that message
*/
public void trace(String message, Object... args) {
if (isDebugEnabled()) {
trace(String.format(message, args), getThrowable(args));
}
}

/**
* Log a message at trace level.
*
* @param message the message to log
*/
public void trace(Object message) {
trace(message, null);
}

/**
* Log a message at debug level.
*
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/net/spy/memcached/compat/log/DefaultLogger.java
@@ -1,5 +1,6 @@
/**
* Copyright (C) 2006-2009 Dustin Sallings
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -44,15 +45,23 @@ public DefaultLogger(String name) {
}

/**
* False.
* Always returns false, trace is not enabled on the DefaultLogger.
*/
@Override
public boolean isTraceEnabled() {
return (false);
}

/**
* Always returns false, debug is not enabled on the DefaultLogger.
*/
@Override
public boolean isDebugEnabled() {
return (false);
}

/**
* True.
* Always returns true, info is always enabled on the DefaultLogger.
*/
@Override
public boolean isInfoEnabled() {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/net/spy/memcached/compat/log/Level.java
@@ -1,5 +1,6 @@
/**
* Copyright (C) 2006-2009 Dustin Sallings
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -27,6 +28,10 @@
*/
public enum Level {

/**
* Trace level.
*/
TRACE,
/**
* Debug level.
*/
Expand Down
17 changes: 10 additions & 7 deletions src/main/java/net/spy/memcached/compat/log/Log4JLogger.java
@@ -1,5 +1,6 @@
/**
* Copyright (C) 2006-2009 Dustin Sallings
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -44,17 +45,16 @@ public Log4JLogger(String name) {
l4jLogger = Logger.getLogger(name);
}

/**
* True if the underlying logger would allow debug messages through.
*/
@Override
public boolean isTraceEnabled() {
return (l4jLogger.isTraceEnabled());
}

@Override
public boolean isDebugEnabled() {
return (l4jLogger.isDebugEnabled());
}

/**
* True if the underlying logger would allow info messages through.
*/
@Override
public boolean isInfoEnabled() {
return (l4jLogger.isInfoEnabled());
Expand All @@ -63,7 +63,7 @@ public boolean isInfoEnabled() {
/**
* Wrapper around log4j.
*
* @param level net.spy.compat.log.AbstractLogger level.
* @param level net.spy.compat.log.Level level.
* @param message object message
* @param e optional throwable
*/
Expand All @@ -72,6 +72,9 @@ public void log(Level level, Object message, Throwable e) {
org.apache.log4j.Level pLevel = org.apache.log4j.Level.DEBUG;

switch (level == null ? Level.FATAL : level) {
case TRACE:
pLevel = org.apache.log4j.Level.TRACE;
break;
case DEBUG:
pLevel = org.apache.log4j.Level.DEBUG;
break;
Expand Down
75 changes: 71 additions & 4 deletions src/main/java/net/spy/memcached/compat/log/Logger.java
@@ -1,5 +1,6 @@
/**
* Copyright (C) 2006-2009 Dustin Sallings
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -38,19 +39,62 @@ public interface Logger {
String getName();

/**
* True if debug is enabled for this logger.
* Checks whether DEBUG logging is enabled.
*
* @return true if debug messages would be displayed
* This may return true, even when the logger is configured to not put the
* resulting output anywhere. You can use this method to avoid potential
* expensive (debugging) code when there is no need for it since it will
* be dropped anyway:
*
* <pre>{@code
*if (log.isDebugEnabled()) {
* ... expensive code here ...
* log.debug(result);
*}
* }</pre>
*
* @return true if debug messages would be displayed.
*/
boolean isDebugEnabled();

/**
* True if info is enabled for this logger.
* Checks whether INFO logging is enabled.
*
* This may return true, even when the logger is configured to not put the
* resulting output anywhere. You can use this method to avoid potential
* expensive (debugging) code when there is no need for it since it will
* be dropped anyway:
*
* <pre>{@code
*if (log.isInfoEnabled()) {
* ... expensive code here ...
* log.info(result);
*}
* }</pre>
*
* @return true if info messages would be displayed
* @return true if info messages would be displayed.
*/
boolean isInfoEnabled();

/**
* Checks whether TRACE logging is enabled.
*
* This may return true, even when the logger is configured to not put the
* resulting output anywhere. You can use this method to avoid potential
* expensive (debugging) code when there is no need for it since it will
* be dropped anyway:
*
* <pre>{@code
*if (log.isTraceEnabled()) {
* ... expensive code here ...
* log.trace(result);
*}
* }</pre>
*
* @return true if trace messages would be displayed.
*/
boolean isTraceEnabled();

/**
* Log a message at the specified level.
*
Expand All @@ -68,6 +112,29 @@ public interface Logger {
*/
void log(Level level, Object message);

/**
* Log a message at trace level.
*
* @param message the message to log
* @param exception the exception that caused the message to be generated
*/
void trace(Object message, Throwable exception);

/**
* Log a message at trace level.
*
* @param message the message to log
*/
void trace(Object message);

/**
* Log a formatted message at trace level.
*
* @param message the message to log
* @param args the arguments for that message
*/
void trace(String message, Object... args);

/**
* Log a message at debug level.
*
Expand Down
104 changes: 104 additions & 0 deletions src/main/java/net/spy/memcached/compat/log/SLF4JLogger.java
@@ -0,0 +1,104 @@
/**
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* 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, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/

package net.spy.memcached.compat.log;

/**
* Logging Implementation using the <a href="http://www.slf4j.org/">SLF4J</a>
* logging facade.
*
* <p>Note that by design, the SLF4J facade does not ship with an actual
* implementation so that it can be chosen during runtime. If you fail to
* provide a logging implementation during runtime, no log messages will
* be logged. See the <a href="http://www.slf4j.org/manual.html">SLF4J
* Manual</a> for more information on how to do this.</p>
*
* <p>Since SLF4J does not support a FATAL log level, errors logged at that
* level get promoted down to ERROR, since this is the highest level
* available.</p>
*/
public class SLF4JLogger extends AbstractLogger {

private final org.slf4j.Logger logger;

/**
* Get an instance of the SLF4JLogger.
*/
public SLF4JLogger(String name) {
super(name);
logger = org.slf4j.LoggerFactory.getLogger(name);
}

@Override
public boolean isTraceEnabled() {
return logger.isTraceEnabled();
}

@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}

@Override
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}

/**
* Wrapper around SLF4J logger facade.
*
* @param level net.spy.compat.log.Level level.
* @param message object message
* @param e optional throwable
*/
@Override
public void log(Level level, Object message, Throwable e) {
if(level == null) {
level = Level.FATAL;
}

switch(level) {
case TRACE:
logger.trace(message.toString(), e);
break;
case DEBUG:
logger.debug(message.toString(), e);
break;
case INFO:
logger.info(message.toString(), e);
break;
case WARN:
logger.warn(message.toString(), e);
break;
case ERROR:
logger.error(message.toString(), e);
break;
case FATAL:
logger.error(message.toString(), e);
break;
default:
logger.error("Unhandled Logging Level: " + level
+ " with log message: " + message.toString(), e);
}
}

}

0 comments on commit 730fe4f

Please sign in to comment.