[logback-dev] svn commit: r1284 - in logback/trunk: logback-classic logback-classic/src/main/java/ch/qos/logback/classic logback-classic/src/main/java/ch/qos/logback/classic/selector logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet logback-classic/src/main/java/ch/qos/logback/classic/util logback-classic/src/main/java/org/slf4j logback-core/src/main/java/ch/qos/logback/core/util
noreply.seb at qos.ch
noreply.seb at qos.ch
Thu Jan 25 19:25:31 CET 2007
Author: seb
Date: Thu Jan 25 19:25:31 2007
New Revision: 1284
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java
Modified:
logback/trunk/logback-classic/pom.xml
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/ClassicGlobal.java
logback/trunk/logback-classic/src/main/java/org/slf4j/LoggerFactory.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java
Log:
first commit of a ContextJNDISelector
Modified: logback/trunk/logback-classic/pom.xml
==============================================================================
--- logback/trunk/logback-classic/pom.xml (original)
+++ logback/trunk/logback-classic/pom.xml Thu Jan 25 19:25:31 2007
@@ -85,6 +85,13 @@
<optional>true</optional>
</dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+
</dependencies>
<build>
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/ClassicGlobal.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/ClassicGlobal.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/ClassicGlobal.java Thu Jan 25 19:25:31 2007
@@ -14,4 +14,8 @@
static public final String CAUSED_BY = "Caused by: ";
static public final char DOT = '.';
static public final String USER_MDC_KEY = "user";
+
+ public static final String LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector";
+ public static String JNDI_CONFIGURATION_RESOURCE = "java:comp/env/logback/configuration-resource";
+ public static String JNDI_CONTEXT_NAME = "java:comp/env/logback/context-name";
}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextJNDISelector.java Thu Jan 25 19:25:31 2007
@@ -0,0 +1,112 @@
+package ch.qos.logback.classic.selector;
+
+import static ch.qos.logback.classic.ClassicGlobal.JNDI_CONFIGURATION_RESOURCE;
+import static ch.qos.logback.classic.ClassicGlobal.JNDI_CONTEXT_NAME;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.util.ContextInitializer;
+import ch.qos.logback.classic.util.JNDIUtil;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.util.Loader;
+import ch.qos.logback.core.util.StatusPrinter;
+
+/**
+ * A class that allows the LoggerFactory to access an environment-based
+ * LoggerContext.
+ *
+ * To add in catalina.sh
+ *
+ * JAVA_OPTS="$JAVA_OPTS "-Dlogback.ContextSelector=JNDI""
+ *
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ */
+public class ContextJNDISelector implements ContextSelector {
+
+ private final Map<String, LoggerContext> contextMap;
+ private final LoggerContext defaultContext;
+
+ public ContextJNDISelector(LoggerContext context) {
+ contextMap = Collections
+ .synchronizedMap(new HashMap<String, LoggerContext>());
+ defaultContext = context;
+ }
+
+ public LoggerContext getLoggerContext() {
+ String contextName = null;
+ Context ctx = null;
+
+ try {
+ // We first try to find the name of our
+ // environment's LoggerContext
+ ctx = JNDIUtil.getInitialContext();
+ contextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
+ } catch (NamingException ne) {
+ // We can't log here
+ }
+
+ if (contextName == null) {
+ // We return the default context
+ return defaultContext;
+ } else {
+ // Let's see if we already know such a context
+ LoggerContext loggerContext = contextMap.get(contextName);
+
+ if (loggerContext == null) {
+ // We have to create a new LoggerContext
+ loggerContext = new LoggerContext();
+ loggerContext.setName(contextName);
+ contextMap.put(contextName, loggerContext);
+
+ // Do we have a dedicated configuration file?
+ String configFilePath = JNDIUtil.lookup(ctx,
+ JNDI_CONFIGURATION_RESOURCE);
+ if (configFilePath != null) {
+ configureLoggerContextByResource(loggerContext, configFilePath);
+ } else {
+ ContextInitializer.autoConfig(loggerContext);
+ }
+ }
+ return loggerContext;
+ }
+ }
+
+ public LoggerContext getDefaultLoggerContext() {
+ return defaultContext;
+ }
+
+ public LoggerContext detachLoggerContext(String loggerContextName) {
+ return contextMap.remove(loggerContextName);
+ }
+
+ private void configureLoggerContextByResource(LoggerContext context,
+ String configFilePath) {
+ URL url = Loader.getResourceByTCL(configFilePath);
+ if (url != null) {
+ try {
+ JoranConfigurator configurator = new JoranConfigurator();
+ context.shutdownAndReset();
+ configurator.setContext(context);
+ configurator.doConfigure(url);
+ } catch (JoranException e) {
+ StatusPrinter.print(context);
+ }
+ } else {
+ Logger logger = defaultContext.getLogger(LoggerContext.ROOT_NAME);
+ logger.warn("The provided URL for context" + context.getName()
+ + " does not lead to a valid file");
+ }
+ }
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/ContextSelector.java Thu Jan 25 19:25:31 2007
@@ -0,0 +1,22 @@
+package ch.qos.logback.classic.selector;
+
+import ch.qos.logback.classic.LoggerContext;
+
+/**
+ * An interface that provides access to different contexts.
+ *
+ * It is used by the LoggerFactory to access the context
+ * it will use to retrieve loggers.
+ *
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ */
+public interface ContextSelector {
+
+ public LoggerContext getLoggerContext();
+
+ public LoggerContext getDefaultLoggerContext();
+
+ public LoggerContext detachLoggerContext(String loggerContextName);
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/DefaultContextSelector.java Thu Jan 25 19:25:31 2007
@@ -0,0 +1,24 @@
+package ch.qos.logback.classic.selector;
+
+import ch.qos.logback.classic.LoggerContext;
+
+public class DefaultContextSelector implements ContextSelector {
+
+ private LoggerContext context;
+
+ public DefaultContextSelector(LoggerContext context) {
+ this.context = context;
+ }
+
+ public LoggerContext getLoggerContext() {
+ return getDefaultLoggerContext();
+ }
+
+ public LoggerContext getDefaultLoggerContext() {
+ return context;
+ }
+
+ public LoggerContext detachLoggerContext(String loggerContextName) {
+ return context;
+ }
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/selector/servlet/ContextDetachingSCL.java Thu Jan 25 19:25:31 2007
@@ -0,0 +1,47 @@
+package ch.qos.logback.classic.selector.servlet;
+
+import static ch.qos.logback.classic.ClassicGlobal.JNDI_CONTEXT_NAME;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.selector.ContextSelector;
+import ch.qos.logback.classic.util.JNDIUtil;
+
+public class ContextDetachingSCL implements ServletContextListener {
+
+ public void contextDestroyed(ServletContextEvent arg0) {
+ String loggerContextName = null;
+
+ try {
+ Context ctx = JNDIUtil.getInitialContext();
+ loggerContextName = (String) JNDIUtil.lookup(ctx, JNDI_CONTEXT_NAME);
+ } catch (NamingException ne) {
+ }
+
+ if (loggerContextName != null) {
+ System.out.println("About to detach context named " + loggerContextName);
+
+ ContextSelector selector = LoggerFactory.getContextSelector();
+ LoggerContext context = selector.detachLoggerContext(loggerContextName);
+ if (context != null) {
+ Logger logger = context.getLogger(LoggerContext.ROOT_NAME);
+ logger.warn("Shutting down context " + loggerContextName);
+ context.shutdownAndReset();
+ } else {
+ System.out.println("No context named " + loggerContextName + " was found.");
+ }
+ }
+ }
+
+ public void contextInitialized(ServletContextEvent arg0) {
+ // do nothing
+ }
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/util/JNDIUtil.java Thu Jan 25 19:25:31 2007
@@ -0,0 +1,30 @@
+package ch.qos.logback.classic.util;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+/**
+ * A simple utility class to create and use a JNDI Context.
+ *
+ * @author Ceki Gülcü
+ * @author Sébastien Pennec
+ */
+
+public class JNDIUtil {
+
+ public static Context getInitialContext() throws NamingException {
+ return new InitialContext();
+ }
+
+ public static String lookup(Context ctx, String name) {
+ if (ctx == null) {
+ return null;
+ }
+ try {
+ return (String) ctx.lookup(name);
+ } catch (NamingException e) {
+ return null;
+ }
+ }
+}
\ No newline at end of file
Modified: logback/trunk/logback-classic/src/main/java/org/slf4j/LoggerFactory.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/org/slf4j/LoggerFactory.java (original)
+++ logback/trunk/logback-classic/src/main/java/org/slf4j/LoggerFactory.java Thu Jan 25 19:25:31 2007
@@ -34,8 +34,13 @@
import org.slf4j.impl.Util;
+import ch.qos.logback.classic.ClassicGlobal;
import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.selector.ContextJNDISelector;
+import ch.qos.logback.classic.selector.ContextSelector;
+import ch.qos.logback.classic.selector.DefaultContextSelector;
import ch.qos.logback.classic.util.ContextInitializer;
+import ch.qos.logback.core.util.OptionHelper;
/**
* The <code>LoggerFactory</code> is a utility class producing Loggers for
@@ -55,7 +60,9 @@
*/
public final class LoggerFactory {
- static LoggerContext loggerContext;
+ static LoggerContext defaultLoggerContext;
+
+ private static ContextSelector contextSelector;
// private constructor prevents instantiation
private LoggerFactory() {
@@ -63,9 +70,19 @@
static {
try {
- loggerContext = new LoggerContext();
- loggerContext.setName("default");
- ContextInitializer.autoConfig(loggerContext);
+ //let's configure a default context
+ defaultLoggerContext = new LoggerContext();
+ defaultLoggerContext.setName("default");
+ ContextInitializer.autoConfig(defaultLoggerContext);
+
+ //See if a special context selector is needed
+ String contextSelectorStr = OptionHelper.getSystemProperty(ClassicGlobal.LOGBACK_CONTEXT_SELECTOR, null);
+ if (contextSelectorStr == null) {
+ contextSelector = new DefaultContextSelector(defaultLoggerContext);
+ } else if (contextSelectorStr.equals("JNDI")) {
+ //if jndi is specified, let's use the appropriate class
+ contextSelector = new ContextJNDISelector(defaultLoggerContext);
+ }
} catch (Exception e) {
// we should never get here
Util.reportFailure("Failed to instantiate logger [" + LoggerContext.class
@@ -82,7 +99,7 @@
* @return logger
*/
public static Logger getLogger(String name) {
- return loggerContext.getLogger(name);
+ return contextSelector.getLoggerContext().getLogger(name);
}
/**
@@ -94,7 +111,7 @@
* @return logger
*/
public static Logger getLogger(Class clazz) {
- return loggerContext.getLogger(clazz.getName());
+ return contextSelector.getLoggerContext().getLogger(clazz.getName());
}
/**
@@ -106,6 +123,15 @@
* @return the ILoggerFactory instance in use
*/
public static ILoggerFactory getILoggerFactory() {
- return loggerContext;
+ return contextSelector.getLoggerContext();
+ }
+
+ /**
+ * Return the {@link ContextSelector} instance in use.
+ *
+ * @return the ContextSelector instance in use
+ */
+ public static ContextSelector getContextSelector() {
+ return contextSelector;
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java Thu Jan 25 19:25:31 2007
@@ -64,9 +64,12 @@
} catch (Throwable t) {
return null;
}
-
}
+ public static URL getResourceByTCL(String resource) {
+ return getResource(resource, getTCL());
+ }
+
/**
* Get the Thread Context Loader which is a JDK 1.2 feature. If we are running
* under JDK 1.1 or anything else goes wrong the method returns
More information about the logback-dev
mailing list