
Author: ceki Date: Mon Oct 30 23:16:56 2006 New Revision: 821 Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/filter/ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/filter/ClassicFilter.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassicFilterAttachable.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassicFilterAttachableImpl.java logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.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 logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/BasicLoggerTest.java Log: - Loggers now go through filter attached to their parent (loggerContext) before any decision. This slows down decision making a little, but is much more flexible. 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 Oct 30 23:16:56 2006 @@ -374,222 +374,148 @@ return childLogger; } - /** - * The next three methods could be merged. However, we decided not to merge - * them to make the calls to these methods more easily understandable, - * avoiding many instances of passing null parameters. - */ - private void filterAndLog(String caller, Level level, String format, - Throwable t) { - LoggingEvent le = new LoggingEvent(caller, this, level, format, t, null); - if (loggerContext.getFilterChainDecision(le) != Filter.DENY) { - callAppenders(le); - } - } - - private void filterAndLog(String caller, Level level, String format, - Object[] argArray, Throwable t) { - LoggingEvent le = new LoggingEvent(caller, this, level, format, t, argArray); - if (loggerContext.getFilterChainDecision(le) != Filter.DENY) { - callAppenders(le); - } - } - - private void filterAndLog(String caller, Level level, Marker marker, - String format, Object[] argArray, Throwable t) { - LoggingEvent le = new LoggingEvent(caller, this, level, format, t, argArray); - le.setMarker(marker); - if (loggerContext.getFilterChainDecision(le) != Filter.DENY) { - callAppenders(le); - } - } public void debug(String msg) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, msg, null); - } +// if(!(effectiveLevelInt <= Level.DEBUG_INT)) { +// return; +// } + filterAndLog(null, Level.DEBUG, msg, null, null); } public void debug(String format, Object arg) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, format, new Object[] { arg }, null); - } + filterAndLog(null, Level.DEBUG, format, new Object[] { arg }, null); } public void debug(String format, Object arg1, Object arg2) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, format, new Object[] { arg1, arg2 }, null); - } + filterAndLog(null, Level.DEBUG, format, new Object[] { arg1, arg2 }, null); } public void debug(String format, Object[] argArray) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, format, new Object[] { argArray }, null); - } + filterAndLog(null, Level.DEBUG, format, argArray, null); } public void debug(String msg, Throwable t) { if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, msg, t); + filterAndLog(null, Level.DEBUG, msg, null, t); } } public final void debug(Marker marker, String msg) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, marker, msg, null, null); + filterAndLog(marker, Level.DEBUG, msg, null, null); + } + + final void filterAndLog(final Marker marker, final Level level, final String msg, final Object[] params, + final Throwable t) { + + final int decision = loggerContext.getFilterChainDecision(marker, this, Level.DEBUG, msg, params, t); + + if(decision == Filter.NEUTRAL) { + if(effectiveLevelInt > level.levelInt) { + return; + } + } else if (decision == Filter.DENY) { + return; } + + LoggingEvent le = new LoggingEvent(FQCN, this, level, msg, t, params); + le.setMarker(marker); + callAppenders(le); } public void debug(Marker marker, String format, Object arg) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, marker, format, new Object[] { arg }, - null); - } + filterAndLog(marker, Level.DEBUG, format, new Object[] { arg }, null); } public void debug(Marker marker, String format, Object arg1, Object arg2) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, marker, format, - new Object[] { arg1, arg2 }, null); - } + filterAndLog(marker, Level.DEBUG, format, new Object[] { arg1, arg2 }, null); } public void debug(Marker marker, String format, Object[] argArray) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, marker, format, - new Object[] { argArray }, null); - } + filterAndLog(marker, Level.DEBUG, format, argArray, null); } public void debug(Marker marker, String msg, Throwable t) { - if (isDebugEnabled()) { - filterAndLog(FQCN, Level.DEBUG, marker, msg, null, t); - } + filterAndLog(marker, Level.DEBUG, msg, null, t); } public void error(String msg) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, msg, null); - } + filterAndLog(null, Level.ERROR, msg, null, null); } public void error(String format, Object arg) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, format, new Object[] { arg }, null); - } + filterAndLog(null, Level.ERROR, format, new Object[] { arg }, null); } public void error(String format, Object arg1, Object arg2) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, format, new Object[] { arg1, arg2 }, null); - } + filterAndLog(null, Level.ERROR, format, new Object[] { arg1, arg2 }, null); } public void error(String format, Object[] argArray) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, format, new Object[] { argArray }, null); - } + filterAndLog(null, Level.ERROR, format, argArray, null); } public void error(String msg, Throwable t) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, msg, t); - } + filterAndLog(null, Level.ERROR, msg, null, t); } public void error(Marker marker, String msg) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, marker, msg, null, null); - } + filterAndLog(marker, Level.ERROR, msg, null, null); } public void error(Marker marker, String format, Object arg) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, marker, format, new Object[] { arg }, - null); - } + filterAndLog(marker, Level.ERROR, format, new Object[] { arg }, null); } public void error(Marker marker, String format, Object arg1, Object arg2) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, marker, format, - new Object[] { arg1, arg2 }, null); - } + filterAndLog(marker, Level.ERROR, format, new Object[] { arg1, arg2 }, null); } public void error(Marker marker, String format, Object[] argArray) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, marker, format, - new Object[] { argArray }, null); - } + filterAndLog(marker, Level.ERROR, format, argArray, null); } public void error(Marker marker, String msg, Throwable t) { - if (isErrorEnabled()) { - filterAndLog(FQCN, Level.ERROR, marker, msg, null, t); - } + filterAndLog(marker, Level.ERROR, msg, null, t); } public void info(String msg) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, msg, null); - } + filterAndLog(null, Level.INFO, msg, null, null); } public void info(String format, Object arg) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, format, new Object[] { arg }, null); - } + filterAndLog(null, Level.INFO, format, new Object[] { arg }, null); } public void info(String format, Object arg1, Object arg2) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, format, new Object[] { arg1, arg2 }, null); - } + filterAndLog(null, Level.INFO, format, new Object[] { arg1, arg2 }, null); } public void info(String format, Object[] argArray) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, format, new Object[] { argArray }, null); - } + filterAndLog(null, Level.INFO, format, argArray, null); } public void info(String msg, Throwable t) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, msg, t); - } + filterAndLog(null, Level.INFO, msg, null, t); } public void info(Marker marker, String msg) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, marker, msg, null, null); - } + filterAndLog(marker, Level.INFO, msg, null, null); } public void info(Marker marker, String format, Object arg) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, marker, format, new Object[] { arg }, null); - } + filterAndLog(marker, Level.INFO, format, new Object[] { arg }, null); } public void info(Marker marker, String format, Object arg1, Object arg2) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, marker, format, - new Object[] { arg1, arg2 }, null); - } + filterAndLog(marker, Level.INFO, format, new Object[] { arg1, arg2 }, null); } public void info(Marker marker, String format, Object[] argArray) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, marker, format, new Object[] { argArray }, - null); - } + filterAndLog(marker, Level.INFO, format, argArray, null); } public void info(Marker marker, String msg, Throwable t) { - if (isInfoEnabled()) { - filterAndLog(FQCN, Level.INFO, marker, msg, null, t); - } + filterAndLog(marker, Level.INFO, msg, null, t); } public final boolean isDebugEnabled() { @@ -629,65 +555,43 @@ } public void warn(String msg) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, msg, null); - } + filterAndLog(null, Level.WARN, msg, null, null); } public void warn(String msg, Throwable t) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, msg, t); - } + filterAndLog(null, Level.WARN, msg, null, t); } public void warn(String format, Object arg) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, format, new Object[] { arg }, null); - } + filterAndLog(null, Level.WARN, format, new Object[] { arg }, null); } public void warn(String format, Object arg1, Object arg2) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, format, new Object[] { arg1, arg2 }, null); - } + filterAndLog(null, Level.WARN, format, new Object[] { arg1, arg2 }, null); } public void warn(String format, Object[] argArray) { - if (effectiveLevelInt <= Level.WARN_INT) { - filterAndLog(FQCN, Level.WARN, format, new Object[] { argArray }, null); - } + filterAndLog(null, Level.WARN, format, argArray, null); } public void warn(Marker marker, String msg) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, marker, msg, null, null); - } + filterAndLog(marker, Level.WARN, msg, null, null); } public void warn(Marker marker, String format, Object arg) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, marker, format, new Object[] { arg }, null); - } + filterAndLog(marker, Level.WARN, format, new Object[] { arg }, null); } public void warn(Marker marker, String format, Object[] argArray) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, marker, format, new Object[] { argArray }, - null); - } + filterAndLog(marker, Level.WARN, format, argArray, null); } public void warn(Marker marker, String format, Object arg1, Object arg2) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, marker, format, - new Object[] { arg1, arg2 }, null); - } + filterAndLog(marker, Level.WARN, format, new Object[] { arg1, arg2 }, null); } public void warn(Marker marker, String msg, Throwable t) { - if (isWarnEnabled()) { - filterAndLog(FQCN, Level.WARN, marker, msg, null, t); - } + filterAndLog(marker, Level.WARN, msg, null, t); } public boolean isAdditive() { 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 Oct 30 23:16:56 2006 @@ -14,16 +14,22 @@ import java.util.Hashtable; import org.slf4j.ILoggerFactory; +import org.slf4j.Marker; +import ch.qos.logback.classic.filter.ClassicFilter; +import ch.qos.logback.classic.spi.ClassicFilterAttachable; +import ch.qos.logback.classic.spi.ClassicFilterAttachableImpl; import ch.qos.logback.classic.spi.LoggerContextRemoteView; import ch.qos.logback.core.ContextBase; import ch.qos.logback.core.CoreGlobal; +import ch.qos.logback.core.filter.Filter; import ch.qos.logback.core.status.ErrorStatus; /** * @author ceki */ -public class LoggerContext extends ContextBase implements ILoggerFactory { +public class LoggerContext extends ContextBase implements ILoggerFactory, + ClassicFilterAttachable { public static final String ROOT_NAME = "root"; @@ -40,6 +46,8 @@ LoggerContextRemoteView loggerContextRemoteView; + ClassicFilterAttachableImpl cfai = null; + public LoggerContext() { super(); this.loggerCache = new Hashtable<String, Logger>(); @@ -61,7 +69,7 @@ logger.buildRemoteView(); } } - + @Override public void setProperty(String key, String val) { super.setProperty(key, val); @@ -154,9 +162,42 @@ public LoggerContextRemoteView getLoggerContextRemoteView() { return loggerContextRemoteView; } - + public void reset() { + root.recursiveReset(); - + + } + + public void addFilter(ClassicFilter newFilter) { + if (cfai == null) { + cfai = new ClassicFilterAttachableImpl(); + } + cfai.addFilter(newFilter); + } + + public void clearAllFilters() { + if (cfai == null) { + return; + } + cfai.clearAllFilters(); + cfai = null; + } + + final public int getFilterChainDecision(final Marker marker, + final Logger logger, final Level level, final String format, final Object[] params, + final Throwable t) { + if (cfai == null) { + return Filter.NEUTRAL; + } + return cfai + .getFilterChainDecision(marker, logger, level, format, params, t); + } + + public ClassicFilter getFirstFilter() { + if (cfai == null) { + return null; + } + return cfai.getFirstFilter(); } } Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/filter/ClassicFilter.java ============================================================================== --- (empty file) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/filter/ClassicFilter.java Mon Oct 30 23:16:56 2006 @@ -0,0 +1,57 @@ +package ch.qos.logback.classic.filter; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.core.filter.Filter; + +/** + * ClassicFilter is a specialized filter with a decide method that takes a bunch of parameters + * instead of a single event object. The latter is cleaner but the latter is much more + * performant. + * + * @author Ceki Gulcu + */ +public abstract class ClassicFilter extends Filter { + + /** + * Points to the next filter in the filter chain. + */ + private ClassicFilter classicNext; + + /** + * Make a decision based on the multiple parameters passed as arguments. + * The returned value should be one of <code>{@link #DENY}</code>, + * <code>{@link #NEUTRAL}</code>, or <code>{@link #ACCEPT}</code>. + + * @param marker + * @param logger + * @param level + * @param format + * @param params + * @param t + * @return + */ + public abstract int decide(Marker marker, Logger logger, + Level level, String format, Object[] params, Throwable t); + + public int decide(Object o) { + throw new UnsupportedOperationException("decide(Object) not supported"); + } + + /** + * Set the next filter pointer. + */ + public void setNext(ClassicFilter next) { + this.classicNext = next; + } + + /** + * Return the pointer to the next filter; + */ + public ClassicFilter getNext() { + return classicNext; + } + +} Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassicFilterAttachable.java ============================================================================== --- (empty file) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassicFilterAttachable.java Mon Oct 30 23:16:56 2006 @@ -0,0 +1,36 @@ +package ch.qos.logback.classic.spi; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.filter.ClassicFilter; + +/** + * Interface for attaching ClassicFilter instances to objects. + * + * @author Ceki Gülcü + */ +public interface ClassicFilterAttachable { + + /** + * Add a filter. + */ + public void addFilter(ClassicFilter newFilter); + + /** + * Get first filter in the chain. + */ + public ClassicFilter getFirstFilter(); + + public void clearAllFilters(); + + /** + * Loop through the filters in the chain. As soon as a filter decides on + * ACCEPT or DENY, then that value is returned. If all of the filters return + * NEUTRAL, then NEUTRAL is returned. + */ + public int getFilterChainDecision(Marker marker, Logger logger, + Level level, String format, Object[] params, Throwable t); + +} Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassicFilterAttachableImpl.java ============================================================================== --- (empty file) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/spi/ClassicFilterAttachableImpl.java Mon Oct 30 23:16:56 2006 @@ -0,0 +1,87 @@ +/** + * Logback: the generic, reliable, fast and flexible logging framework. + * + * Copyright (C) 1999-2006, QOS.ch + * + * This library is free software, you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation. + */ +package ch.qos.logback.classic.spi; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.filter.ClassicFilter; +import ch.qos.logback.core.filter.Filter; + +/** + * Implementation of ClassicFilterAttachable. + * + * @author Ceki Gülcü + */ +final public class ClassicFilterAttachableImpl implements ClassicFilterAttachable { + + ClassicFilter headFilter; + ClassicFilter tailFilter; + + /** + * Add a filter to end of the filter list. + */ + public void addFilter(ClassicFilter newFilter) { + if (headFilter == null) { + headFilter = newFilter; + tailFilter = newFilter; + } else { + tailFilter.setNext(newFilter); + tailFilter = newFilter; + } + } + + /** + * Get first filter in the chain. + */ + public ClassicFilter getFirstFilter() { + return headFilter; + } + + /** + * Clear the filter chain + */ + public void clearAllFilters() { + ClassicFilter f = headFilter; + while (f != null) { + final ClassicFilter next = f.getNext(); + f.setNext(null); + f = next; + } + f = null; + headFilter = null; + tailFilter = null; + } + + /** + * Loop through the filters in the chain. As soon as a filter decides on + * ACCEPT or DENY, then that value is returned. If all of the filters return + * NEUTRAL, then NEUTRAL is returned. + */ + public int getFilterChainDecision(Marker marker, Logger logger, + Level level, String format, Object[] params, Throwable t) { + ClassicFilter f = headFilter; + + while (f != null) { + switch (f.decide(marker, logger, level, format, params, t)) { + case Filter.DENY: + return Filter.DENY; + + case Filter.ACCEPT: + return Filter.ACCEPT; + + case Filter.NEUTRAL: + f = f.getNext(); + } + } + return Filter.NEUTRAL; + } +} Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/BasicLoggerTest.java ============================================================================== --- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/BasicLoggerTest.java (original) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/BasicLoggerTest.java Mon Oct 30 23:16:56 2006 @@ -9,6 +9,9 @@ */ package ch.qos.logback.classic; +import java.net.InetAddress; +import java.net.UnknownHostException; + import junit.framework.TestCase; import org.slf4j.LoggerFactory; @@ -16,7 +19,6 @@ import ch.qos.logback.core.appender.ListAppender; import ch.qos.logback.core.util.StatusPrinter; - public class BasicLoggerTest extends TestCase { public void testBasic() { @@ -34,7 +36,7 @@ public void testNoStart() { LoggerContext lc = new LoggerContext(); ListAppender listAppender = new ListAppender(); - //listAppender.start(); + // listAppender.start(); listAppender.setContext(lc); Logger root = lc.getLogger(LoggerContext.ROOT_NAME); root.addAppender(listAppender); @@ -42,27 +44,45 @@ logger.debug("hello"); StatusPrinter.print(lc.getStatusManager()); } - + public void testAdditive() { - LoggerContext lc = new LoggerContext(); - ListAppender listAppender = new ListAppender(); - listAppender.start(); - Logger root = lc.getLogger(LoggerContext.ROOT_NAME); - root.addAppender(listAppender); - Logger logger = lc.getLogger(BasicLoggerTest.class); - logger.addAppender(listAppender); - logger.setAdditive(false); - logger.debug("hello"); - // 1 instead of two, since logger is not additive - assertEquals(1, listAppender.list.size()); + LoggerContext lc = new LoggerContext(); + ListAppender listAppender = new ListAppender(); + listAppender.start(); + Logger root = lc.getLogger(LoggerContext.ROOT_NAME); + root.addAppender(listAppender); + Logger logger = lc.getLogger(BasicLoggerTest.class); + logger.addAppender(listAppender); + logger.setAdditive(false); + logger.debug("hello"); + // 1 instead of two, since logger is not additive + assertEquals(1, listAppender.list.size()); } - + public void testRootLogger() { - Logger logger = (Logger)LoggerFactory.getLogger(LoggerContext.ROOT_NAME); - LoggerContext lc = logger.getLoggerContext(); - - assertNotNull("Returned logger is null", logger); - assertEquals("Return logger isn't named root", logger.getName(), LoggerContext.ROOT_NAME); - assertTrue("logger instances should be indentical", logger == lc.root); + Logger logger = (Logger) LoggerFactory.getLogger(LoggerContext.ROOT_NAME); + LoggerContext lc = logger.getLoggerContext(); + + assertNotNull("Returned logger is null", logger); + assertEquals("Return logger isn't named root", logger.getName(), + LoggerContext.ROOT_NAME); + assertTrue("logger instances should be indentical", logger == lc.root); + } + + public void testBasicFiltering() throws Exception { + LoggerContext lc = new LoggerContext(); + ListAppender listAppender = new ListAppender(); + listAppender.start(); + Logger root = lc.getLogger(LoggerContext.ROOT_NAME); + root.addAppender(listAppender); + root.setLevel(Level.INFO); + Logger logger = lc.getLogger(BasicLoggerTest.class); + logger.debug("x"); + assertEquals(0, listAppender.list.size()); + logger.info("x"); + logger.warn("x"); + logger.error("x"); + assertEquals(3, listAppender.list.size()); } + } Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java ============================================================================== --- (empty file) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java Mon Oct 30 23:16:56 2006 @@ -0,0 +1,44 @@ +package ch.qos.logback.classic; + + +import java.net.InetAddress; + +import junit.framework.TestCase; +import ch.qos.logback.core.appender.NOPAppender; + +public class LoggerPerfTest extends TestCase { + + final static String KAL = "kal"; + String localhostName = null; + + public void setUp() throws Exception { + localhostName = InetAddress.getLocalHost().getCanonicalHostName(); + } + public void testSpeed() { + long len = 1000*1000*10; + loop(len); + double avg = loop(len); + + System.out.println("Running on "+localhostName); + // check for performance on KAL only + if(KAL.equals(localhostName)) { + assertTrue(30 > avg); + } + System.out.println("Average log time for disabled statements: "+avg+" nanos."); + } + + double loop(long len) { + LoggerContext lc = new LoggerContext(); + NOPAppender mopAppender = new NOPAppender(); + mopAppender.start(); + Logger logger = lc.getLogger(this.getClass()); + logger.setLevel(Level.OFF); + long start = System.nanoTime(); + for(long i = 0; i < len; i++) { + logger.debug("Toto"); + } + long end = System.nanoTime(); + return (end-start)/len; + } + +}