[slf4j-dev] svn commit: r721 - slf4j/trunk/osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl
Author: jconlon Date: Fri Feb 9 16:52:28 2007 New Revision: 721 Modified: slf4j/trunk/osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java Log: Check log level before creating strings. Modified: slf4j/trunk/osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java == --- slf4j/trunk/osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java (original) +++ slf4j/trunk/osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java Fri Feb 9 16:52:28 2007 @@ -120,20 +120,27 @@ * int, java.lang.String) */ public void log(ServiceReference sr, int level, String message) { - String output = createMessage(sr, message); - + switch (level) { case LOG_DEBUG: - delegate.debug(output); + if(delegate.isDebugEnabled()){ + delegate.debug(createMessage(sr, message)); + } break; case LOG_ERROR: - delegate.error(output); + if(delegate.isErrorEnabled()){ + delegate.error(createMessage(sr, message)); + } break; case LOG_INFO: - delegate.info(output); + if(delegate.isInfoEnabled()){ + delegate.info(createMessage(sr, message)); + } break; case LOG_WARNING: - delegate.warn(output); + if(delegate.isWarnEnabled()){ + delegate.warn(createMessage(sr, message)); + } break; default: break; @@ -166,20 +173,27 @@ */ public void log(ServiceReference sr, int level, String message, Throwable exception) { - String output = createMessage(sr, message); switch (level) { case LOG_DEBUG: - delegate.debug(output, exception); + if(delegate.isDebugEnabled()){ + delegate.debug(createMessage(sr, message), exception); + } break; case LOG_ERROR: - delegate.error(output, exception); + if(delegate.isErrorEnabled()){ + delegate.error(createMessage(sr, message), exception); + } break; case LOG_INFO: - delegate.info(output, exception); + if(delegate.isInfoEnabled()){ + delegate.info(createMessage(sr, message), exception); + } break; case LOG_WARNING: - delegate.warn(output, exception); + if(delegate.isWarnEnabled()){ + delegate.warn(createMessage(sr, message), exception); + } break; default: break; ___ dev mailing list dev@slf4j.org http://www.slf4j.org/mailman/listinfo/dev
Re: [slf4j-dev] [logback-user] LoggerFactory question
At 07:04 PM 2/9/2007, Eric Crahen wrote: >I'm using Logback, but I build my code only against the SLF4J api. One >thing that I found strange was that LoggerFactory is not actually part of >the SLF4J api. Correct. >This poses a challenge to me, because I will need to depend on some >arbitrary implementation of an SLF4J api (probably the nop one) in order >to build my code. Then at deployment time, I need to remove that >slf4j-noop dependency and swap in a different one. The reason this is >tricky for me is that the deployment process I use currently is >(compile-time dependencies + extra runtime dependencies). The style in >slf4j creates a ((compile-time dependencies - slf4j-nop) + runtime >dependencies). This process is part of a larger overarching system that my >organization happens to use, so bucking the trend isn't too fun - though >possible. > >Also, it seems like all these implementations of LoggerFactory are pretty >much identical. I think that these could be consolidated into a single >LoggerFactory in the slf4-api package. This package could make use of the >ServiceProvider mechanism thats present in Java 4 & 5 + standard in Java 6 >to load the underlying Logger implementations. What do you think? I could >probably contribute a patch that would demonstrate how this might work. Hi Eric, This issue came up previously and will continue to haunt us for the foreseeable future. I'd wouldn't be exaggerating if I said that I'd be very much interested in your contribution. I am CCing the slf4j-dev list as well. You might want to submit your proposal there instead. >- Eric -- Ceki Gülcü Logback: The reliable, generic, fast and flexible logging framework for Java. http://logback.qos.ch ___ dev mailing list dev@slf4j.org http://www.slf4j.org/mailman/listinfo/dev
[slf4j-dev] svn commit: r722 - in slf4j/trunk: jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl slf4j-api/src/main/java/org/slf4j/spi slf4j-jdk14/src/main/java/org/slf4j/impl slf4j-log4
Author: ceki Date: Fri Feb 9 22:49:30 2007 New Revision: 722 Added: slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java slf4j/trunk/slf4j-api/src/main/java/org/slf4j/spi/LocationAwareLogger.java Modified: slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4FLogFactory.java slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java Log: It looks like theres is a simple fix for bug#23 (see [1]). It won't impact existing clients, not existing bindings. [1] http://bugzilla.slf4j.org/show_bug.cgi?id=23 Modified: slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4FLogFactory.java == --- slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4FLogFactory.java (original) +++ slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4FLogFactory.java Fri Feb 9 22:49:30 2007 @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.spi.LocationAwareLogger; /** * @@ -152,7 +153,11 @@ instance = (Log) loggerMap.get(name); if (instance == null) { Logger logger = LoggerFactory.getLogger(name); -instance = new SLF4JLog(logger); +if(logger instanceof LocationAwareLogger) { + instance = new SLF4JLocationAwareLog((LocationAwareLogger) logger); +} else { + instance = new SLF4JLog(logger); +} loggerMap.put(name, instance); } } Added: slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java == --- (empty file) +++ slf4j/trunk/jcl104-over-slf4j/src/main/java/org/apache/commons/logging/impl/SLF4JLocationAwareLog.java Fri Feb 9 22:49:30 2007 @@ -0,0 +1,200 @@ +// TOTO + +package org.apache.commons.logging.impl; + +import org.apache.commons.logging.Log; +import org.slf4j.Logger; +import org.slf4j.spi.LocationAwareLogger; + +/** + * Implementation of [EMAIL PROTECTED] Log org.apache.commons.logging.Log} interface which + * delegates all processing to a wrapped [EMAIL PROTECTED] Logger org.slf4j.Logger} instance. + * + * JCL's FATAL and TRACE levels are mapped to ERROR and DEBUG respectively. All + * other levels map one to one. + * + * @author Ceki Gülcü + */ +public class SLF4JLocationAwareLog implements Log { + + private LocationAwareLogger logger; + private static final String FQCN = SLF4JLocationAwareLog.class.getName(); + + SLF4JLocationAwareLog(LocationAwareLogger logger) { +this.logger = logger; + } + + /** + * Directly delegates to the wrapped org.slf4j.Logger instance. + */ + public boolean isDebugEnabled() { +return logger.isDebugEnabled(); + } + + /** + * Directly delegates to the wrapped org.slf4j.Logger instance. + */ + public boolean isErrorEnabled() { +return logger.isErrorEnabled(); + } + + /** + * Delegates to the isErrorEnabled method of the wrapped + * org.slf4j.Logger instance. + */ + public boolean isFatalEnabled() { +return logger.isErrorEnabled(); + } + + /** + * Directly delegates to the wrapped org.slf4j.Logger instance. + */ + public boolean isInfoEnabled() { +return logger.isInfoEnabled(); + } + + /** + * Delegates to the isDebugEnabled method of the wrapped + * org.slf4j.Logger instance. + */ + public boolean isTraceEnabled() { +return logger.isDebugEnabled(); + } + + /** + * Directly delegates to the wrapped org.slf4j.Logger instance. + */ + public boolean isWarnEnabled() { +return logger.isWarnEnabled(); + } + + /** + * Converts the input parameter to String and then delegates to + * the debug method of the wrapped org.slf4j.Logger instance. + * + * @param message the message to log. Converted to [EMAIL PROTECTED] String} + */ + public void trace(Object message) { +logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null); + } + + /** + * Converts the first input parameter to String and then delegates to + * the debug method of the wrapped org.slf4j.Logger instance. + * + * @param message the message to log. Converted to [EMAIL PROTECTED] String} + * @param t the exception to log + */ + public void trace(Object message, Throwable t) { +logger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), t); + } + + /** + * Converts the input parameter to String and then delegates to the wrapped + * org.slf4j.Logger instance. + * + * @param message the message to log. Converted to [EMAIL PROTECTED] String} + */ + public void debug(Object message) {
[slf4j-dev] [Bug 23] bogus jcl-over-slf4j impl - %F, %L etc. off by one
show_bug.cgi?id=23 --- Comment #2 from [EMAIL PROTECTED] 2007-02-09 22:50 --- I just committed a fix for this bug. After its tested, it should be included in SLF4J version 1.3. -- Configure bugmail: userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug, or are watching the assignee. ___ dev mailing list dev@slf4j.org http://www.slf4j.org/mailman/listinfo/dev
[slf4j-dev] Consolidating the LoggerFactory / A better plugin mechanism
I've been using the SLF4J API in some of my work and one thing about it that makes it very awkward, from a dependency mangement standpoint, is that one of the core APIs - the LoggerFactory - is actually not a part of the slf4j-api package. Instead, its actually reimplemented in each of the slf4j implementations. This is awkward for various reasons, 1. The API is incomplete. I actually can't build anything against the API since I really do require a LoggerFactory; I need to choose an arbitrary implementation to build against. 2. It complicates deployments in some situations where compile-time-dependencies + run-time-dependencies because of #1. 4. All of the LoggerFactory implementations are basically identical 3. I have to hope everyone uses the same LoggerFactory signature. The nice part is, that with the mechanism SLF4J has, selecting a Logger implementation ss purely a deployment issue. Just deploy the right jar and the Logger you pick takes effect. That's very handy. I think that we can resolve the undesirable issues while still retaining the behavior we have today. Here is my proposal: Create a single LoggerFactory and placed it into slf4j-api, and deleted the LoggerFactory classes everywhere else they exist (slf4j-simple, logback, etc). This new LoggerFactory leverages Sun's ServiceProvider API which exists in all JDK's since 1.4 (maybe 1.3). It looks like this: package org.slf4j; import sun.misc.Service; import org.slf4j.impl.Util; import java.util.Iterator; /** * This class is a simple wrapper over Sun's Service provider * factory. It provides a standard mechanism for loading plugins * in a simple way. */ public abstract class LoggerFactory { private static final ILoggerFactory factory; // Initialize the real ILoggerFactory static { ILoggerFactory f = null; try { // Use the current context ClassLoader to enumerate all the resources // that define ILoggerFactory services. for(Iterator i = Service.providers(ILoggerFactory.class); i.hasNext(); ) { Object o = i.next(); if(f == null) f = (ILoggerFactory)o; else Util.reportWarning("More than once service provider was defined"); } factory = f; if(f == null) { // TODO: Should there be a simple fall back on a System.out logger? // TODO: Perhaps the simple loggers is included with SLF4J-API and // TODO: Is selected always, unless another implementation is provided } } public static Logger getLogger(Class name) { return getLogger(name.getName()); } public static Logger getLogger(String name) { if(factory != null) return factory.getLogger(name); // TODO: Not a problem if the above suggestion is taken throw new IllegalStateException("No " + ILoggerFactory.class + " implementation was provided!"); } } The simple explanation of this is that all the magic happens in the Service class. What it does, for those who are unfamilair, is that it uses the context ClassLoader to locate a resource named services/<>. This resource can contain multiple lines of text, each line should be the fully qualified class name of a concrete implementation of the interface you asked for. This class should have a default constructor. To give an example of this simple class can be used in place of what we have now I'll walk through an example of how I refitted the slf4j-simple package to utilize this, Step #1: Delete slf4j-simple/src/main/java/org/slf4j/LoggerFactory.java Step #2: Create slf4j-simple/src/main/resources/META-INF/services/org.slf4j.ILoggerFactory Step #3: Add a line the the above resource file which reads " org.slf4j.impl.SimpleLoggerFactory" This can be repeated for each SLF4J provider (implementation of the API). Benefits: * slf4j-api is now complete - this is *all* people need to build against and depend on * This exact same approach can be used to resolve the similar issue it looks like the MarkerFactory faces. * This preserves the existing behavior of deploy-what-you-want. Its still 0 config to select an implementation. Drawbacks: * Depends on sun.misc -- (resolvable) Although this is an internal sun class, they actually do a good job of maintaining it, and it exists in SE4, SE5 & SE6. It's understandable to be nervous about depending on it. Maybe some cleanroom implementations don't support it (blackdown?) We could write a simpler version of the Service class which does the same thing, its really not that much code and I could provide this if you want. I would personally like to see such an enhancement to SLF4J, I don't know about others. Any thoughts or comments? -- - Eric LoggerFactory.java Description: Binary data slf4j-1.2-patch.tgz Description: GNU Zip compressed data ___ dev mailing list dev@slf4j.org http://www.slf4j.org/mailman/listinfo/dev