You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ps...@apache.org on 2007/10/30 03:28:21 UTC

svn commit: r589940 - in /logging/sandbox/jul-to-log4j-bridge/src: main/java/org/apache/logging/julbridge/ test/java/org/apache/log4j/jul/ test/java/org/apache/logging/julbridge/

Author: psmith
Date: Mon Oct 29 19:28:20 2007
New Revision: 589940

URL: http://svn.apache.org/viewvc?rev=589940&view=rev
Log:
Fixed a bug found by Joshua ChaitinPollack where LoggingEvents were being posted to the matching
log4j Logger without obeying the configured thresholds defined for that logger.

This is inline with what the Receiver class does.

Added test case based on test harness code provided by Joshua, slightly massaged to fit
within the unit test infrastructure.

Added:
    logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULBridgeTestUtils.java
    logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/logging/julbridge/AssimilatedLevelTest.java
Modified:
    logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java
    logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jBridge.java
    logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULReceiverTest.java

Modified: logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java
URL: http://svn.apache.org/viewvc/logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java?rev=589940&r1=589939&r2=589940&view=diff
==============================================================================
--- logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java (original)
+++ logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java Mon Oct 29 19:28:20 2007
@@ -13,41 +13,45 @@
 import java.util.logging.Handler;
 import java.util.logging.LogRecord;
 
+import org.apache.log4j.Category;
 import org.apache.log4j.Logger;
 import org.apache.log4j.spi.LoggerRepository;
 import org.apache.log4j.spi.LoggingEvent;
 
-
 /**
- * An implementation of {@link Handler} that converts the {@link LogRecord}
- * into a {@link LoggingEvent} and posts it to a duplicately named
- * {@link Logger} in the log4j system.
+ * An implementation of {@link Handler} that converts the {@link LogRecord} into
+ * a {@link LoggingEvent} and posts it to a duplicately named {@link Logger} in
+ * the log4j system.
  * 
  * @author psmith
- *
+ * 
  */
-class JULBridgeHandler extends Handler{
+class JULBridgeHandler extends Handler {
 
     private final LoggerRepository repository;
     private final JULLog4jEventConverter converter;
-    
-    public JULBridgeHandler(LoggerRepository repository, JULLog4jEventConverter converter) {
+
+    public JULBridgeHandler(LoggerRepository repository,
+            JULLog4jEventConverter converter) {
         this.repository = repository;
         this.converter = converter;
     }
-    
 
     public void close() throws SecurityException {
-        
+
     }
 
     public void flush() {
-        
+
     }
 
     public void publish(LogRecord record) {
         LoggingEvent event = converter.convert(record);
-        repository.getLogger(record.getLoggerName()).callAppenders(event);
+
+        Category localLogger = repository.getLogger(record.getLoggerName());
+        if (event.getLevel().isGreaterOrEqual(localLogger.getEffectiveLevel())) {
+            localLogger.callAppenders(event);
+        }
     }
 
 }

Modified: logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jBridge.java
URL: http://svn.apache.org/viewvc/logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jBridge.java?rev=589940&r1=589939&r2=589940&view=diff
==============================================================================
--- logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jBridge.java (original)
+++ logging/sandbox/jul-to-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jBridge.java Mon Oct 29 19:28:20 2007
@@ -20,37 +20,42 @@
 
 /**
  * <p>
- * Helper class that creates bridge filters between java.util.logging.Loggers and an equivalent
- * log4j Logger.
+ * Helper class that creates bridge filters between java.util.logging.Loggers
+ * and an equivalent log4j Logger.
  * </p>
  * <p>
- * The <code>bridge</code>-style method calls use a {@link Filter} implementation that tries to
- * minimise interference with the existing <code>java.util.logging</code> configuration, but can
- * only bridge specific named loggers, and is not able to bridge child loggers automatically. Any
- * Logger that is bridged that contains an existing Filter instance is delegated to when deciding if
- * the LogRecord should continue in the java.util.logging framework, even though the bridge posts
- * the LogRecord into log4j regardless. If there was no existing Filter defined for the bridged
- * Logger, then the bridging Filter returns 'true' to mimic the default behaviour of not having a
+ * The <code>bridge</code>-style method calls use a {@link Filter}
+ * implementation that tries to minimise interference with the existing
+ * <code>java.util.logging</code> configuration, but can only bridge specific
+ * named loggers, and is not able to bridge child loggers automatically. Any
+ * Logger that is bridged that contains an existing Filter instance is delegated
+ * to when deciding if the LogRecord should continue in the java.util.logging
+ * framework, even though the bridge posts the LogRecord into log4j regardless.
+ * If there was no existing Filter defined for the bridged Logger, then the
+ * bridging Filter returns 'true' to mimic the default behaviour of not having a
  * Filter defined.
  * </p>
  * <p>
- * The <code>assimilate</code>-style methods are much more dramatic, in that they are designed to
- * completely take over the JUL-logging, and route all events into log4j. This mechanism resets the
- * java.util.logging framework configuration to it's default state, which has default {@link Level}
- * configured at INFO, and then configures the root JUL Logger with the matching Level that the
- * provided LoggerRepository has been configured. You should, therefore, assimilate the JUL logging
- * system after the log4j system has been properly configured. You should consider whether the
- * default {@link JULLevelConverter} is appropriate to your needs, you may optionally provide your
- * own conversion instance to map the 2 Level classes.
+ * The <code>assimilate</code>-style methods are much more dramatic, in that
+ * they are designed to completely take over the JUL-logging, and route all
+ * events into log4j. This mechanism resets the java.util.logging framework
+ * configuration to it's default state, which has default {@link Level}
+ * configured at INFO, and then configures the root JUL Logger with the matching
+ * Level that the provided LoggerRepository has been configured. You should,
+ * therefore, assimilate the JUL logging system after the log4j system has been
+ * properly configured. You should consider whether the default
+ * {@link JULLevelConverter} is appropriate to your needs, you may optionally
+ * provide your own conversion instance to map the 2 Level classes.
  * </p>
  * <p>
- * The assimilate approach is very useful for the general case where you wish to forget about JUL
- * logging and use the flexibility of the log4j system. There is an ever so slightly higher cost in
- * routing the event into log4j using this approach because each LogRecord received must
- * lookup a named {@link Logger}.  The <code>bridge</code>-style approach is slightly faster 
- * because the specifically requested logger name is looked-up on construction and re-used.
- * Generally though, the slight performance hit is not worth the inflexibility of having
- * to specify each and every Logger you want to bridge.
+ * The assimilate approach is very useful for the general case where you wish to
+ * forget about JUL logging and use the flexibility of the log4j system. There
+ * is an ever so slightly higher cost in routing the event into log4j using this
+ * approach because each LogRecord received must lookup a named {@link Logger}.
+ * The <code>bridge</code>-style approach is slightly faster because the
+ * specifically requested logger name is looked-up on construction and re-used.
+ * Generally though, the slight performance hit is not worth the inflexibility
+ * of having to specify each and every Logger you want to bridge.
  * </p>
  * 
  * @see JULLevelConverter
@@ -60,8 +65,8 @@
 public class JULLog4jBridge {
 
     /**
-     * Convenience method that gathers the default LoggerRepository and uses a default Level
-     * Converter implemenation.
+     * Convenience method that gathers the default LoggerRepository and uses a
+     * default Level Converter implemenation.
      * 
      * @param JULLoggerName
      */
@@ -70,43 +75,60 @@
                 JULLog4jEventConverter.DEFAULT_LEVEL_CONVERTER);
     }
 
-    public static void bridgeJULLogger(String JULLoggerName, LoggerRepository repository) {
+    public static void bridgeJULLogger(String JULLoggerName,
+            LoggerRepository repository) {
         bridgeJULLogger(JULLoggerName, repository,
                 JULLog4jEventConverter.DEFAULT_LEVEL_CONVERTER);
     }
 
     /**
-     * Creates a bridge between the named java.util.logging Logger name, and an equivalent inside
-     * the log4j LoggerRepository, using the provided level converter class. If the JUL Logger
-     * already has a configured Filter, then it is replaced by this bridge, and a WARN level event
-     * is triggered on the JULLog4jBridge own Logger
+     * Creates a bridge between the named java.util.logging Logger name, and an
+     * equivalent inside the log4j LoggerRepository, using the provided level
+     * converter class. If the JUL Logger already has a configured Filter, then
+     * it is replaced by this bridge, and a WARN level event is triggered on the
+     * JULLog4jBridge own Logger
      * 
      * @param JULLoggerName
      * @param repository
      */
-    public static void bridgeJULLogger(String JULLoggerName, LoggerRepository repository,
-            JULLevelConverter levelConverter) {
+    public static void bridgeJULLogger(String JULLoggerName,
+            LoggerRepository repository, JULLevelConverter levelConverter) {
         Logger log4jLogger = repository.getLogger(JULLoggerName);
-        java.util.logging.Logger JULLogger = java.util.logging.Logger.getLogger(JULLoggerName);
+        java.util.logging.Logger JULLogger = java.util.logging.Logger
+                .getLogger(JULLoggerName);
 
-        JULLogger.setFilter(new JULBridgeFilter(JULLogger.getFilter(), log4jLogger,
-                new JULLog4jEventConverter(repository, levelConverter)));
+        JULLogger.setFilter(new JULBridgeFilter(JULLogger.getFilter(),
+                log4jLogger, new JULLog4jEventConverter(repository,
+                        levelConverter)));
     }
 
     /**
-     * Completely take over the underlying java.logging sub-system. Any existing java.logging
-     * configuration is reset, and a top level Handler is registered that gathers all LogRecords and
-     * converts them into log4j LoggingEvents.
+     * Completely take over the underlying java.logging sub-system. Any existing
+     * java.logging configuration is reset, and a top level Handler is
+     * registered that gathers all LogRecords and converts them into log4j
+     * LoggingEvents.
      */
-    public static void assimilate(LoggerRepository repository, JULLevelConverter levelConverter) {
+    public static void assimilate(LoggerRepository repository,
+            JULLevelConverter levelConverter) {
 
         java.util.logging.LogManager.getLogManager().reset();
 
+        // clearAllFilters(java.util.logging.LogManager.getLogManager());
+
         java.util.logging.Logger.getLogger("").setLevel(
                 levelConverter.convertLog4jLevel(repository.getThreshold()));
         java.util.logging.Logger.getLogger("").addHandler(
-                new JULBridgeHandler(repository, new JULLog4jEventConverter(repository,
-                        levelConverter)));
+                new JULBridgeHandler(repository, new JULLog4jEventConverter(
+                        repository, levelConverter)));
+    }
+
+    private static void clearAllFilters(java.util.logging.LogManager logManager) {
+        Enumeration enumeration = logManager.getLoggerNames();
+        while (enumeration.hasMoreElements()) {
+            java.util.logging.Logger logger = logManager.getLogger(enumeration
+                    .nextElement().toString());
+            logger.setFilter(null);
+        }
     }
 
     public static void assimilate(LoggerRepository repository) {
@@ -118,19 +140,21 @@
     }
 
     /**
-     * Reverse of {@link #assimilate()}, disconnects the bridge
-     * from the java.util.logging subsystem by resetting that framework
-     * back to it's default configuration (removes all Handlers and Filters)
+     * Reverse of {@link #assimilate()}, disconnects the bridge from the
+     * java.util.logging subsystem by resetting that framework back to it's
+     * default configuration (removes all Handlers and Filters)
      */
     public static void repatriate() {
-        
-        java.util.logging.LogManager logManager = java.util.logging.LogManager.getLogManager();
+
+        java.util.logging.LogManager logManager = java.util.logging.LogManager
+                .getLogManager();
         Enumeration loggerNames = logManager.getLoggerNames();
-        while(loggerNames.hasMoreElements()) {
-            logManager.getLogger(loggerNames.nextElement().toString()).setFilter(null);
+        while (loggerNames.hasMoreElements()) {
+            logManager.getLogger(loggerNames.nextElement().toString())
+                    .setFilter(null);
         }
         logManager.reset();
-        
+
     }
 
 }

Added: logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULBridgeTestUtils.java
URL: http://svn.apache.org/viewvc/logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULBridgeTestUtils.java?rev=589940&view=auto
==============================================================================
--- logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULBridgeTestUtils.java (added)
+++ logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULBridgeTestUtils.java Mon Oct 29 19:28:20 2007
@@ -0,0 +1,21 @@
+package org.apache.log4j.jul;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.spi.LoggingEvent;
+
+public class JULBridgeTestUtils {
+
+    public static String convertToString(List observedLoggingEvents) {
+        StringBuffer buf = new StringBuffer();
+        for (Iterator iterator = observedLoggingEvents.iterator(); iterator
+                .hasNext();) {
+            LoggingEvent event = (LoggingEvent) iterator.next();
+            buf.append("message:'").append(event.getMessage()).append("', ");
+            buf.append("timeStamp: ").append(event.getTimeStamp());
+            buf.append("logger:").append(event.getLevel());
+        }
+        return buf.toString();
+    }
+}

Modified: logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULReceiverTest.java
URL: http://svn.apache.org/viewvc/logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULReceiverTest.java?rev=589940&r1=589939&r2=589940&view=diff
==============================================================================
--- logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULReceiverTest.java (original)
+++ logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/log4j/jul/JULReceiverTest.java Mon Oct 29 19:28:20 2007
@@ -1,24 +1,22 @@
 /*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.log4j.jul;
 
 import java.net.URL;
-import java.util.Iterator;
-import java.util.List;
 
 import junit.framework.TestCase;
 
@@ -27,7 +25,6 @@
 import org.apache.log4j.LoggerRepositoryExImpl;
 import org.apache.log4j.plugins.PluginConfigurator;
 import org.apache.log4j.spi.LoggerRepository;
-import org.apache.log4j.spi.LoggingEvent;
 import org.apache.log4j.spi.RepositorySelector;
 import org.apache.logging.julbridge.JULLog4jBridge;
 import org.apache.logging.julbridge.MockAppender;
@@ -35,8 +32,8 @@
 public class JULReceiverTest extends TestCase {
 
     private final Object repositorySelectorGuard = new Object();
-    final LoggerRepository repositoryExImpl = new LoggerRepositoryExImpl(LogManager
-            .getLoggerRepository());
+    final LoggerRepository repositoryExImpl = new LoggerRepositoryExImpl(
+            LogManager.getLoggerRepository());
     private MockAppender mockAppender;
 
     protected void setUp() throws Exception {
@@ -59,25 +56,17 @@
 
     public void testJULReceiverPluginConfiguration() {
         URL resource = this.getClass().getResource("JULReceiverPluginTest.xml");
-         PluginConfigurator.configure(resource);
+        PluginConfigurator.configure(resource);
 
         Logger.getRootLogger().addAppender(mockAppender);
-        java.util.logging.Logger juliLogger = java.util.logging.Logger.getLogger("foo");
+        java.util.logging.Logger juliLogger = java.util.logging.Logger
+                .getLogger("foo");
         juliLogger.info("boo");
-        assertEquals("Should have received 1 event: " + convertToString(mockAppender.observedLoggingEvents), 1, mockAppender.observedLoggingEvents.size());
+        assertEquals("Should have received 1 event: " +
+                JULBridgeTestUtils
+                        .convertToString(mockAppender.observedLoggingEvents),
+                1, mockAppender.observedLoggingEvents.size());
 
-    }
-
-    private String convertToString(List observedLoggingEvents) {
-        StringBuffer buf = new StringBuffer();
-        for (Iterator iterator = observedLoggingEvents.iterator(); iterator
-                .hasNext();) {
-            LoggingEvent event = (LoggingEvent) iterator.next();
-            buf.append("message:'").append(event.getMessage()).append("', ");
-            buf.append("timeStamp: ").append(event.getTimeStamp());
-            buf.append("logger:").append(event.getLevel());
-        }
-        return buf.toString();
     }
 
 }

Added: logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/logging/julbridge/AssimilatedLevelTest.java
URL: http://svn.apache.org/viewvc/logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/logging/julbridge/AssimilatedLevelTest.java?rev=589940&view=auto
==============================================================================
--- logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/logging/julbridge/AssimilatedLevelTest.java (added)
+++ logging/sandbox/jul-to-log4j-bridge/src/test/java/org/apache/logging/julbridge/AssimilatedLevelTest.java Mon Oct 29 19:28:20 2007
@@ -0,0 +1,58 @@
+package org.apache.logging.julbridge;
+
+import java.util.logging.Logger;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.jul.JULBridgeTestUtils;
+
+/**
+ * Ensures that logging events arriving into log4j obey the configured levels
+ * for that logger.
+ * 
+ * For example, Finer and Finest level in JUL should not be sent to appenders if
+ * the matching log4j Logger is set to WARN level.
+ * 
+ * @author Joshua ChaitinPollack, modified to fit unit test structure by Paul
+ *         Smith
+ * 
+ */
+public class AssimilatedLevelTest extends TestCase {
+
+    private MockAppender mockAppender;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        LogManager.resetConfiguration();
+        JULLog4jBridge.assimilate();
+        mockAppender = new MockAppender();
+        org.apache.log4j.Logger.getRootLogger().addAppender(mockAppender);
+
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        JULLog4jBridge.repatriate();
+        mockAppender.close();
+        mockAppender = null;
+    }
+
+    public void testExpectedLevels() {
+
+        org.apache.log4j.Logger.getRootLogger().setLevel(Level.WARN);
+        Logger logger = Logger.getLogger("test.logger");
+
+        logger.finest("Finest");
+        logger.finer("Finer");
+        logger.fine("Fine");
+        logger.warning("Warning");
+        logger.severe("Severe");
+        assertEquals("Mismatch on expected # events: " +
+                JULBridgeTestUtils
+                        .convertToString(mockAppender.observedLoggingEvents),
+                2, mockAppender.observedLoggingEvents.size());
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org