blob: ca2097b9b5b04a7b8c79d29b4d4f18f6249e2f32 [file] [log] [blame]
/*
* Copyright (c) 2004-2007 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, 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 DEALINGS IN THE SOFTWARE.
*/
package org.slf4j;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.helpers.SubstituteLoggerFactory;
import org.slf4j.helpers.Util;
import org.slf4j.impl.StaticLoggerBinder;
/**
* The <code>LoggerFactory</code> is a utility class producing Loggers for
* various logging APIs, most notably for log4j, logback and JDK 1.4 logging.
* Other implementations such as {@link org.slf4j.impl.NOPLogger NOPLogger} and
* {@link org.slf4j.impl.SimpleLogger SimpleLogger} are also supported.
*
* <p>
* <code>LoggerFactory</code> is essentially a wrapper around an
* {@link ILoggerFactory} instance bound with <code>LoggerFactory</code> at
* compile time.
*
* <p>
* Please note that all methods in <code>LoggerFactory</code> are static.
*
* @author Ceki G&uuml;lc&uuml;
*/
public final class LoggerFactory {
static ILoggerFactory loggerFactory;
static final String NO_STATICLOGGERBINDER_URL = "http://www.slf4j.org/codes.html#StaticLoggerBinder";
static final String NULL_LF_URL = "http://www.slf4j.org/codes.html#null_LF";
static final String VERSION_MISMATCH = "http://www.slf4j.org/codes.html#version_mismatch";
static final String SUBSTITUTE_LOGGER_URL = "http://www.slf4j.org/codes.html#substituteLogger";
/**
* It is out responsibility to track version changes and manage the
* compatibility list.
*
* <p>
*/
static private final String[] API_COMPATIBILITY_LIST = new String[] { "1.5.5" };
// private constructor prevents instantiation
private LoggerFactory() {
}
static {
staticInitialize();
versionSanityCheck();
}
private final static void staticInitialize() {
try {
// support re-entrant behavior.
// See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
List loggerNameList = new ArrayList();
loggerFactory = new SubstituteLoggerFactory(loggerNameList);
loggerFactory = StaticLoggerBinder.SINGLETON.getLoggerFactory();
emitSubstitureLoggerWarning(loggerNameList);
} catch (NoClassDefFoundError ncde) {
loggerFactory = null; // undo SubstituteLoggerFactory assignment
String msg = ncde.getMessage();
if (msg != null && msg.indexOf("org/slf4j/impl/StaticLoggerBinder") != -1) {
Util
.reportFailure("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Util.reportFailure("See " + NO_STATICLOGGERBINDER_URL
+ " for further details.");
}
throw ncde;
} catch (Exception e) {
loggerFactory = null; // undo SubstituteLoggerFactory assignment
// we should never get here
Util.reportFailure("Failed to instantiate logger ["
+ StaticLoggerBinder.SINGLETON.getLoggerFactoryClassStr() + "]", e);
}
}
private final static void emitSubstitureLoggerWarning(List loggerNameList) {
if (loggerNameList.size() == 0) {
return;
}
Util
.reportFailure("The following loggers will not work becasue they were created");
Util
.reportFailure("during the default configuration phase of the underlying logging system.");
Util.reportFailure("See also " + SUBSTITUTE_LOGGER_URL);
for (int i = 0; i < loggerNameList.size(); i++) {
String loggerName = (String) loggerNameList.get(i);
Util.reportFailure(loggerName);
}
}
private final static void versionSanityCheck() {
try {
String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
boolean match = false;
for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
if (API_COMPATIBILITY_LIST[i].equals(requested)) {
match = true;
}
}
if (!match) {
Util.reportFailure("The requested version " + requested
+ " of your slf4j-binding does not match any of "
+ Arrays.toString(API_COMPATIBILITY_LIST));
Util.reportFailure("See " + VERSION_MISMATCH + " for further details.");
}
} catch (java.lang.NoSuchFieldError nsfe) {
// given our large user base anbd SLF4J's commitment to backward
// compatibility, we cannot cry
// here. Only for implementations which willingly declare a
// REQUESTED_API_VERSION field do we emit compatibility warnings.
} catch (Throwable e) {
// we should never reach here
Util.reportFailure(
"Unexpected problem occured during version sanity check", e);
}
}
/**
* Return a logger named according to the name parameter using the statically
* bound {@link ILoggerFactory} instance.
*
* @param name
* The name of the logger.
* @return logger
*/
public static Logger getLogger(String name) {
if (loggerFactory == null) {
throw new IllegalStateException(
"Logging factory implementation cannot be null. See also "
+ NULL_LF_URL);
}
return loggerFactory.getLogger(name);
}
/**
* Return a logger named corresponding to the class passed as parameter, using
* the statically bound {@link ILoggerFactory} instance.
*
* @param clazz
* the returned logger will be named after clazz
* @return logger
*/
public static Logger getLogger(Class clazz) {
if (loggerFactory == null) {
throw new IllegalStateException(
"Logging factory implementation cannot be null. See also "
+ NULL_LF_URL);
}
return loggerFactory.getLogger(clazz.getName());
}
/**
* Return the {@link ILoggerFactory} instance in use.
*
* <p>
* ILoggerFactory instance is bound with this class at compile time.
*
* @return the ILoggerFactory instance in use
*/
public static ILoggerFactory getILoggerFactory() {
return loggerFactory;
}
}