Author: chetanm
Date: Mon Dec 16 06:34:15 2013
New Revision: 1551120

URL: http://svn.apache.org/r1551120
Log:
SLING-3251 - Enable Logback ChangeLevelDispatcher by default if JUL Integration 
is enabled

Added a check if LevelChangePropagator is installed or not (through config) in 
case bridge handler is enabled. If not then one would be installed

Modified:
    
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/Activator.java
    
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
    sling/trunk/bundles/commons/log/src/test/resources/test-jul-config.xml

Modified: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/Activator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/Activator.java?rev=1551120&r1=1551119&r2=1551120&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/Activator.java
 (original)
+++ 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/Activator.java
 Mon Dec 16 06:34:15 2013
@@ -23,26 +23,22 @@ import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.status.ErrorStatus;
+import ch.qos.logback.core.util.StatusPrinter;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.slf4j.bridge.SLF4JBridgeHandler;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.core.status.ErrorStatus;
-import ch.qos.logback.core.util.StatusPrinter;
 
 public class Activator implements BundleActivator {
-    private static final String JUL_SUPPORT = 
"org.apache.sling.commons.log.julenabled";
 
     private LogbackManager logManager;
 
     private BundleContext context;
 
     private Timer timer;
-    private boolean bridgeHandlerInstalled;
     private long startTime;
     private static final AtomicInteger counter = new AtomicInteger();
     public static final long INIT_TASK_PERIOD_MSEC = 1;
@@ -64,10 +60,6 @@ public class Activator implements Bundle
     }
 
     public void stop(BundleContext context) throws Exception {
-        if(bridgeHandlerInstalled){
-            SLF4JBridgeHandler.uninstall();
-        }
-
         if(timer != null){
             timer.cancel();
             timer = null;
@@ -80,30 +72,6 @@ public class Activator implements Bundle
     }
 
     private void initializeLogbackManager(boolean immediateInit) throws 
InvalidSyntaxException {
-        // SLING-2373
-        if (Boolean.parseBoolean(context.getProperty(JUL_SUPPORT))) {
-            // In config one must enable the LevelChangePropagator
-            // 
http://logback.qos.ch/manual/configuration.html#LevelChangePropagator
-            // make sure configuration is empty unless explicitly set
-            if (System.getProperty("java.util.logging.config.file") == null
-                    && System.getProperty("java.util.logging.config.class") == 
null) {
-                final Thread ct = Thread.currentThread();
-                final ClassLoader old = ct.getContextClassLoader();
-                try {
-                    ct.setContextClassLoader(getClass().getClassLoader());
-                    System.setProperty("java.util.logging.config.class",
-                            
"org.apache.sling.commons.log.internal.Activator.DummyLogManagerConfiguration");
-                    java.util.logging.LogManager.getLogManager().reset();
-                } finally {
-                    ct.setContextClassLoader(old);
-                    System.clearProperty("java.util.logging.config.class");
-                }
-            }
-
-            SLF4JBridgeHandler.install();
-            bridgeHandlerInstalled = true;
-        }
-
         logManager = new LogbackManager(context);
         
         final Logger log = LoggerFactory.getLogger(getClass());
@@ -139,14 +107,4 @@ public class Activator implements Bundle
     private static boolean isSlf4jInitialized(){
         return LoggerFactory.getILoggerFactory() instanceof LoggerContext;
     }
-
-
-    /**
-     * The <code>DummyLogManagerConfiguration</code> class is used as JUL
-     * LogginManager configurator to preven reading platform default
-     * configuration which just duplicate log output to be redirected to SLF4J.
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static class DummyLogManagerConfiguration {
-    }
 }

Modified: 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java?rev=1551120&r1=1551119&r2=1551120&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
 (original)
+++ 
sling/trunk/bundles/commons/log/src/main/java/org/apache/sling/commons/log/logback/internal/LogbackManager.java
 Mon Dec 16 06:34:15 2013
@@ -20,6 +20,7 @@ import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.gaffer.GafferUtil;
 import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.jul.LevelChangePropagator;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.classic.spi.LoggerContextAwareBase;
 import ch.qos.logback.classic.spi.LoggerContextListener;
@@ -46,8 +47,11 @@ import org.osgi.framework.ServiceReferen
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.LoggerFactory;
+import org.slf4j.bridge.SLF4JBridgeHandler;
 
 public class LogbackManager extends LoggerContextAwareBase {
+    private static final String JUL_SUPPORT = 
"org.apache.sling.commons.log.julenabled";
+
     //These properties should have been defined in SlingLogPanel
     //But we need them while registering ServiceFactory and hence
     //would not want to load SlingLogPanel class for registration
@@ -108,6 +112,8 @@ public class LogbackManager extends Logg
 
     private final List<ServiceTracker> serviceTrackers = new 
ArrayList<ServiceTracker>();
 
+    private final boolean bridgeHandlerInstalled;
+
     /**
      * Time at which reset started. Used as the threshold for logging error
      * messages from status printer
@@ -123,17 +129,17 @@ public class LogbackManager extends Logg
         this.log = LoggerFactory.getLogger(getClass());
         this.rootDir = getRootDir(bundleContext);
         this.debug = Boolean.parseBoolean(bundleContext.getProperty(DEBUG));
+        this.bridgeHandlerInstalled = installSlf4jBridgeHandler(bundleContext);
 
         this.appenderTracker = new AppenderTracker(bundleContext, 
getLoggerContext());
         this.configSourceTracker = new ConfigSourceTracker(bundleContext, 
this);
         this.filterTracker = new FilterTracker(bundleContext,this);
         this.turboFilterTracker = new 
TurboFilterTracker(bundleContext,getLoggerContext());
 
-        // TODO Make it configurable
-        // TODO: what should it be ?
         getLoggerContext().setName(contextName);
         this.logConfigManager = new LogConfigManager(getLoggerContext(), 
bundleContext, rootDir, this);
 
+        resetListeners.add(new LevelChangePropagatorChecker());
         resetListeners.add(logConfigManager);
         resetListeners.add(appenderTracker);
         resetListeners.add(configSourceTracker);
@@ -152,10 +158,15 @@ public class LogbackManager extends Logg
         registerWebConsoleSupport();
         registerEventHandler();
         StatusPrinter.printInCaseOfErrorsOrWarnings(getLoggerContext(), 
startTime);
+
         started = true;
     }
 
     public void shutdown() {
+        if(bridgeHandlerInstalled){
+            SLF4JBridgeHandler.uninstall();
+        }
+
         logConfigManager.close();
 
         for(ServiceTracker tracker : serviceTrackers){
@@ -288,6 +299,83 @@ public class LogbackManager extends Logg
         return rootDir;
     }
 
+    //~-------------------------------------------------- Slf4j Bridge Handler 
Support
+
+    /**
+     * Installs the Slf4j BridgeHandler to route the JUL logs through Slf4j
+     *
+     * @return true only if the BridgeHandler is installed.
+     */
+    private static boolean installSlf4jBridgeHandler(BundleContext 
bundleContext){
+        // SLING-2373
+        if (Boolean.parseBoolean(bundleContext.getProperty(JUL_SUPPORT))) {
+            // In config one must enable the LevelChangePropagator
+            // 
http://logback.qos.ch/manual/configuration.html#LevelChangePropagator
+            // make sure configuration is empty unless explicitly set
+            if (System.getProperty("java.util.logging.config.file") == null
+                    && System.getProperty("java.util.logging.config.class") == 
null) {
+                final Thread ct = Thread.currentThread();
+                final ClassLoader old = ct.getContextClassLoader();
+                try {
+                    
ct.setContextClassLoader(LogbackManager.class.getClassLoader());
+                    System.setProperty("java.util.logging.config.class",
+                            DummyLogManagerConfiguration.class.getName());
+                    java.util.logging.LogManager.getLogManager().reset();
+                } finally {
+                    ct.setContextClassLoader(old);
+                    System.clearProperty("java.util.logging.config.class");
+                }
+            }
+
+            SLF4JBridgeHandler.install();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * It checks if LevelChangePropagator is installed or not. If not then
+     * it installs the propagator when Slf4j Bridge Handler is installed
+     */
+    private class LevelChangePropagatorChecker implements LogbackResetListener 
{
+
+        @Override
+        public void onResetStart(LoggerContext context) {
+
+        }
+
+        @Override
+        public void onResetComplete(LoggerContext context) {
+            List<LoggerContextListener> listenerList = 
context.getCopyOfListenerList();
+            boolean levelChangePropagatorInstalled = false;
+            for (LoggerContextListener listener : listenerList) {
+                if (listener instanceof LevelChangePropagator) {
+                    levelChangePropagatorInstalled = true;
+                    break;
+                }
+            }
+
+            
//http://logback.qos.ch/manual/configuration.html#LevelChangePropagator
+            if (!levelChangePropagatorInstalled
+                    && bridgeHandlerInstalled) {
+                LevelChangePropagator propagator = new LevelChangePropagator();
+                propagator.setContext(context);
+                propagator.start();
+                context.addListener(propagator);
+                addInfo("Slf4j bridge handler found to be enabled. Installing 
the LevelChangePropagator");
+            }
+        }
+    }
+
+    /**
+     * The <code>DummyLogManagerConfiguration</code> class is used as JUL
+     * LogginManager configurator to preven reading platform default
+     * configuration which just duplicate log output to be redirected to SLF4J.
+     */
+    @SuppressWarnings("UnusedDeclaration")
+    public static class DummyLogManagerConfiguration {
+    }
+
     private class LoggerReconfigurer implements Runnable {
 
         public void run() {
@@ -312,7 +400,7 @@ public class LogbackManager extends Logg
         }
     }
 
-    // ~-------------------------------LogggerContextListener
+    // ~-------------------------------LoggerContextListener
 
     private class OsgiIntegrationListener implements LoggerContextListener {
 
@@ -559,10 +647,6 @@ public class LogbackManager extends Logg
         Map<String,Appender<ILoggingEvent>> getAppenderMap(){
             return Collections.unmodifiableMap(appenders);
         }
-
-        LogConfig getConfig(String loggerName) {
-            return osgiConfiguredLoggers.get(loggerName);
-        }
     }
 
     private void registerWebConsoleSupport() {

Modified: sling/trunk/bundles/commons/log/src/test/resources/test-jul-config.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/log/src/test/resources/test-jul-config.xml?rev=1551120&r1=1551119&r2=1551120&view=diff
==============================================================================
--- sling/trunk/bundles/commons/log/src/test/resources/test-jul-config.xml 
(original)
+++ sling/trunk/bundles/commons/log/src/test/resources/test-jul-config.xml Mon 
Dec 16 06:34:15 2013
@@ -18,7 +18,9 @@
   -->
 
 <configuration>
-  <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
+  <newRule pattern="*/configuration/osgi"
+           actionClass="org.apache.sling.commons.log.logback.OsgiAction"/>
+  <osgi/>
 
   <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
     <encoder>


Reply via email to