[logback-dev] svn commit: r1420 - in logback/trunk/logback-classic/src: main/java/ch/qos/logback/classic test/java/ch/qos/logback/classic

noreply.seb at qos.ch noreply.seb at qos.ch
Mon Mar 12 15:46:55 CET 2007


Author: seb
Date: Mon Mar 12 15:46:54 2007
New Revision: 1420

Added:
   logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java
Modified:
   logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
   logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java

Log:
Refactored Logger and LoggerContext classes.
We now construct the Object array to place the arguments of the parametrized logging only when the TurboFilters have been called.
This makes the cost of not logging less expensive of about 20 nanos per request.
The isDebugEnabled methods (and related isXXXEnabled() ) now call the TurboFilters before returning their result.

Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java	(original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java	Mon Mar 12 15:46:54 2007
@@ -249,11 +249,6 @@
     return aai.getAppender(name);
   }
 
-  // public boolean isAttached(Appender appender) {
-  // // TODO Auto-generated method stub
-  // return false;
-  // }
-
   /**
    * Invoke all the appenders of this logger.
    * 
@@ -375,18 +370,15 @@
   }
 
   public void debug(String msg) {
-    // if(!(effectiveLevelInt <= Level.DEBUG_INT)) {
-    // return;
-    // }
     filterAndLog(null, Level.DEBUG, msg, null, null);
   }
 
   public void debug(String format, Object arg) {
-    filterAndLog(null, Level.DEBUG, format, new Object[] { arg }, null);
+    filterAndLog(null, Level.DEBUG, format, arg, null);
   }
 
   public void debug(String format, Object arg1, Object arg2) {
-    filterAndLog(null, Level.DEBUG, format, new Object[] { arg1, arg2 }, null);
+    filterAndLog(null, Level.DEBUG, format, arg1, arg2, null);
   }
 
   public void debug(String format, Object[] argArray) {
@@ -403,6 +395,49 @@
     filterAndLog(marker, Level.DEBUG, msg, null, null);
   }
 
+  /**
+   * The next methods are not merged into one because of the time we gain by not
+   * creating a new Object[] with the params. This reduces the cost of not
+   * logging of about 20 nanos.
+   */
+
+  public final void filterAndLog(final String localFQCN, final Marker marker,
+      final Level level, final String msg, final Object param, final Throwable t) {
+
+    final FilterReply decision = loggerContext.getTurboFilterChainDecision(
+        marker, this, Level.DEBUG, msg, param, t);
+
+    if (decision == FilterReply.NEUTRAL) {
+      if (effectiveLevelInt > level.levelInt) {
+        return;
+      }
+    } else if (decision == FilterReply.DENY) {
+      return;
+    }
+
+    buildLoggingEventAndAppend(localFQCN, marker, level, msg,
+        new Object[] { param }, t);
+  }
+
+  public final void filterAndLog(final String localFQCN, final Marker marker,
+      final Level level, final String msg, final Object param1,
+      final Object param2, final Throwable t) {
+
+    final FilterReply decision = loggerContext.getTurboFilterChainDecision(
+        marker, this, Level.DEBUG, msg, param1, param2, t);
+
+    if (decision == FilterReply.NEUTRAL) {
+      if (effectiveLevelInt > level.levelInt) {
+        return;
+      }
+    } else if (decision == FilterReply.DENY) {
+      return;
+    }
+
+    buildLoggingEventAndAppend(localFQCN, marker, level, msg, new Object[] {
+        param1, param2 }, t);
+  }
+
   public final void filterAndLog(final String localFQCN, final Marker marker,
       final Level level, final String msg, final Object[] params,
       final Throwable t) {
@@ -418,10 +453,26 @@
       return;
     }
 
+    buildLoggingEventAndAppend(localFQCN, marker, level, msg, params, t);
+  }
+
+  private void buildLoggingEventAndAppend(final String localFQCN,
+      final Marker marker, final Level level, final String msg,
+      final Object[] params, final Throwable t) {
     LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params);
     le.setMarker(marker);
     callAppenders(le);
+  }
 
+  final void filterAndLog(final Marker marker, final Level level,
+      final String msg, final Object param1, final Throwable t) {
+    filterAndLog(FQCN, marker, level, msg, param1, t);
+  }
+
+  final void filterAndLog(final Marker marker, final Level level,
+      final String msg, final Object param1, final Object param2,
+      final Throwable t) {
+    filterAndLog(FQCN, marker, level, msg, param1, param2, t);
   }
 
   final void filterAndLog(final Marker marker, final Level level,
@@ -526,6 +577,12 @@
   }
 
   public final boolean isDebugEnabled() {
+    FilterReply decision = callTurboFilters(Level.DEBUG);
+    if  (decision.equals(FilterReply.ACCEPT)) {
+      return true;
+    } else if (decision.equals(FilterReply.DENY)) {
+      return false;
+    }
     return (effectiveLevelInt <= Level.DEBUG_INT);
   }
 
@@ -534,6 +591,12 @@
   }
 
   public final boolean isErrorEnabled() {
+    FilterReply decision = callTurboFilters(Level.ERROR);
+    if  (decision.equals(FilterReply.ACCEPT)) {
+      return true;
+    } else if (decision.equals(FilterReply.DENY)) {
+      return false;
+    }
     return (effectiveLevelInt <= Level.ERROR_INT);
   }
 
@@ -542,6 +605,12 @@
   }
 
   public boolean isInfoEnabled() {
+    FilterReply decision = callTurboFilters(Level.INFO);
+    if  (decision.equals(FilterReply.ACCEPT)) {
+      return true;
+    } else if (decision.equals(FilterReply.DENY)) {
+      return false;
+    }
     return (effectiveLevelInt <= Level.INFO_INT);
   }
 
@@ -550,6 +619,12 @@
   }
 
   public boolean isWarnEnabled() {
+    FilterReply decision = callTurboFilters(Level.WARN);
+    if  (decision.equals(FilterReply.ACCEPT)) {
+      return true;
+    } else if (decision.equals(FilterReply.DENY)) {
+      return false;
+    }
     return (effectiveLevelInt <= Level.WARN_INT);
   }
 
@@ -558,6 +633,10 @@
   }
 
   public boolean isEnabledFor(Level level) {
+    FilterReply decision = callTurboFilters(level);
+    if  (decision.equals(FilterReply.ACCEPT)) {
+      return true;
+    }
     return (effectiveLevelInt <= level.levelInt);
   }
 
@@ -612,11 +691,28 @@
   public String toString() {
     return "Logger[" + name + "]";
   }
+  
+  /**
+   * Method that calls the attached TurboFilter
+   * objects based on the logger and the level.
+   * 
+   * It is used by isYYYEnabled() methods.
+   * 
+   * It returns the typical FilterReply values:
+   * ACCEPT, NEUTRAL or DENY.
+   * 
+   * @param level
+   * @return the reply given by the TurboFilters
+   */
+  private FilterReply callTurboFilters(Level level) {
+    return loggerContext.getTurboFilterChainDecision(
+        null, this, level, null, null, null);
+  }
 
   /**
    * Return the context for this logger.
    * 
-   * @return
+   * @return the context
    */
   public LoggerContext getLoggerContext() {
     return loggerContext;

Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java	(original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/LoggerContext.java	Mon Mar 12 15:46:54 2007
@@ -215,6 +215,26 @@
     return cfai.getTurboFilterChainDecision(marker, logger, level, format,
         params, t);
   }
+  
+  final public FilterReply getTurboFilterChainDecision(final Marker marker,
+      final Logger logger, final Level level, final String format,
+      final Object param, final Throwable t) {
+    if (cfai == null) {
+      return FilterReply.NEUTRAL;
+    }
+    return cfai.getTurboFilterChainDecision(marker, logger, level, format,
+        new Object[]{param}, t);
+  }
+  
+  final public FilterReply getTurboFilterChainDecision(final Marker marker,
+      final Logger logger, final Level level, final String format,
+      final Object param1, final Object param2, final Throwable t) {
+    if (cfai == null) {
+      return FilterReply.NEUTRAL;
+    }
+    return cfai.getTurboFilterChainDecision(marker, logger, level, format,
+        new Object[]{param1, param2}, t);
+  }
 
   public TurboFilter getFirstTurboFilter() {
     if (cfai == null) {

Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerTest.java	Mon Mar 12 15:46:54 2007
@@ -0,0 +1,110 @@
+package ch.qos.logback.classic;
+
+import org.slf4j.Marker;
+
+import ch.qos.logback.classic.turbo.TurboFilter;
+import ch.qos.logback.core.spi.FilterReply;
+import junit.framework.TestCase;
+
+public class LoggerTest extends TestCase {
+
+  LoggerContext context;
+  Logger logger;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    context = new LoggerContext();
+    context.setName("test");
+    context.start();
+    logger = context.getLogger(LoggerTest.class);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    super.tearDown();
+  }
+
+  private void addYesFilter() {
+    YesFilter filter = new YesFilter();
+    filter.start();
+    context.addTurboFilter(filter);
+  }
+  
+  private void addNoFilter() {
+    NoFilter filter = new NoFilter();
+    filter.start();
+    context.addTurboFilter(filter);
+  }
+
+  public void testIsDebugEnabledWithYesFilter() {
+    addYesFilter();
+    logger.setLevel(Level.INFO);
+    assertTrue(logger.isDebugEnabled());
+  }
+
+  public void testIsInfoEnabledWithYesFilter() {
+    addYesFilter();
+    logger.setLevel(Level.WARN);
+    assertTrue(logger.isInfoEnabled());
+  }
+
+  public void testIsWarnEnabledWithYesFilter() {
+    addYesFilter();
+    logger.setLevel(Level.ERROR);
+    assertTrue(logger.isWarnEnabled());
+  }
+
+  public void testIsErrorEnabledWithYesFilter() {
+    addYesFilter();
+    logger.setLevel(Level.OFF);
+    assertTrue(logger.isErrorEnabled());
+  }
+
+  public void testIsEnabledForWithYesFilter() {
+    addYesFilter();
+    logger.setLevel(Level.ERROR);
+    assertTrue(logger.isEnabledFor(Level.INFO));
+  }
+  
+  public void testIsDebugEnabledWithNoFilter() {
+    addNoFilter();
+    logger.setLevel(Level.DEBUG);
+    assertFalse(logger.isDebugEnabled());
+  }
+  
+  public void testIsInfoEnabledWithNoFilter() {
+    addNoFilter();
+    logger.setLevel(Level.DEBUG);
+    assertFalse(logger.isInfoEnabled());
+  }
+  
+  public void testIsWarnEnabledWithNoFilter() {
+    addNoFilter();
+    logger.setLevel(Level.DEBUG);
+    assertFalse(logger.isWarnEnabled());
+  }
+  
+  public void testIsErrorEnabledWithNoFilter() {
+    addNoFilter();
+    logger.setLevel(Level.DEBUG);
+    assertFalse(logger.isErrorEnabled());
+  }
+
+}
+
+class YesFilter extends TurboFilter {
+  @Override
+  public FilterReply decide(Marker marker, Logger logger, Level level,
+      String format, Object[] params, Throwable t) {
+    return FilterReply.ACCEPT;
+  }
+}
+
+class NoFilter extends TurboFilter {
+  @Override
+  public FilterReply decide(Marker marker, Logger logger, Level level,
+      String format, Object[] params, Throwable t) {
+    return FilterReply.DENY;
+  }
+}
\ No newline at end of file



More information about the logback-dev mailing list