logback-dev
Threads by month
- ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
December 2008
- 8 participants
- 156 discussions

svn commit: r2093 - in logback/trunk: logback-classic/src/main/java/ch/qos/logback/classic/sift logback-core/src/main/java/ch/qos/logback/core/sift logback-core/src/test/java/ch/qos/logback/core/sift logback-core/src/test/java/ch/qos/logback/core/sift/tracker
by noreply.ceki@qos.ch 19 Dec '08
by noreply.ceki@qos.ch 19 Dec '08
19 Dec '08
Author: ceki
Date: Fri Dec 19 19:24:52 2008
New Revision: 2093
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java
Log:
- The key parameter used as a sifting discriminator is now of type String
instead of a generic K. This simplifies the code without real loss
of generality. :-)
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java Fri Dec 19 19:24:52 2008
@@ -17,7 +17,7 @@
import ch.qos.logback.core.sift.AppenderFactoryBase;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
-public class AppenderFactory extends AppenderFactoryBase<LoggingEvent, String>{
+public class AppenderFactory extends AppenderFactoryBase<LoggingEvent>{
String mdcKey;
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java Fri Dec 19 19:24:52 2008
@@ -26,7 +26,7 @@
*
* @author Ceki Gulcu
*/
-public class SiftingAppender extends SiftingAppenderBase<LoggingEvent, String> {
+public class SiftingAppender extends SiftingAppenderBase<LoggingEvent> {
String mdcKey;
@@ -59,7 +59,7 @@
}
}
- AppenderTracker<LoggingEvent, String> getAppenderTracker() {
+ AppenderTracker<LoggingEvent> getAppenderTracker() {
return appenderTracker;
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java Fri Dec 19 19:24:52 2008
@@ -17,7 +17,7 @@
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.JoranException;
-public abstract class AppenderFactoryBase<E, K> {
+public abstract class AppenderFactoryBase<E> {
final List<SaxEvent> eventList;
Context context;
@@ -35,9 +35,9 @@
System.out.println(eventList);
}
- public abstract SiftingJoranConfiguratorBase<E> getSiftingJoranConfigurator(K k);
+ public abstract SiftingJoranConfiguratorBase<E> getSiftingJoranConfigurator(String k);
- Appender<E> buildAppender(Context context, K k) throws JoranException {
+ Appender<E> buildAppender(Context context, String k) throws JoranException {
SiftingJoranConfiguratorBase<E> sjc = getSiftingJoranConfigurator(k);
sjc.setContext(context);
sjc.doConfigure(eventList);
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java Fri Dec 19 19:24:52 2008
@@ -13,15 +13,15 @@
import ch.qos.logback.core.Appender;
-public interface AppenderTracker<E, K> {
+public interface AppenderTracker<E> {
static int MILLIS_IN_ONE_SECOND = 1000;
static int THRESHOLD = 30 * 60 * MILLIS_IN_ONE_SECOND; // 30 minutes
- void put(K key, Appender<E> value, long timestamp);
- Appender<E> get(K key, long timestamp);
+ void put(String key, Appender<E> value, long timestamp);
+ Appender<E> get(String key, long timestamp);
void stopStaleAppenders(long timestamp);
- List<K> keyList();
+ List<String> keyList();
List<Appender<E>> valueList();
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java Fri Dec 19 19:24:52 2008
@@ -21,9 +21,9 @@
* longer than THRESHOLD, stop it.
* @author Ceki Gulcu
*/
-public class AppenderTrackerImpl<E, K> implements AppenderTracker<E, K> {
+public class AppenderTrackerImpl<E> implements AppenderTracker<E> {
- Map<K, Entry> map = new HashMap<K, Entry>();
+ Map<String, Entry> map = new HashMap<String, Entry>();
Entry head; // least recently used entries are towards the head
Entry tail; // most recently used entries are towards the tail
@@ -36,7 +36,7 @@
}
- public synchronized void put(K key, Appender<E> value, long timestamp) {
+ public synchronized void put(String key, Appender<E> value, long timestamp) {
Entry entry = map.get(key);
if (entry == null) {
entry = new Entry(key, value, timestamp);
@@ -45,7 +45,7 @@
moveToTail(entry);
}
- public synchronized Appender<E> get(K key, long timestamp) {
+ public synchronized Appender<E> get(String key, long timestamp) {
Entry existing = map.get(key);
if (existing == null) {
return null;
@@ -70,8 +70,8 @@
}
}
- public List<K> keyList() {
- List<K> result = new LinkedList<K>();
+ public List<String> keyList() {
+ List<String> result = new LinkedList<String>();
Entry e = head;
while (e != tail) {
result.add(e.key);
@@ -151,11 +151,11 @@
Entry next;
Entry prev;
- K key;
+ String key;
Appender<E> value;
long timestamp;
- Entry(K k, Appender<E> v, long timestamp) {
+ Entry(String k, Appender<E> v, long timestamp) {
this.key = k;
this.value = v;
this.timestamp = timestamp;
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java Fri Dec 19 19:24:52 2008
@@ -12,7 +12,6 @@
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.OptionHelper;
/**
* This appender can contains other appenders which it can build dynamically
@@ -24,13 +23,13 @@
*
* @author Ceki Gulcu
*/
-public abstract class SiftingAppenderBase<E, K> extends
+public abstract class SiftingAppenderBase<E> extends
UnsynchronizedAppenderBase<E> {
- protected AppenderTracker<E, K> appenderTracker = new AppenderTrackerImpl<E, K>();
- AppenderFactoryBase<E, K> appenderFactory;
+ protected AppenderTracker<E> appenderTracker = new AppenderTrackerImpl<E>();
+ AppenderFactoryBase<E> appenderFactory;
- public void setAppenderFactory(AppenderFactoryBase<E, K> appenderFactory) {
+ public void setAppenderFactory(AppenderFactoryBase<E> appenderFactory) {
this.appenderFactory = appenderFactory;
}
@@ -46,7 +45,7 @@
}
}
- abstract protected K getDiscriminatingValue(E event);
+ abstract protected String getDiscriminatingValue(E event);
abstract protected long getTimestamp(E event);
@Override
@@ -55,7 +54,7 @@
return;
}
- K value = getDiscriminatingValue(event);
+ String value = getDiscriminatingValue(event);
long timestamp = getTimestamp(event);
Appender<E> appender = appenderTracker.get(value, timestamp);
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java Fri Dec 19 19:24:52 2008
@@ -16,7 +16,7 @@
Context context = new ContextBase();
- AppenderTracker<Object, String> appenderTracker = new AppenderTrackerImpl<Object, String>();
+ AppenderTracker<Object> appenderTracker = new AppenderTrackerImpl<Object>();
ListAppender<Object> la = new ListAppender<Object>();
@Before
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java Fri Dec 19 19:24:52 2008
@@ -28,7 +28,7 @@
*/
public class Simulator {
- AppenderTrackerImpl<Object, String> appenderTracker = new AppenderTrackerImpl<Object, String>();
+ AppenderTrackerImpl<Object> appenderTracker = new AppenderTrackerImpl<Object>();
AppenderTrackerTImpl t_appenderTracker = new AppenderTrackerTImpl();
List<String> keySpace = new ArrayList<String>();
@@ -79,7 +79,7 @@
}
void play(SimulationEvent simulationEvent,
- AppenderTracker<Object, String> appenderTracker) {
+ AppenderTracker<Object> appenderTracker) {
String mdcValue = simulationEvent.key;
long timestamp = simulationEvent.timestamp;
Appender<Object> appender = appenderTracker.get(mdcValue, timestamp);
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java Fri Dec 19 19:24:52 2008
@@ -23,7 +23,7 @@
*
* @author Ceki Gulcu
*/
-public class AppenderTrackerTImpl implements AppenderTracker<Object, String> {
+public class AppenderTrackerTImpl implements AppenderTracker<Object> {
List<TEntry> entryList = new LinkedList<TEntry>();
long lastCheck = 0;
1
0
Author: ceki
Date: Fri Dec 19 17:10:55 2008
New Revision: 2092
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java
- copied, changed from r2091, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java
- copied, changed from r2087, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java
logback/trunk/logback-examples/src/main/java/chapter6/duplicateMessage.xml
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml
logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml
logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
logback/trunk/logback-examples/src/main/java/chapter6/FilterEvents.java
logback/trunk/logback-examples/src/main/java/chapter6/basicConfiguration.xml
logback/trunk/logback-examples/src/main/java/chapter6/basicEventEvaluator.xml
logback/trunk/logback-examples/src/main/java/chapter6/levelFilterConfig.xml
logback/trunk/logback-examples/src/main/java/chapter6/sampleTurboFilterConfig.xml
logback/trunk/logback-examples/src/main/java/chapter6/thresholdFilterConfig.xml
logback/trunk/logback-examples/src/main/java/chapter6/turboFilters.xml
logback/trunk/logback-site/src/site/pages/manual/filters.html
logback/trunk/logback-site/src/site/pages/manual/joran.html
logback/trunk/logback-site/src/site/pages/news.html
logback/trunk/logback-site/src/site/pages/support.html
Log:
- Documentation on DuplicateMessageFilter
- Finished renaming HoardingAppender as SiftingAppender (as well as associated classes)
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java Fri Dec 19 17:10:55 2008
@@ -20,7 +20,7 @@
import ch.qos.logback.classic.joran.action.LevelAction;
import ch.qos.logback.classic.joran.action.LoggerAction;
import ch.qos.logback.classic.joran.action.RootLoggerAction;
-import ch.qos.logback.classic.sift.HoardAction;
+import ch.qos.logback.classic.sift.SiftAction;
import ch.qos.logback.classic.spi.PlatformInfo;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
import ch.qos.logback.core.joran.action.AppenderRefAction;
@@ -53,8 +53,8 @@
rs.addRule(new Pattern("*/evaluator/matcher"),
new MatcherAction());
- rs.addRule(new Pattern("configuration/appender/hoard"), new HoardAction());
- rs.addRule(new Pattern("configuration/appender/hoard/*"), new NOPAction());
+ rs.addRule(new Pattern("configuration/appender/sift"), new SiftAction());
+ rs.addRule(new Pattern("configuration/appender/sift/*"), new NOPAction());
rs.addRule(new Pattern("configuration/logger"), new LoggerAction());
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java Fri Dec 19 17:10:55 2008
@@ -27,7 +27,7 @@
}
public SiftingJoranConfiguratorBase<LoggingEvent> getSiftingJoranConfigurator(String k) {
- return new HoardingJoranConfigurator(mdcKey, k);
+ return new SiftingJoranConfigurator(mdcKey, k);
}
}
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java (from r2091, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftAction.java Fri Dec 19 17:10:55 2008
@@ -11,7 +11,7 @@
import ch.qos.logback.core.joran.spi.ActionException;
import ch.qos.logback.core.joran.spi.InterpretationContext;
-public class HoardAction extends Action implements InPlayListener {
+public class SiftAction extends Action implements InPlayListener {
List<SaxEvent> seList;
@Override
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java (from r2087, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingJoranConfigurator.java Fri Dec 19 17:10:55 2008
@@ -12,12 +12,12 @@
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
-public class HoardingJoranConfigurator extends SiftingJoranConfiguratorBase<LoggingEvent> {
+public class SiftingJoranConfigurator extends SiftingJoranConfiguratorBase<LoggingEvent> {
String key;
String value;
- HoardingJoranConfigurator(String key, String value) {
+ SiftingJoranConfigurator(String key, String value) {
this.key = key;
this.value = value;
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java Fri Dec 19 17:10:55 2008
@@ -15,22 +15,36 @@
import ch.qos.logback.classic.Logger;
import ch.qos.logback.core.spi.FilterReply;
+/**
+ *
+ * See {@link http://logback.qos.ch/manual/filters.html#DuplicateMessageFilter}
+ * for details.
+ *
+ * @author Ceki Gulcu
+ *
+ */
public class DuplicateMessageFilter extends TurboFilter {
- static final int DEFAULT_CACHE_SIZE = 100;
- static final int DEFAULT_ALLOWED_REPETITIONS = 5;
-
+ /**
+ * The default cache size.
+ */
+ public static final int DEFAULT_CACHE_SIZE = 100;
+ /**
+ * The default number of allows repetitions.
+ */
+ public static final int DEFAULT_ALLOWED_REPETITIONS = 5;
+
public int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;
public int cacheSize = DEFAULT_CACHE_SIZE;
-
+
private LRUMessageCache msgCache;
-
+
@Override
public void start() {
msgCache = new LRUMessageCache(cacheSize);
super.start();
}
-
+
@Override
public void stop() {
msgCache.clear();
@@ -42,7 +56,7 @@
public FilterReply decide(Marker marker, Logger logger, Level level,
String format, Object[] params, Throwable t) {
int count = msgCache.getMessageCount(format);
- if(count <= allowedRepetitions) {
+ if (count <= allowedRepetitions) {
return FilterReply.NEUTRAL;
} else {
return FilterReply.DENY;
@@ -53,6 +67,11 @@
return allowedRepetitions;
}
+ /**
+ * The allowed number of repetitions before
+ *
+ * @param allowedRepetitions
+ */
public void setAllowedRepetitions(int allowedRepetitions) {
this.allowedRepetitions = allowedRepetitions;
}
@@ -64,5 +83,5 @@
public void setCacheSize(int cacheSize) {
this.cacheSize = cacheSize;
}
-
+
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java Fri Dec 19 17:10:55 2008
@@ -29,7 +29,7 @@
int getMessageCount(String msg) {
Integer i = super.get(msg);
if(i == null) {
- i = 1;
+ i = 0;
} else {
i = new Integer(i.intValue()+1);
}
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml Fri Dec 19 17:10:55 2008
@@ -8,9 +8,9 @@
<mdcKey>cycle</mdcKey>
<defaultValue>cycleDefault</defaultValue>
- <hoard>
+ <sift>
<appender name="list-${cycle}" class="ch.qos.logback.core.read.ListAppender"/>
- </hoard>
+ </sift>
</appender>
<root level="DEBUG">
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml Fri Dec 19 17:10:55 2008
@@ -4,11 +4,11 @@
<configuration debug="true">
<appender name="SIFT"
- class="ch.qos.logback.classic.hoard.HoardingAppender">
+ class="ch.qos.logback.classic.sift.SiftingAppender">
<mdcKey>userid</mdcKey>
<default>asdad</default>
- <hoard>
+ <sift>
<appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
<File>${userid}.log</File>
<Append>true</Append>
@@ -16,7 +16,7 @@
<Pattern>%d [%thread] %level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
- </hoard>
+ </sift>
</appender>
<root level="DEBUG">
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml
==============================================================================
--- logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml Fri Dec 19 17:10:55 2008
@@ -8,9 +8,9 @@
<mdcKey>userid</mdcKey>
<defaultValue>smoke</defaultValue>
- <hoard>
+ <sift>
<appender name="list-${userid}" class="ch.qos.logback.core.read.ListAppender"/>
- </hoard>
+ </sift>
</appender>
<root level="DEBUG">
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java Fri Dec 19 17:10:55 2008
@@ -1,3 +1,12 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.turbo;
import static org.junit.Assert.*;
@@ -13,7 +22,7 @@
@Test
public void smoke() {
DuplicateMessageFilter dmf = new DuplicateMessageFilter();
- dmf.setAllowedRepetitions(1);
+ dmf.setAllowedRepetitions(0);
dmf.start();
assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "x", null, null));
assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "y", null, null));
@@ -36,7 +45,7 @@
@Test
public void many() {
DuplicateMessageFilter dmf = new DuplicateMessageFilter();
- dmf.setAllowedRepetitions(1);
+ dmf.setAllowedRepetitions(0);
int cacheSize = 10;
int margin = 2;
dmf.setCacheSize(cacheSize);
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java Fri Dec 19 17:10:55 2008
@@ -28,12 +28,6 @@
UnsynchronizedAppenderBase<E> {
protected AppenderTracker<E, K> appenderTracker = new AppenderTrackerImpl<E, K>();
- // Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String,
- // Appender<LoggingEvent>>();
-
- String mdcKey;
- String defaultValue;
-
AppenderFactoryBase<E, K> appenderFactory;
public void setAppenderFactory(AppenderFactoryBase<E, K> appenderFactory) {
@@ -53,7 +47,6 @@
}
abstract protected K getDiscriminatingValue(E event);
-
abstract protected long getTimestamp(E event);
@Override
@@ -82,20 +75,4 @@
appender.doAppend(event);
}
- public String getMdcKey() {
- return mdcKey;
- }
-
- public void setMdcKey(String mdcKey) {
- this.mdcKey = mdcKey;
- }
-
- /**
- * @see #setDefaultValue(String)
- * @return
- */
- public String getDefaultValue() {
- return defaultValue;
- }
-
}
Modified: logback/trunk/logback-examples/src/main/java/chapter6/FilterEvents.java
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/FilterEvents.java (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/FilterEvents.java Fri Dec 19 17:10:55 2008
@@ -33,13 +33,13 @@
for (int i = 0; i < 10; i++) {
if (i == 3) {
MDC.put("username", "sebastien");
- logger.debug("logging statement " + i);
+ logger.debug("logging statement {}", i);
MDC.remove("username");
} else if (i == 6) {
Marker billing = MarkerFactory.getMarker("billing");
- logger.error(billing, "billing statement " + i);
+ logger.error(billing, "billing statement {}", i);
} else {
- logger.info("logging statement " + i);
+ logger.info("logging statement {}", i);
}
}
}
Modified: logback/trunk/logback-examples/src/main/java/chapter6/basicConfiguration.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/basicConfiguration.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/basicConfiguration.xml Fri Dec 19 17:10:55 2008
@@ -1,16 +1,12 @@
<configuration>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </layout>
- </appender>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
- <root>
- <level value="DEBUG" />
- <appender-ref ref="STDOUT" />
- </root>
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
</configuration>
\ No newline at end of file
Modified: logback/trunk/logback-examples/src/main/java/chapter6/basicEventEvaluator.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/basicEventEvaluator.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/basicEventEvaluator.xml Fri Dec 19 17:10:55 2008
@@ -1,23 +1,19 @@
<configuration debug="true">
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
- <evaluator name="myEval">
- <expression>message.contains("billing")</expression>
- </evaluator>
- <OnMismatch>NEUTRAL</OnMismatch>
- <OnMatch>DENY</OnMatch>
- </filter>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </layout>
- </appender>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator name="myEval">
+ <expression>message.contains("billing")</expression>
+ </evaluator>
+ <OnMismatch>NEUTRAL</OnMismatch>
+ <OnMatch>DENY</OnMatch>
+ </filter>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
- <root>
- <level value="DEBUG" />
- <appender-ref ref="STDOUT" />
- </root>
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
</configuration>
\ No newline at end of file
Added: logback/trunk/logback-examples/src/main/java/chapter6/duplicateMessage.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter6/duplicateMessage.xml Fri Dec 19 17:10:55 2008
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<configuration>
+
+ <turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter" />
+
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date [%thread] %-5level %logger - %msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="console" />
+ </root>
+</configuration>
\ No newline at end of file
Modified: logback/trunk/logback-examples/src/main/java/chapter6/levelFilterConfig.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/levelFilterConfig.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/levelFilterConfig.xml Fri Dec 19 17:10:55 2008
@@ -1,21 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
- <appender name="CONSOLE"
- class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>INFO</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>
- %-4relative [%thread] %-5level %logger{30} - %msg%n
- </pattern>
- </layout>
- </appender>
- <root>
- <level value="DEBUG" />
- <appender-ref ref="CONSOLE" />
- </root>
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.classic.filter.LevelFilter">
+ <level>INFO</level>
+ <onMatch>ACCEPT</onMatch>
+ <onMismatch>DENY</onMismatch>
+ </filter>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
+ </layout>
+ </appender>
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
</configuration>
\ No newline at end of file
Modified: logback/trunk/logback-examples/src/main/java/chapter6/sampleTurboFilterConfig.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/sampleTurboFilterConfig.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/sampleTurboFilterConfig.xml Fri Dec 19 17:10:55 2008
@@ -1,19 +1,16 @@
<configuration>
- <turboFilter class="chapter6.SampleTurboFilter">
- <Marker>sample</Marker>
- </turboFilter>
+ <turboFilter class="chapter6.SampleTurboFilter">
+ <Marker>sample</Marker>
+ </turboFilter>
- <appender name="STDOUT"
- class="ch.qos.logback.core.ConsoleAppender">
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>
- %-4relative [%thread] %-5level %logger - %msg%n
- </pattern>
- </layout>
- </appender>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
+ </layout>
+ </appender>
- <root>
- <appender-ref ref="STDOUT" />
- </root>
+ <root>
+ <appender-ref ref="STDOUT" />
+ </root>
</configuration>
\ No newline at end of file
Modified: logback/trunk/logback-examples/src/main/java/chapter6/thresholdFilterConfig.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/thresholdFilterConfig.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/thresholdFilterConfig.xml Fri Dec 19 17:10:55 2008
@@ -1,19 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
- <appender name="CONSOLE"
- class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>INFO</level>
- </filter>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <pattern>
- %-4relative [%thread] %-5level %logger{30} - %msg%n
- </pattern>
- </layout>
- </appender>
- <root>
- <level value="DEBUG" />
- <appender-ref ref="CONSOLE" />
- </root>
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>INFO</level>
+ </filter>
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
+ </layout>
+ </appender>
+ <root level="DEBUG">
+ <appender-ref ref="CONSOLE" />
+ </root>
</configuration>
\ No newline at end of file
Modified: logback/trunk/logback-examples/src/main/java/chapter6/turboFilters.xml
==============================================================================
--- logback/trunk/logback-examples/src/main/java/chapter6/turboFilters.xml (original)
+++ logback/trunk/logback-examples/src/main/java/chapter6/turboFilters.xml Fri Dec 19 17:10:55 2008
@@ -2,16 +2,16 @@
<configuration>
- <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
- <MDCKey>username</MDCKey>
- <Value>sebastien</Value>
- <OnMatch>ACCEPT</OnMatch>
- </turboFilter>
-
- <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
- <Marker>billing</Marker>
- <OnMatch>DENY</OnMatch>
- </turboFilter>
+ <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
+ <MDCKey>username</MDCKey>
+ <Value>sebastien</Value>
+ <OnMatch>ACCEPT</OnMatch>
+ </turboFilter>
+
+ <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
+ <Marker>billing</Marker>
+ <OnMatch>DENY</OnMatch>
+ </turboFilter>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
@@ -19,8 +19,7 @@
</layout>
</appender>
- <root>
- <level value="info"/>
+ <root level="info">
<appender-ref ref="console" />
- </root>
+ </root>
</configuration>
\ No newline at end of file
Modified: logback/trunk/logback-site/src/site/pages/manual/filters.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/filters.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/filters.html Fri Dec 19 17:10:55 2008
@@ -390,7 +390,7 @@
<p>The <a
href="../xref/chapter6/FilterEvents.html"><code>FilterEvents</code></a>
- class issues ten logging requests, numbered from 0 to 9. Let us
+ application issues ten logging requests, numbered 0 to 9. Let us
rist run <code>FilterEvents</code> class without any filters:
</p>
@@ -422,7 +422,7 @@
<p>we obtain:
</p>
-<div class="source"><pre>0 [main] INFO chapter6.FilterEvents - logging statement 0
+ <p class="source">0 [main] INFO chapter6.FilterEvents - logging statement 0
0 [main] INFO chapter6.FilterEvents - logging statement 1
0 [main] INFO chapter6.FilterEvents - logging statement 2
0 [main] DEBUG chapter6.FilterEvents - logging statement 3
@@ -430,11 +430,10 @@
0 [main] INFO chapter6.FilterEvents - logging statement 5
0 [main] INFO chapter6.FilterEvents - logging statement 7
0 [main] INFO chapter6.FilterEvents - logging statement 8
-0 [main] INFO chapter6.FilterEvents - logging statement 9</pre></div>
+0 [main] INFO chapter6.FilterEvents - logging statement 9</p>
- <a name="TurboFilter"></a>
- <h3>TurboFilters</h3>
+ <h2><a name="TurboFilter" href="#TurboFilter">TurboFilters</a></h2>
<p><code>TurboFilter</code> objects all extend the
<a href="../xref/ch/qos/logback/classic/turbo/TurboFilter.html">
@@ -601,31 +600,32 @@
</root>
</configuration></pre></div>
- <p>
- You can see this configuration in action by issuing the following command:
+ <p>You can see this configuration in action by issuing the
+ following command:
</p>
-<div class="source"><pre>
-java chapter6.FilterEvents src/main/java/chapter6/turboFilters.xml
-</pre></div>
+ <p class="source">java chapter6.FilterEvents src/main/java/chapter6/turboFilters.xml</p>
- <p>
- As we've seen previously, the <code>FilterEvents</code> class creates 10 logging requests,
- each with its number from 0 to 9. All of the requests are of level <em>INFO</em>,
- just like the configured overall level, except for two requests.
- The 3rd request, is a <em>DEBUG</em> level corresponding to the key <em>username</em>.
- This obviously satisfies the first <code>TurboFilter</code> declared in the previous
- configuration file. The 6th request, a <em>ERROR</em> level request,
- which is issued along with the <em>billing</em> marker, matches
- the second <code>TurboFilter</code>.
+ <p>As we've seen previously, the <a
+ href="../xref/chapter6/FilterEvents.html"><code>FilterEvents</code></a>
+ application issues 10 logging requests, numbered 0 to 9. Except
+ for requests 3 and 6, all of the requests are of level
+ <em>INFO</em>, the same level as the one assigned to the root
+ logger. The 3rd request, is issued at the the <em>DEBUG</em>
+ level, which is below the effective level. However, since the MDC
+ key "username" is set to "sebastien" just before the 3rd request
+ and removed just afterwards, the <code>MDCFilter</code>
+ specifically accepts the request (and only that request). The 6th
+ request, issued at the <em>ERROR</em> level, is marked as
+ "billing". As such, it is denied by the MarkerFilter (the second
+ turbo filter in the configuration).
</p>
- <p>
- Here is the output of the previous command:
+ <p>Thus, the output of <code>FilterEvents</code> application
+ configured with <em>turboFilters.xml</em> file shown above is:
</p>
-<div class="source"><pre>
-2006-12-04 15:17:22,859 [main] INFO chapter6.FilterEvents - logging statement 0
+ <p class="source">2006-12-04 15:17:22,859 [main] INFO chapter6.FilterEvents - logging statement 0
2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 1
2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 2
2006-12-04 15:17:22,875 [main] DEBUG chapter6.FilterEvents - logging statement 3
@@ -633,24 +633,119 @@
2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 5
2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 7
2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 8
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 9
-</pre></div>
+2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 9</p>
- <p>
- One can see that the 3rd request, who should not be displayed if we
- only followed the overall <em>INFO</em> level, appears anyway, because
- it matched the first <code>TurboFilter</code> requirements and was accepted.
+ <p>One can see that the 3rd request, which should not be displayed
+ if we only followed the overall <em>INFO</em> level, appears
+ anyway, because it matched the first <code>TurboFilter</code>
+ requirements and was accepted.
</p>
- <p>
- On the other hand, the 6th request, that is a <em>ERROR</em> level request
- should have been displayed. But it satisfied the second <code>TurboFilter</code>
- whose <span class="option">OnMatch</span> option is set to <em>DENY</em>.
- Thus, the 6th request was not displayed.
+ <p>On the other hand, the 6th request, that is a <em>ERROR</em>
+ level request should have been displayed. But it satisfied the
+ second <code>TurboFilter</code> whose <span
+ class="option">OnMatch</span> option is set to <em>DENY</em>.
+ Thus, the 6th request was not displayed.
</p>
+
+
+ <h3><a name="DuplicateMessageFilter"
+ href="#DuplicateMessageFilter">DuplicateMessageFilter</a></h3>
+
+ <p>The <code>DuplicateMessageFilter</code> merits a separate
+ presentation. This filter detects duplicate messages, and beyond
+ a certain number of repetitions, drops repeated messages.
+ </p>
+
+ <p>To detect repetition, this filter uses simple String equality
+ between messages. It does not detect messages which are very
+ similar, varying only by few characters. For example, if you
+ write:
+ </p>
+
+ <p class="source">logger.debug("Hello "+name0);
+logger.debug("Hello "+name1);</p>
+
+ <p>Assuming <code>name0</code> and <code>name1</code> have
+ different values, the two "Hello" messages will be considered as
+ unrelated. Depending on user demand, future releases may check for
+ string similarity, eliminating repetitions of similar but not
+ identical messages.
+ </p>
+
+ <p>Note that in case of parameterized logging, only the raw
+ message is taken into consideration. For example, in the next two
+ requests, the raw messages, i.e. "Hello {}.", are identical, and
+ thus considered as repetitions.
+ </p>
+
+ <p class="source">logger.debug("Hello {}.", name0);
+logger.debug("Hello {}.", name1);</p>
+
+ <p>The number of allowed repetitions can be specified by the <span
+ class="option">AllowedRepetitions</span> property. For example, if
+ the said property is set to 1, then the 2nd and subsequent
+ occurrences of the same message will be dropped. Similarly, if the
+ said property is set to 2, then the 3rd and subsequent occurrences
+ of the same message will be dropped. By default, the <span
+ class="option">AllowedRepetitions</span> property is set to 5.
+ </p>
+
+ <p>In order to detect repetitions, this filter needs to keep
+ references to old messages in an internal cache. The size of this
+ cache is determined by the <span class="option">CacheSize</span>
+ property. By the default, this is set to 100.
+ </p>
+
+
+<em>Example: <code>DuplicateMessageFilter</code>
+configuration (logback-examples/src/main/java/chapter6/duplicateMessage.xml)</em>
+<div class="source"><pre><configuration>
+
+ <b><turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter"/></b>
+
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%date [%thread] %-5level %logger - %msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="console" />
+ </root>
+</configuration></pre></div>
+
+ <p>Thus, the output for <code>FilterEvents</code> application
+ configured with <em>duplicateMessage.xml</em> is:
+ </p>
+
+ <p class="source">2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 0
+2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 1
+2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 2
+2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 4
+2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 5
+2008-12-19 15:04:26,171 [main] ERROR chapter6.FilterEvents - billing statement 6</p>
+
+ <p>"logging statement 0" is the first <em>occurrence</em> of the
+ message "logging statement {}". "logging statement 1" is the first
+ <em>repetition</em>, "logging statement 2" is the second
+ repetition. Interestingly enough, "logging statement 3" of level
+ DEBUG, is the <em>third</em> repetition, even though it is later
+ dropped by virtue of the <a
+ href="architecture.html#basic_selection">basic selection
+ rule</a>. This can be explained by the fact that turbo filters are
+ invoked before other types of filters, including the basic
+ selection rule. Thus, <code>DuplicateMessageFilter</code>
+ considers "logging statement 3" as a repetition, oblivious to the
+ fact that it will be dropped further down in the processing
+ chain. "logging statement 4" is the fourth repetition and "logging
+ statement 5" the fifth. Statements 6 and beyond are dropped
+ because only 5 repetitions are allowed by default.
+ </p>
+
<h2>Logback-access</h2>
<p>Logback-access offers most of the features available with
Modified: logback/trunk/logback-site/src/site/pages/manual/joran.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/joran.html (original)
+++ logback/trunk/logback-site/src/site/pages/manual/joran.html Fri Dec 19 17:10:55 2008
@@ -414,12 +414,21 @@
</p>
<p>Given a <code>StatusManager</code> you an access all the status
- data associated with a logback context. You may also attach a
- <code>StatusListener</code> to a <code>StatusManager</code> so that
- you can take immediate action in response to status messages,
- especially to messages occuring after logback
- configuration. Registering a status listener is a convenient way to
- supervise logback's internal state without human intervention.
+ data associated with a logback context. To keep memory usage at
+ reasonable levels, the default <code>StatusManager</code>
+ implementation stores the status messages in two separate parts,
+ the header part and the tail part. The header part stores the fist
+ <em>H</em> status messages whereas the tail part stores the last
+ <em>T</em> messages. At present time <em>H</em>=<em>T</em>=150,
+ although these values may change in future releases.</p>
+
+
+ <p>You may also attach a <code>StatusListener</code> to a
+ <code>StatusManager</code> so that you can take immediate action in
+ response to status messages, especially to messages occurring after
+ logback configuration. Registering a status listener is a
+ convenient way to supervise logback's internal state without human
+ intervention.
</p>
<p>Logback ships with a <code>StatusListener</code> implementation
Modified: logback/trunk/logback-site/src/site/pages/news.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/news.html (original)
+++ logback/trunk/logback-site/src/site/pages/news.html Fri Dec 19 17:10:55 2008
@@ -29,6 +29,37 @@
<hr width="80%" align="center" />
+ <h3>xx of December 2008 - Release of version 0.9.14</h3>
+
+ <p>Corrected a serious dead-lock problem occuring during
+ configuration. It was reported in <a
+ href="http://jira.qos.ch/browse/LBCLASSIC-81">LBCLASSIC-81</a> by
+ Holger Mense.</p>
+
+ <p>Corrected thread leakage observed with
+ <code>TimeBasedRollingPolicy</code>'s
+ <code>AsynchronousCompressor</code>. This bug was reported in <a
+ href="http://jira.qos.ch/browse/LBCORE-78">LBCORE-78</a> by Szel
+ Zoltan.</p>
+
+ <p>Added <a
+ href="manual/filters.html#DuplicateMessageFilter">DuplicateMessageFilter</a>,
+ a turbo filter which detects duplicate messages, and beyond a
+ certain number of repetitions, drops repeated messages.</p>
+
+
+ <p><code>BasicStatusManager</code>'s internal buffer is now split
+ into two parts, the header part and the tail part. The header part
+ stores the fist H status messages whereas the tail part stores the
+ last T messages. At present time H=T=150, although these values may
+ change in future releases.</p>
+
+ <p>Fixed <code>NullPointerException</code> thrown when calling
+ <code>setContextMap</code> on a fresh MDC. <a
+ href="http://jira.qos.ch/browse/LBCLASSIC-98">Issue was</a>
+ reported by Francois Terrier.
+ </p>
+
<h3>5th of December 2008 - Release of version 0.9.13</h3>
<p>A <code>NullPointerException</code> was being thrown when a the
Modified: logback/trunk/logback-site/src/site/pages/support.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/support.html (original)
+++ logback/trunk/logback-site/src/site/pages/support.html Fri Dec 19 17:10:55 2008
@@ -30,15 +30,17 @@
<p>As the founders and current maintainers of the logback project,
we can offer you highest quality of support. Opting for our
- professional logback support service is a great way to leverage the
- expertise of developers who have in depth knowledge of the logback
- framework.
+ professional logback support service is a great way to leverage
+ the expertise of logback developers.
</p>
+ <p>If your project requires custom appenders or logback
+ extensions, we can also help you.
+ </p>
- <p>To obtain a quote for "Professional Support Contract" please do
- not hesitate to contact us. We will happy to discuss or help you
- with logging-related issues.</p>
+ <p>For a quote for "Professional Support Contract" please do not
+ hesitate to contact us. We will happy to discuss or help you with
+ logging-related issues.</p>
<table>
<tr>
1
0

18 Dec '08
Author: ceki
Date: Thu Dec 18 22:33:27 2008
New Revision: 2091
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java
- copied, changed from r2087, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java
logback/trunk/logback-classic/src/test/input/joran/sift/
- copied from r2086, /logback/trunk/logback-classic/src/test/input/joran/hoard/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java
logback/trunk/logback-classic/src/test/input/joran/hoard/
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml
logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml
logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml
logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
Log:
SiftingAppender has been largely made generic by virtue of its migration to lb-core
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java Thu Dec 18 22:33:27 2008
@@ -25,8 +25,8 @@
public void end(InterpretationContext ec, String name) throws ActionException {
ec.removeInPlayListener(this);
Object o = ec.peekObject();
- if (o instanceof HoardingAppender) {
- HoardingAppender ha = (HoardingAppender) o;
+ if (o instanceof SiftingAppender) {
+ SiftingAppender ha = (SiftingAppender) o;
AppenderFactory appenderFactory = new AppenderFactory(context, seList, ha.getMdcKey());
ha.setAppenderFactory(appenderFactory);
}
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java (from r2087, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/SiftingAppender.java Thu Dec 18 22:33:27 2008
@@ -12,6 +12,7 @@
import org.slf4j.MDC;
import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.sift.AppenderTracker;
import ch.qos.logback.core.sift.SiftingAppenderBase;
import ch.qos.logback.core.util.OptionHelper;
@@ -25,7 +26,7 @@
*
* @author Ceki Gulcu
*/
-public class HoardingAppender extends SiftingAppenderBase<LoggingEvent, String> {
+public class SiftingAppender extends SiftingAppenderBase<LoggingEvent, String> {
String mdcKey;
@@ -57,6 +58,10 @@
return mdcValue;
}
}
+
+ AppenderTracker<LoggingEvent, String> getAppenderTracker() {
+ return appenderTracker;
+ }
@Override
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml
==============================================================================
--- /logback/trunk/logback-classic/src/test/input/joran/hoard/completeCycle.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/completeCycle.xml Thu Dec 18 22:33:27 2008
@@ -3,8 +3,8 @@
<configuration debug="true">
- <appender name="HOARD"
- class="ch.qos.logback.classic.hoard.HoardingAppender">
+ <appender name="SIFT"
+ class="ch.qos.logback.classic.sift.SiftingAppender">
<mdcKey>cycle</mdcKey>
<defaultValue>cycleDefault</defaultValue>
@@ -14,7 +14,7 @@
</appender>
<root level="DEBUG">
- <appender-ref ref="HOARD" />
+ <appender-ref ref="SIFT" />
</root>
</configuration>
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml
==============================================================================
--- /logback/trunk/logback-classic/src/test/input/joran/hoard/hoard0.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/hoard0.xml Thu Dec 18 22:33:27 2008
@@ -3,7 +3,7 @@
<configuration debug="true">
- <appender name="HOARD"
+ <appender name="SIFT"
class="ch.qos.logback.classic.hoard.HoardingAppender">
<mdcKey>userid</mdcKey>
@@ -20,7 +20,7 @@
</appender>
<root level="DEBUG">
- <appender-ref ref="HOARD" />
+ <appender-ref ref="SIFT" />
</root>
</configuration>
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml
==============================================================================
--- /logback/trunk/logback-classic/src/test/input/joran/hoard/smoke.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/smoke.xml Thu Dec 18 22:33:27 2008
@@ -3,8 +3,8 @@
<configuration debug="true">
- <appender name="HOARD"
- class="ch.qos.logback.classic.hoard.HoardingAppender">
+ <appender name="SIFT"
+ class="ch.qos.logback.classic.sift.SiftingAppender">
<mdcKey>userid</mdcKey>
<defaultValue>smoke</defaultValue>
@@ -14,7 +14,7 @@
</appender>
<root level="DEBUG">
- <appender-ref ref="HOARD" />
+ <appender-ref ref="SIFT" />
</root>
</configuration>
Modified: logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml
==============================================================================
--- /logback/trunk/logback-classic/src/test/input/joran/hoard/unsetDefaultValueProperty.xml (original)
+++ logback/trunk/logback-classic/src/test/input/joran/sift/unsetDefaultValueProperty.xml Thu Dec 18 22:33:27 2008
@@ -3,17 +3,17 @@
<configuration debug="true">
- <appender name="HOARD"
- class="ch.qos.logback.classic.hoard.HoardingAppender">
+ <appender name="SIFT"
+ class="ch.qos.logback.classic.sift.SiftingAppender">
<mdcKey>userid</mdcKey>
- <hoard>
+ <sift>
<appender name="list-${userid}" class="ch.qos.logback.core.read.ListAppender"/>
- </hoard>
+ </sift>
</appender>
<root level="DEBUG">
- <appender-ref ref="HOARD" />
+ <appender-ref ref="SIFT" />
</root>
</configuration>
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java Thu Dec 18 22:33:27 2008
@@ -36,7 +36,6 @@
suite.addTest(new JUnit4TestAdapter(ch.qos.logback.classic.turbo.PackageTest.class));
suite.addTest(new JUnit4TestAdapter(
ch.qos.logback.classic.sift.PackageTest.class));
-
return suite;
}
}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java Thu Dec 18 22:33:27 2008
@@ -0,0 +1,19 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.sift;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+(a)RunWith(Suite.class)
+(a)SuiteClasses({SiftingAppenderTest.class})
+public class PackageTest {
+}
\ No newline at end of file
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java Thu Dec 18 22:33:27 2008
@@ -0,0 +1,95 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.sift;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.slf4j.MDC;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.classic.util.TeztConstants;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.sift.AppenderTracker;
+import ch.qos.logback.core.util.StatusPrinter;
+
+public class SiftingAppenderTest {
+
+ static String PREFIX = TeztConstants.TEST_DIR_PREFIX + "input/joran/sift/";
+
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void unsetDefaultValueProperty() throws JoranException {
+ configure(PREFIX + "unsetDefaultValueProperty.xml");
+ logger.debug("hello");
+ SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
+ assertFalse(ha.isStarted());
+
+ }
+
+ @Test
+ public void smoke() throws JoranException {
+ configure(PREFIX + "smoke.xml");
+ logger.debug("smoke");
+ long timestamp = 0;
+ SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.getAppenderTracker().get("smoke", timestamp);
+
+ StatusPrinter.print(loggerContext);
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+ }
+
+ @Test
+ public void testWholeCycle() throws JoranException {
+ String mdcKey = "cycle";
+ configure(PREFIX + "completeCycle.xml");
+ MDC.put(mdcKey, "a");
+ logger.debug("smoke");
+ long timestamp = System.currentTimeMillis();
+ SiftingAppender ha = (SiftingAppender) root.getAppender("SIFT");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.getAppenderTracker().get("a", timestamp);
+ StatusPrinter.print(loggerContext);
+
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+
+ MDC.remove(mdcKey);
+ LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null, null);
+ le.setTimeStamp(timestamp+AppenderTracker.THRESHOLD*2);
+ ha.doAppend(le);
+ assertFalse(listAppender.isStarted());
+ assertEquals(1, ha.getAppenderTracker().keyList().size());
+ assertEquals("cycleDefault", ha.getAppenderTracker().keyList().get(0));
+
+ }
+}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java Thu Dec 18 22:33:27 2008
@@ -9,7 +9,6 @@
*/
package ch.qos.logback.core.sift;
-
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -25,10 +24,12 @@
*
* @author Ceki Gulcu
*/
-public abstract class SiftingAppenderBase<E, K> extends UnsynchronizedAppenderBase<E> {
+public abstract class SiftingAppenderBase<E, K> extends
+ UnsynchronizedAppenderBase<E> {
protected AppenderTracker<E, K> appenderTracker = new AppenderTrackerImpl<E, K>();
- //Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String, Appender<LoggingEvent>>();
+ // Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String,
+ // Appender<LoggingEvent>>();
String mdcKey;
String defaultValue;
@@ -41,18 +42,7 @@
@Override
public void start() {
- int errors = 0;
- if (OptionHelper.isEmpty(mdcKey)) {
- errors++;
- addError("The \"mdcKey\" property must be set");
- }
- if (OptionHelper.isEmpty(defaultValue)) {
- errors++;
- addError("The \"defaultValue\" property must be set");
- }
- if (errors == 0) {
- super.start();
- }
+ super.start();
}
@Override
@@ -63,18 +53,18 @@
}
abstract protected K getDiscriminatingValue(E event);
+
abstract protected long getTimestamp(E event);
-
+
@Override
protected void append(E event) {
if (!isStarted()) {
return;
}
-
K value = getDiscriminatingValue(event);
long timestamp = getTimestamp(event);
-
+
Appender<E> appender = appenderTracker.get(value, timestamp);
if (appender == null) {
@@ -108,5 +98,4 @@
return defaultValue;
}
-
}
1
0

svn commit: r2090 - in logback/trunk/logback-core/src: main/java/ch/qos/logback/core/sift test/java/ch/qos/logback/core test/java/ch/qos/logback/core/sift
by noreply.ceki@qos.ch 18 Dec '08
by noreply.ceki@qos.ch 18 Dec '08
18 Dec '08
Author: ceki
Date: Thu Dec 18 22:22:44 2008
New Revision: 2090
Removed:
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/SiftingAppenderTest.java
Modified:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java
Log:
SiftingAppender has been largely made generic by virtue of its migration to lb-core
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java Thu Dec 18 22:22:44 2008
@@ -27,7 +27,7 @@
*/
public abstract class SiftingAppenderBase<E, K> extends UnsynchronizedAppenderBase<E> {
- AppenderTracker<E, K> appenderTracker = new AppenderTrackerImpl<E, K>();
+ protected AppenderTracker<E, K> appenderTracker = new AppenderTrackerImpl<E, K>();
//Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String, Appender<LoggingEvent>>();
String mdcKey;
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java Thu Dec 18 22:22:44 2008
@@ -22,7 +22,8 @@
ch.qos.logback.core.joran.PackageTest.class,
ch.qos.logback.core.appender.PackageTest.class,
ch.qos.logback.core.spi.PackageTest.class,
- ch.qos.logback.core.rolling.PackageTest.class})
+ ch.qos.logback.core.rolling.PackageTest.class,
+ ch.qos.logback.core.sift.PackageTest.class})
public class AllCoreTest {
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java Thu Dec 18 22:22:44 2008
@@ -8,8 +8,6 @@
import org.junit.Before;
import org.junit.Test;
-import ch.qos.logback.classic.sift.AppenderTracker;
-import ch.qos.logback.classic.sift.AppenderTrackerImpl;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.read.ListAppender;
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java Thu Dec 18 22:22:44 2008
@@ -14,6 +14,6 @@
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-(a)SuiteClasses({SiftingAppenderTest.class})
+(a)SuiteClasses({ScenarioBasedAppenderTrackerTest.class})
public class PackageTest {
}
\ No newline at end of file
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java Thu Dec 18 22:22:44 2008
@@ -14,8 +14,6 @@
import org.junit.Ignore;
import org.junit.Test;
-import ch.qos.logback.classic.sift.AppenderTracker;
-
public class ScenarioBasedAppenderTrackerTest {
Simulator simulator;
1
0

svn commit: r2089 - logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift
by noreply.ceki@qos.ch 18 Dec '08
by noreply.ceki@qos.ch 18 Dec '08
18 Dec '08
Author: ceki
Date: Thu Dec 18 22:13:35 2008
New Revision: 2089
Added:
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/SiftingAppenderTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java
Log:
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/AppenderTrackerTest.java Thu Dec 18 22:13:35 2008
@@ -0,0 +1,63 @@
+package ch.qos.logback.core.sift;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.classic.sift.AppenderTracker;
+import ch.qos.logback.classic.sift.AppenderTrackerImpl;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.read.ListAppender;
+
+public class AppenderTrackerTest {
+
+
+ Context context = new ContextBase();
+ AppenderTracker<Object, String> appenderTracker = new AppenderTrackerImpl<Object, String>();
+ ListAppender<Object> la = new ListAppender<Object>();
+
+ @Before
+ public void setUp() {
+ la.setContext(context);
+ la.start();
+ }
+
+
+ @Test
+ public void empty0() {
+ long now = 3000;
+ appenderTracker.stopStaleAppenders(now);
+ assertEquals(0, appenderTracker.keyList().size());
+ }
+
+ @Test
+ public void empty1() {
+ long now = 3000;
+ assertNull(appenderTracker.get("a", now++));
+ now += AppenderTrackerImpl.THRESHOLD+1000;
+ appenderTracker.stopStaleAppenders(now);
+ assertNull(appenderTracker.get("a", now++));
+ }
+
+ @Test
+ public void smoke() {
+ assertTrue(la.isStarted());
+ long now = 3000;
+ appenderTracker.put("a", la, now);
+ assertEquals(la, appenderTracker.get("a", now++));
+ now += AppenderTrackerImpl.THRESHOLD+1000;
+ appenderTracker.stopStaleAppenders(now);
+ assertFalse(la.isStarted());
+ assertNull(appenderTracker.get("a", now++));
+ }
+
+ @Test
+ public void scenarioBased() {
+
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/PackageTest.java Thu Dec 18 22:13:35 2008
@@ -0,0 +1,19 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+(a)RunWith(Suite.class)
+(a)SuiteClasses({SiftingAppenderTest.class})
+public class PackageTest {
+}
\ No newline at end of file
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/ScenarioBasedAppenderTrackerTest.java Thu Dec 18 22:13:35 2008
@@ -0,0 +1,55 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import ch.qos.logback.classic.sift.AppenderTracker;
+
+public class ScenarioBasedAppenderTrackerTest {
+
+ Simulator simulator;
+
+ void verify() {
+ AppenderTracker at = simulator.appenderTracker;
+ AppenderTracker t_at = simulator.t_appenderTracker;
+ //List<String> resultKeys = at.keyList();
+ //List<String> witnessKeys = t_at.keyList();
+ assertEquals(t_at.keyList(), at.keyList());
+ }
+
+ @Test
+ public void shortTest() {
+ simulator = new Simulator(20, AppenderTracker.THRESHOLD / 2);
+ simulator.buildScenario(200);
+ simulator.simulate();
+ verify();
+ }
+
+ @Test
+ public void mediumTest() {
+ simulator = new Simulator(100, AppenderTracker.THRESHOLD / 2);
+ simulator.buildScenario(20000);
+ simulator.simulate();
+ verify();
+ }
+
+ @Test
+ @Ignore
+ public void longetTest() {
+ simulator = new Simulator(100, AppenderTracker.THRESHOLD / 200);
+ simulator.buildScenario(2000000);
+ simulator.simulate();
+ verify();
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/SiftingAppenderTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/SiftingAppenderTest.java Thu Dec 18 22:13:35 2008
@@ -0,0 +1,96 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.slf4j.MDC;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.sift.AppenderTracker;
+import ch.qos.logback.classic.sift.HoardingAppender;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.classic.util.TeztConstants;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.util.StatusPrinter;
+
+public class SiftingAppenderTest {
+
+ static String PREFIX = TeztConstants.TEST_DIR_PREFIX + "input/joran/hoard/";
+
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void unsetDefaultValueProperty() throws JoranException {
+ configure(PREFIX + "unsetDefaultValueProperty.xml");
+ logger.debug("hello");
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ assertFalse(ha.isStarted());
+
+ }
+
+ @Test
+ public void smoke() throws JoranException {
+ configure(PREFIX + "smoke.xml");
+ logger.debug("smoke");
+ long timestamp = 0;
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.appenderTracker.get("smoke", timestamp);
+
+ StatusPrinter.print(loggerContext);
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+ }
+
+ @Test
+ public void testWholeCycle() throws JoranException {
+ String mdcKey = "cycle";
+ configure(PREFIX + "completeCycle.xml");
+ MDC.put(mdcKey, "a");
+ logger.debug("smoke");
+ long timestamp = System.currentTimeMillis();
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.appenderTracker.get("a", timestamp);
+ StatusPrinter.print(loggerContext);
+
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+
+ MDC.remove(mdcKey);
+ LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null, null);
+ le.setTimeStamp(timestamp+AppenderTracker.THRESHOLD*2);
+ ha.doAppend(le);
+ assertFalse(listAppender.isStarted());
+ assertEquals(1, ha.appenderTracker.keyList().size());
+ assertEquals("cycleDefault", ha.appenderTracker.keyList().get(0));
+
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/Simulator.java Thu Dec 18 22:13:35 2008
@@ -0,0 +1,92 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.appender.NOPAppender;
+import ch.qos.logback.core.sift.tracker.AppenderTrackerTImpl;
+import ch.qos.logback.core.sift.tracker.SimulationEvent;
+
+/**
+ * Simulate use of AppenderTracker by HoardAppender.
+ *
+ * @author ceki
+ *
+ */
+public class Simulator {
+
+ AppenderTrackerImpl<Object, String> appenderTracker = new AppenderTrackerImpl<Object, String>();
+ AppenderTrackerTImpl t_appenderTracker = new AppenderTrackerTImpl();
+
+ List<String> keySpace = new ArrayList<String>();
+ List<SimulationEvent> scenario = new ArrayList<SimulationEvent>();
+ Random randomKeyGen = new Random(100);
+
+ Random random = new Random(11234);
+
+ final int maxTimestampInc;
+ long timestamp = 30000;
+
+ Simulator(int keySpaceLen, int maxTimestampInc) {
+ this.maxTimestampInc = maxTimestampInc;
+ Map<String, String> checkMap = new HashMap<String, String>();
+ for (int i = 0; i < keySpaceLen; i++) {
+ String k = getRandomKeyStr();
+ if (checkMap.containsKey(k)) {
+ System.out.println("random key collision occured");
+ k += "" + i;
+ }
+ keySpace.add(k);
+ checkMap.put(k, k);
+ }
+
+ }
+
+ private String getRandomKeyStr() {
+ int ri = randomKeyGen.nextInt();
+ String s = String.format("%X", ri);
+ return s;
+ }
+
+ void buildScenario(int simLen) {
+ int keySpaceLen = keySpace.size();
+ for (int i = 0; i < simLen; i++) {
+ int index = random.nextInt(keySpaceLen);
+ timestamp += random.nextInt(maxTimestampInc);
+ String key = keySpace.get(index);
+ scenario.add(new SimulationEvent(key, timestamp));
+ }
+ }
+
+ public void simulate() {
+ for (SimulationEvent simeEvent : scenario) {
+ play(simeEvent, appenderTracker);
+ play(simeEvent, t_appenderTracker);
+ }
+ }
+
+ void play(SimulationEvent simulationEvent,
+ AppenderTracker<Object, String> appenderTracker) {
+ String mdcValue = simulationEvent.key;
+ long timestamp = simulationEvent.timestamp;
+ Appender<Object> appender = appenderTracker.get(mdcValue, timestamp);
+ if (appender == null) {
+ appender = new NOPAppender<Object>();
+ appenderTracker.put(mdcValue, appender, timestamp);
+ }
+ appenderTracker.stopStaleAppenders(timestamp);
+ }
+}
1
0

svn commit: r2088 - logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker
by noreply.ceki@qos.ch 18 Dec '08
by noreply.ceki@qos.ch 18 Dec '08
18 Dec '08
Author: ceki
Date: Thu Dec 18 22:12:54 2008
New Revision: 2088
Added:
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/SimulationEvent.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/TEntry.java
Log:
heavy refactorization
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/AppenderTrackerTImpl.java Thu Dec 18 22:12:54 2008
@@ -0,0 +1,98 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift.tracker;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.sift.AppenderTracker;
+
+/**
+ * This is an alternative (slower) implementation of AppenderTracker for testing
+ * purposes.
+ *
+ * @author Ceki Gulcu
+ */
+public class AppenderTrackerTImpl implements AppenderTracker<Object, String> {
+
+ List<TEntry> entryList = new LinkedList<TEntry>();
+ long lastCheck = 0;
+
+ public AppenderTrackerTImpl() {
+ }
+
+ @SuppressWarnings("unchecked")
+ synchronized public void put(String k, Appender<Object> appender,
+ long timestamp) {
+ TEntry te = getEntry(k);
+ if (te != null) {
+ te.timestamp = timestamp;
+ } else {
+ te = new TEntry(k, appender, timestamp);
+ entryList.add(te);
+ }
+ Collections.sort(entryList);
+ }
+
+ @SuppressWarnings("unchecked")
+ synchronized public Appender<Object> get(String k, long timestamp) {
+ TEntry te = getEntry(k);
+ if (te == null) {
+ return null;
+ } else {
+ te.timestamp = timestamp;
+ Collections.sort(entryList);
+ return te.appender;
+ }
+ }
+
+ synchronized public void stopStaleAppenders(long timestamp) {
+ if (lastCheck + MILLIS_IN_ONE_SECOND > timestamp) {
+ return;
+ }
+ lastCheck = timestamp;
+ while (entryList.size() != 0 && isEntryStale(entryList.get(0), timestamp)) {
+ entryList.remove(0);
+ }
+ }
+
+ final private boolean isEntryStale(TEntry entry, long now) {
+ return ((entry.timestamp + THRESHOLD) < now);
+ }
+
+ synchronized public List<String> keyList() {
+ List<String> keyList = new ArrayList<String>();
+ for (TEntry e : entryList) {
+ keyList.add(e.key);
+ }
+ return keyList;
+ }
+
+ synchronized public List<Appender<Object>> valueList() {
+ List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
+ for (TEntry e : entryList) {
+ appenderList.add(e.appender);
+ }
+ return appenderList;
+ }
+
+ private TEntry getEntry(String k) {
+ for (int i = 0; i < entryList.size(); i++) {
+ TEntry te = entryList.get(i);
+ if (te.key.equals(k)) {
+ return te;
+ }
+ }
+ return null;
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/SimulationEvent.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/SimulationEvent.java Thu Dec 18 22:12:54 2008
@@ -0,0 +1,17 @@
+package ch.qos.logback.core.sift.tracker;
+
+
+public class SimulationEvent {
+
+ public String key;
+ public long timestamp;
+
+ public SimulationEvent(String key, long timestamp) {
+ this.key = key;
+ this.timestamp = timestamp;
+ }
+
+ public String toString() {
+ return "Event: k=" + key +", timestamp=" + timestamp;
+ }
+}
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/TEntry.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/tracker/TEntry.java Thu Dec 18 22:12:54 2008
@@ -0,0 +1,45 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift.tracker;
+
+import ch.qos.logback.core.Appender;
+
+public class TEntry implements Comparable {
+
+ String key;
+ long timestamp;
+ Appender<Object> appender;
+
+ TEntry(String key, Appender<Object> appender, long timestamp) {
+ this.key = key;
+ this.appender = appender;
+ this.timestamp = timestamp;
+ }
+
+ public int compareTo(Object o) {
+ if(!(o instanceof TEntry)) {
+ throw new IllegalArgumentException("arguments must be of type "+TEntry.class);
+ }
+
+ TEntry other = (TEntry) o;
+ if(timestamp > other.timestamp) {
+ return 1;
+ }
+ if(timestamp == other.timestamp) {
+ return 0;
+ }
+ return -1;
+ }
+
+ @Override
+ public String toString() {
+ return "("+key+","+timestamp+")";
+ }
+}
1
0

18 Dec '08
Author: ceki
Date: Thu Dec 18 22:11:36 2008
New Revision: 2087
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
- copied, changed from r2086, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java
- copied, changed from r2086, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/sift/
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTracker.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTrackerImpl.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
Log:
- heavy refactorization of SiftingAppender
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java Thu Dec 18 22:11:36 2008
@@ -1,49 +1,33 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.sift;
-import java.util.ArrayList;
import java.util.List;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.core.Appender;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.event.SaxEvent;
-import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.util.StatusPrinter;
+import ch.qos.logback.core.sift.AppenderFactoryBase;
+import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
-public class AppenderFactory {
+public class AppenderFactory extends AppenderFactoryBase<LoggingEvent, String>{
- final List<SaxEvent> eventList;
- Context context;
+ String mdcKey;
- AppenderFactory(Context context, List<SaxEvent> eventList) {
- this.context = context;
- this.eventList = new ArrayList<SaxEvent>(eventList);
- removeHoardElement();
-
- }
-
- void removeHoardElement() {
- eventList.remove(0);
- eventList.remove(eventList.size() - 1);
- System.out.println(eventList);
- }
-
- Appender<LoggingEvent> buildAppender(Context context, String mdcKey,
- String mdcValue) throws JoranException {
- //HoardingContext hoardingContext = new HoardingContext(context, mdcKey,
- // mdcValue);
- HoardingJoranConfigurator hjc = new HoardingJoranConfigurator(mdcKey, mdcValue);
- hjc.setContext(context);
-
- hjc.doConfigure(eventList);
-
- StatusPrinter.print(context);
-
- return hjc.getAppender();
+ AppenderFactory(Context context, List<SaxEvent> eventList, String mdcKey) {
+ super(context, eventList);
+ this.mdcKey = mdcKey;
}
- public List<SaxEvent> getEventList() {
- return eventList;
+ public SiftingJoranConfiguratorBase<LoggingEvent> getSiftingJoranConfigurator(String k) {
+ return new HoardingJoranConfigurator(mdcKey, k);
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java Thu Dec 18 22:11:36 2008
@@ -27,7 +27,7 @@
Object o = ec.peekObject();
if (o instanceof HoardingAppender) {
HoardingAppender ha = (HoardingAppender) o;
- AppenderFactory appenderFactory = new AppenderFactory(context, seList);
+ AppenderFactory appenderFactory = new AppenderFactory(context, seList, ha.getMdcKey());
ha.setAppenderFactory(appenderFactory);
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java Thu Dec 18 22:11:36 2008
@@ -12,9 +12,7 @@
import org.slf4j.MDC;
import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.UnsynchronizedAppenderBase;
-import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.sift.SiftingAppenderBase;
import ch.qos.logback.core.util.OptionHelper;
/**
@@ -27,19 +25,12 @@
*
* @author Ceki Gulcu
*/
-public class HoardingAppender extends UnsynchronizedAppenderBase<LoggingEvent> {
+public class HoardingAppender extends SiftingAppenderBase<LoggingEvent, String> {
- AppenderTracker<LoggingEvent> appenderTracker = new AppenderTrackerImpl<LoggingEvent>();
- //Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String, Appender<LoggingEvent>>();
String mdcKey;
String defaultValue;
- AppenderFactory appenderFactory;
-
- void setAppenderFactory(AppenderFactory appenderFactory) {
- this.appenderFactory = appenderFactory;
- }
@Override
public void start() {
@@ -58,43 +49,22 @@
}
@Override
- public void stop() {
- for (Appender<LoggingEvent> appender : appenderTracker.valueList()) {
- appender.stop();
- }
- }
-
- @Override
- protected void append(LoggingEvent loggingEvent) {
- if (!isStarted()) {
- return;
- }
-
+ protected String getDiscriminatingValue(LoggingEvent event) {
String mdcValue = MDC.get(mdcKey);
-
if (mdcValue == null) {
- mdcValue = defaultValue;
+ return defaultValue;
+ } else {
+ return mdcValue;
}
+ }
- long timestamp = loggingEvent.getTimeStamp();
-
- Appender<LoggingEvent> appender = appenderTracker.get(mdcValue, timestamp);
-
- if (appender == null) {
- try {
- appender = appenderFactory.buildAppender(context, mdcKey, mdcValue);
- if (appender != null) {
- appenderTracker.put(mdcValue, appender, timestamp);
- }
- } catch (JoranException e) {
- addError("Failed to build appender for " + mdcKey + "=" + mdcValue, e);
- return;
- }
- }
- appenderTracker.stopStaleAppenders(timestamp);
- appender.doAppend(loggingEvent);
+
+ @Override
+ protected long getTimestamp(LoggingEvent event) {
+ return event.getTimeStamp();
}
+
public String getMdcKey() {
return mdcKey;
}
@@ -127,4 +97,6 @@
this.defaultValue = defaultValue;
}
+
+
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java Thu Dec 18 22:11:36 2008
@@ -6,16 +6,13 @@
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.joran.GenericConfigurator;
import ch.qos.logback.core.joran.action.ActionConst;
import ch.qos.logback.core.joran.action.AppenderAction;
-import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
-import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
-import ch.qos.logback.core.joran.spi.Interpreter;
import ch.qos.logback.core.joran.spi.Pattern;
import ch.qos.logback.core.joran.spi.RuleStore;
+import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
-public class HoardingJoranConfigurator extends GenericConfigurator {
+public class HoardingJoranConfigurator extends SiftingJoranConfiguratorBase<LoggingEvent> {
String key;
String value;
@@ -24,23 +21,13 @@
this.key = key;
this.value = value;
}
+
@Override
protected Pattern initialPattern() {
return new Pattern("configuration");
}
@Override
- protected void addImplicitRules(Interpreter interpreter) {
- NestedComplexPropertyIA nestedComplexIA = new NestedComplexPropertyIA();
- nestedComplexIA.setContext(context);
- interpreter.addImplicitAction(nestedComplexIA);
-
- NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA();
- nestedSimpleIA.setContext(context);
- interpreter.addImplicitAction(nestedSimpleIA);
- }
-
- @Override
protected void addInstanceRules(RuleStore rs) {
rs.addRule(new Pattern("configuration/appender"), new AppenderAction());
}
Copied: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java (from r2086, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java)
==============================================================================
--- /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java Thu Dec 18 22:11:36 2008
@@ -1,3 +1,12 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
import java.util.ArrayList;
@@ -8,12 +17,12 @@
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.JoranException;
-public abstract class AppenderFactory<E, K> {
+public abstract class AppenderFactoryBase<E, K> {
final List<SaxEvent> eventList;
Context context;
- AppenderFactory(Context context, List<SaxEvent> eventList) {
+ protected AppenderFactoryBase(Context context, List<SaxEvent> eventList) {
this.context = context;
this.eventList = new ArrayList<SaxEvent>(eventList);
removeHoardElement();
@@ -26,11 +35,10 @@
System.out.println(eventList);
}
-
- abstract SiftingJoranConfigurator<E> getSiftingJoranConfigurator(K k);
+ public abstract SiftingJoranConfiguratorBase<E> getSiftingJoranConfigurator(K k);
Appender<E> buildAppender(Context context, K k) throws JoranException {
- SiftingJoranConfigurator<E> sjc = getSiftingJoranConfigurator(k);
+ SiftingJoranConfiguratorBase<E> sjc = getSiftingJoranConfigurator(k);
sjc.setContext(context);
sjc.doConfigure(eventList);
return sjc.getAppender();
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java Thu Dec 18 22:11:36 2008
@@ -19,7 +19,7 @@
static int THRESHOLD = 30 * 60 * MILLIS_IN_ONE_SECOND; // 30 minutes
void put(K key, Appender<E> value, long timestamp);
- Appender<E> get(String key, long timestamp);
+ Appender<E> get(K key, long timestamp);
void stopStaleAppenders(long timestamp);
List<K> keyList();
List<Appender<E>> valueList();
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java Thu Dec 18 22:11:36 2008
@@ -45,7 +45,7 @@
moveToTail(entry);
}
- public synchronized Appender<E> get(String key, long timestamp) {
+ public synchronized Appender<E> get(K key, long timestamp) {
Entry existing = map.get(key);
if (existing == null) {
return null;
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java Thu Dec 18 22:11:36 2008
@@ -33,9 +33,9 @@
String mdcKey;
String defaultValue;
- AppenderFactory<E, K> appenderFactory;
+ AppenderFactoryBase<E, K> appenderFactory;
- void setAppenderFactory(AppenderFactory<E, K> appenderFactory) {
+ public void setAppenderFactory(AppenderFactoryBase<E, K> appenderFactory) {
this.appenderFactory = appenderFactory;
}
Copied: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java (from r2086, /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java)
==============================================================================
--- /logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfiguratorBase.java Thu Dec 18 22:11:36 2008
@@ -2,22 +2,22 @@
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.joran.GenericConfigurator;
+import ch.qos.logback.core.joran.action.NestedBasicPropertyIA;
+import ch.qos.logback.core.joran.action.NestedComplexPropertyIA;
import ch.qos.logback.core.joran.spi.Interpreter;
-import ch.qos.logback.core.joran.spi.RuleStore;
-public abstract class SiftingJoranConfigurator<E> extends GenericConfigurator {
+public abstract class SiftingJoranConfiguratorBase<E> extends GenericConfigurator {
@Override
protected void addImplicitRules(Interpreter interpreter) {
- // TODO Auto-generated method stub
+ NestedComplexPropertyIA nestedComplexIA = new NestedComplexPropertyIA();
+ nestedComplexIA.setContext(context);
+ interpreter.addImplicitAction(nestedComplexIA);
+ NestedBasicPropertyIA nestedSimpleIA = new NestedBasicPropertyIA();
+ nestedSimpleIA.setContext(context);
+ interpreter.addImplicitAction(nestedSimpleIA);
}
-
- @Override
- protected void addInstanceRules(RuleStore rs) {
- // TODO Auto-generated method stub
-
- }
-
- abstract Appender<E> getAppender();
+
+ abstract public Appender<E> getAppender();
}
1
0

svn commit: r2086 - logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift
by noreply.ceki@qos.ch 18 Dec '08
by noreply.ceki@qos.ch 18 Dec '08
18 Dec '08
Author: ceki
Date: Thu Dec 18 21:48:23 2008
New Revision: 2086
Added:
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java
Log:
- migrating SiftingAppender to logback-core from logback-classic
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactory.java Thu Dec 18 21:48:23 2008
@@ -0,0 +1,43 @@
+package ch.qos.logback.core.sift;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.joran.event.SaxEvent;
+import ch.qos.logback.core.joran.spi.JoranException;
+
+public abstract class AppenderFactory<E, K> {
+
+ final List<SaxEvent> eventList;
+ Context context;
+
+ AppenderFactory(Context context, List<SaxEvent> eventList) {
+ this.context = context;
+ this.eventList = new ArrayList<SaxEvent>(eventList);
+ removeHoardElement();
+
+ }
+
+ void removeHoardElement() {
+ eventList.remove(0);
+ eventList.remove(eventList.size() - 1);
+ System.out.println(eventList);
+ }
+
+
+ abstract SiftingJoranConfigurator<E> getSiftingJoranConfigurator(K k);
+
+ Appender<E> buildAppender(Context context, K k) throws JoranException {
+ SiftingJoranConfigurator<E> sjc = getSiftingJoranConfigurator(k);
+ sjc.setContext(context);
+ sjc.doConfigure(eventList);
+ return sjc.getAppender();
+ }
+
+ public List<SaxEvent> getEventList() {
+ return eventList;
+ }
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTracker.java Thu Dec 18 21:48:23 2008
@@ -0,0 +1,28 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+import java.util.List;
+
+import ch.qos.logback.core.Appender;
+
+public interface AppenderTracker<E, K> {
+
+ static int MILLIS_IN_ONE_SECOND = 1000;
+ static int THRESHOLD = 30 * 60 * MILLIS_IN_ONE_SECOND; // 30 minutes
+
+ void put(K key, Appender<E> value, long timestamp);
+ Appender<E> get(String key, long timestamp);
+ void stopStaleAppenders(long timestamp);
+ List<K> keyList();
+ List<Appender<E>> valueList();
+
+
+}
\ No newline at end of file
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderTrackerImpl.java Thu Dec 18 21:48:23 2008
@@ -0,0 +1,207 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import ch.qos.logback.core.Appender;
+
+/**
+ * Track appenders by a key. When an appender is not used for
+ * longer than THRESHOLD, stop it.
+ * @author Ceki Gulcu
+ */
+public class AppenderTrackerImpl<E, K> implements AppenderTracker<E, K> {
+
+ Map<K, Entry> map = new HashMap<K, Entry>();
+
+ Entry head; // least recently used entries are towards the head
+ Entry tail; // most recently used entries are towards the tail
+
+ long lastCheck = 0;
+
+ AppenderTrackerImpl() {
+ head = new Entry(null, null, 0);
+ tail = head;
+ }
+
+
+ public synchronized void put(K key, Appender<E> value, long timestamp) {
+ Entry entry = map.get(key);
+ if (entry == null) {
+ entry = new Entry(key, value, timestamp);
+ map.put(key, entry);
+ }
+ moveToTail(entry);
+ }
+
+ public synchronized Appender<E> get(String key, long timestamp) {
+ Entry existing = map.get(key);
+ if (existing == null) {
+ return null;
+ } else {
+ existing.setTimestamp(timestamp);
+ moveToTail(existing);
+ return existing.value;
+ }
+ }
+
+
+ public synchronized void stopStaleAppenders(long now) {
+ if (lastCheck + MILLIS_IN_ONE_SECOND > now) {
+ return;
+ }
+ lastCheck = now;
+ while (head.value != null && isEntryStale(head,now)) {
+ Appender appender = head.value;
+ //System.out.println(" stopping "+appender);
+ appender.stop();
+ removeHead();
+ }
+ }
+
+ public List<K> keyList() {
+ List<K> result = new LinkedList<K>();
+ Entry e = head;
+ while (e != tail) {
+ result.add(e.key);
+ e = e.next;
+ }
+ return result;
+ }
+
+
+ final private boolean isEntryStale(Entry entry, long now) {
+ return ((entry.timestamp + THRESHOLD) < now);
+ }
+
+
+ private void removeHead() {
+ // System.out.println("RemoveHead called");
+ map.remove(head.key);
+ head = head.next;
+ head.prev = null;
+ }
+
+ private void moveToTail(Entry e) {
+ rearrangePreexistingLinks(e);
+ rearrangeTailLinks(e);
+ }
+
+ private void rearrangePreexistingLinks(Entry e) {
+ if (e.prev != null) {
+ e.prev.next = e.next;
+ }
+ if (e.next != null) {
+ e.next.prev = e.prev;
+ }
+ if (head == e) {
+ head = e.next;
+ }
+ }
+
+ private void rearrangeTailLinks(Entry e) {
+ if (head == tail) {
+ head = e;
+ }
+ Entry preTail = tail.prev;
+ if (preTail != null) {
+ preTail.next = e;
+ }
+ e.prev = preTail;
+ e.next = tail;
+ tail.prev = e;
+ }
+
+ public void dump() {
+ Entry e = head;
+ System.out.print("N:");
+ while (e != null) {
+ // System.out.print(e+"->");
+ System.out.print(e.key + ", ");
+ e = e.next;
+ }
+ System.out.println();
+ }
+
+
+
+ public List<Appender<E>> valueList() {
+ List<Appender<E>> result = new LinkedList<Appender<E>>();
+ Entry e = head;
+ while (e != tail) {
+ result.add(e.value);
+ e = e.next;
+ }
+ return result;
+ }
+
+ // ================================================================
+ private class Entry {
+ Entry next;
+ Entry prev;
+
+ K key;
+ Appender<E> value;
+ long timestamp;
+
+ Entry(K k, Appender<E> v, long timestamp) {
+ this.key = k;
+ this.value = v;
+ this.timestamp = timestamp;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Entry other = (Entry) obj;
+ if (key == null) {
+ if (other.key != null)
+ return false;
+ } else if (!key.equals(other.key))
+ return false;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + key + ", " + value + ")";
+ }
+ }
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingAppenderBase.java Thu Dec 18 21:48:23 2008
@@ -0,0 +1,112 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.sift;
+
+
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.UnsynchronizedAppenderBase;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.util.OptionHelper;
+
+/**
+ * This appender can contains other appenders which it can build dynamically
+ * depending on MDC values. The built appender is specified as part of a
+ * configuration file.
+ *
+ * <p>See the logback manual for further details.
+ *
+ *
+ * @author Ceki Gulcu
+ */
+public abstract class SiftingAppenderBase<E, K> extends UnsynchronizedAppenderBase<E> {
+
+ AppenderTracker<E, K> appenderTracker = new AppenderTrackerImpl<E, K>();
+ //Map<String, Appender<LoggingEvent>> appenderMap = new Hashtable<String, Appender<LoggingEvent>>();
+
+ String mdcKey;
+ String defaultValue;
+
+ AppenderFactory<E, K> appenderFactory;
+
+ void setAppenderFactory(AppenderFactory<E, K> appenderFactory) {
+ this.appenderFactory = appenderFactory;
+ }
+
+ @Override
+ public void start() {
+ int errors = 0;
+ if (OptionHelper.isEmpty(mdcKey)) {
+ errors++;
+ addError("The \"mdcKey\" property must be set");
+ }
+ if (OptionHelper.isEmpty(defaultValue)) {
+ errors++;
+ addError("The \"defaultValue\" property must be set");
+ }
+ if (errors == 0) {
+ super.start();
+ }
+ }
+
+ @Override
+ public void stop() {
+ for (Appender<E> appender : appenderTracker.valueList()) {
+ appender.stop();
+ }
+ }
+
+ abstract protected K getDiscriminatingValue(E event);
+ abstract protected long getTimestamp(E event);
+
+ @Override
+ protected void append(E event) {
+ if (!isStarted()) {
+ return;
+ }
+
+
+ K value = getDiscriminatingValue(event);
+ long timestamp = getTimestamp(event);
+
+ Appender<E> appender = appenderTracker.get(value, timestamp);
+
+ if (appender == null) {
+ try {
+ appender = appenderFactory.buildAppender(context, value);
+ if (appender != null) {
+ appenderTracker.put(value, appender, timestamp);
+ }
+ } catch (JoranException e) {
+ addError("Failed to build appender for [" + value + "]", e);
+ return;
+ }
+ }
+ appenderTracker.stopStaleAppenders(timestamp);
+ appender.doAppend(event);
+ }
+
+ public String getMdcKey() {
+ return mdcKey;
+ }
+
+ public void setMdcKey(String mdcKey) {
+ this.mdcKey = mdcKey;
+ }
+
+ /**
+ * @see #setDefaultValue(String)
+ * @return
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+
+}
Added: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/sift/SiftingJoranConfigurator.java Thu Dec 18 21:48:23 2008
@@ -0,0 +1,23 @@
+package ch.qos.logback.core.sift;
+
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.joran.GenericConfigurator;
+import ch.qos.logback.core.joran.spi.Interpreter;
+import ch.qos.logback.core.joran.spi.RuleStore;
+
+public abstract class SiftingJoranConfigurator<E> extends GenericConfigurator {
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ // TODO Auto-generated method stub
+
+ }
+
+ abstract Appender<E> getAppender();
+}
1
0

18 Dec '08
Author: ceki
Date: Thu Dec 18 21:15:43 2008
New Revision: 2085
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/
- copied from r2079, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderFactory.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTracker.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderTracker.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTrackerImpl.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderTrackerImpl.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardAction.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingAppender.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingJoranConfigurator.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/AppenderTrackerTest.java
- copied, changed from r2084, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java
- copied, changed from r2082, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/PackageTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/ScenarioBasedAppenderTrackerTest.java
- copied, changed from r2082, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/ScenarioBasedAppenderTrackerTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/Simulator.java
- copied, changed from r2082, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/Simulator.java
Removed:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/PackageTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/ScenarioBasedAppenderTrackerTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/Simulator.java
Modified:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/tracker/AppenderTrackerTImpl.java
Log:
Renamed HoardingAppender as SiftingAppender
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java Thu Dec 18 21:15:43 2008
@@ -10,7 +10,6 @@
package ch.qos.logback.classic.joran;
-import ch.qos.logback.classic.hoard.HoardAction;
import ch.qos.logback.classic.joran.action.ConfigurationAction;
import ch.qos.logback.classic.joran.action.ConsolePluginAction;
import ch.qos.logback.classic.joran.action.ContextNameAction;
@@ -21,6 +20,7 @@
import ch.qos.logback.classic.joran.action.LevelAction;
import ch.qos.logback.classic.joran.action.LoggerAction;
import ch.qos.logback.classic.joran.action.RootLoggerAction;
+import ch.qos.logback.classic.sift.HoardAction;
import ch.qos.logback.classic.spi.PlatformInfo;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
import ch.qos.logback.core.joran.action.AppenderRefAction;
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java (from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderFactory.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderFactory.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderFactory.java Thu Dec 18 21:15:43 2008
@@ -1,4 +1,4 @@
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import java.util.ArrayList;
import java.util.List;
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTracker.java (from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderTracker.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderTracker.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTracker.java Thu Dec 18 21:15:43 2008
@@ -1,4 +1,4 @@
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import java.util.List;
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTrackerImpl.java (from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderTrackerImpl.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/AppenderTrackerImpl.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/AppenderTrackerImpl.java Thu Dec 18 21:15:43 2008
@@ -7,7 +7,7 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import java.util.HashMap;
import java.util.LinkedList;
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java (from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardAction.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardAction.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardAction.java Thu Dec 18 21:15:43 2008
@@ -1,4 +1,4 @@
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import java.util.ArrayList;
import java.util.List;
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java (from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingAppender.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingAppender.java Thu Dec 18 21:15:43 2008
@@ -7,7 +7,7 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import org.slf4j.MDC;
Copied: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java (from r2084, /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingJoranConfigurator.java)
==============================================================================
--- /logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/hoard/HoardingJoranConfigurator.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/sift/HoardingJoranConfigurator.java Thu Dec 18 21:15:43 2008
@@ -1,4 +1,4 @@
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import java.util.Collection;
import java.util.HashMap;
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java Thu Dec 18 21:15:43 2008
@@ -35,7 +35,7 @@
suite.addTest(ch.qos.logback.classic.spi.PackageTest.suite());
suite.addTest(new JUnit4TestAdapter(ch.qos.logback.classic.turbo.PackageTest.class));
suite.addTest(new JUnit4TestAdapter(
- ch.qos.logback.classic.hoard.PackageTest.class));
+ ch.qos.logback.classic.sift.PackageTest.class));
return suite;
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/tracker/AppenderTrackerTImpl.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/tracker/AppenderTrackerTImpl.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/tracker/AppenderTrackerTImpl.java Thu Dec 18 21:15:43 2008
@@ -14,7 +14,7 @@
import java.util.LinkedList;
import java.util.List;
-import ch.qos.logback.classic.hoard.AppenderTracker;
+import ch.qos.logback.classic.sift.AppenderTracker;
import ch.qos.logback.core.Appender;
/**
Copied: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/AppenderTrackerTest.java (from r2084, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java)
==============================================================================
--- /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/AppenderTrackerTest.java Thu Dec 18 21:15:43 2008
@@ -1,4 +1,4 @@
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -8,6 +8,8 @@
import org.junit.Before;
import org.junit.Test;
+import ch.qos.logback.classic.sift.AppenderTracker;
+import ch.qos.logback.classic.sift.AppenderTrackerImpl;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.ContextBase;
import ch.qos.logback.core.read.ListAppender;
Copied: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java (from r2082, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/PackageTest.java)
==============================================================================
--- /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/PackageTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/PackageTest.java Thu Dec 18 21:15:43 2008
@@ -7,13 +7,13 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-(a)SuiteClasses({HoardingAppenderTest.class})
+(a)SuiteClasses({SiftingAppenderTest.class})
public class PackageTest {
}
\ No newline at end of file
Copied: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/ScenarioBasedAppenderTrackerTest.java (from r2082, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/ScenarioBasedAppenderTrackerTest.java)
==============================================================================
--- /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/ScenarioBasedAppenderTrackerTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/ScenarioBasedAppenderTrackerTest.java Thu Dec 18 21:15:43 2008
@@ -7,13 +7,15 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import static org.junit.Assert.assertEquals;
import org.junit.Ignore;
import org.junit.Test;
+import ch.qos.logback.classic.sift.AppenderTracker;
+
public class ScenarioBasedAppenderTrackerTest {
Simulator simulator;
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java Thu Dec 18 21:15:43 2008
@@ -0,0 +1,96 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.sift;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.slf4j.MDC;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.classic.sift.AppenderTracker;
+import ch.qos.logback.classic.sift.HoardingAppender;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.classic.util.TeztConstants;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.util.StatusPrinter;
+
+public class SiftingAppenderTest {
+
+ static String PREFIX = TeztConstants.TEST_DIR_PREFIX + "input/joran/hoard/";
+
+ LoggerContext loggerContext = new LoggerContext();
+ Logger logger = loggerContext.getLogger(this.getClass().getName());
+ Logger root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
+
+ void configure(String file) throws JoranException {
+ JoranConfigurator jc = new JoranConfigurator();
+ jc.setContext(loggerContext);
+ jc.doConfigure(file);
+ }
+
+ @Test
+ public void unsetDefaultValueProperty() throws JoranException {
+ configure(PREFIX + "unsetDefaultValueProperty.xml");
+ logger.debug("hello");
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ assertFalse(ha.isStarted());
+
+ }
+
+ @Test
+ public void smoke() throws JoranException {
+ configure(PREFIX + "smoke.xml");
+ logger.debug("smoke");
+ long timestamp = 0;
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.appenderTracker.get("smoke", timestamp);
+
+ StatusPrinter.print(loggerContext);
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+ }
+
+ @Test
+ public void testWholeCycle() throws JoranException {
+ String mdcKey = "cycle";
+ configure(PREFIX + "completeCycle.xml");
+ MDC.put(mdcKey, "a");
+ logger.debug("smoke");
+ long timestamp = System.currentTimeMillis();
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.appenderTracker.get("a", timestamp);
+ StatusPrinter.print(loggerContext);
+
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+
+ MDC.remove(mdcKey);
+ LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null, null);
+ le.setTimeStamp(timestamp+AppenderTracker.THRESHOLD*2);
+ ha.doAppend(le);
+ assertFalse(listAppender.isStarted());
+ assertEquals(1, ha.appenderTracker.keyList().size());
+ assertEquals("cycleDefault", ha.appenderTracker.keyList().get(0));
+
+ }
+}
Copied: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/Simulator.java (from r2082, /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/Simulator.java)
==============================================================================
--- /logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/Simulator.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/sift/Simulator.java Thu Dec 18 21:15:43 2008
@@ -7,7 +7,7 @@
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
-package ch.qos.logback.classic.hoard;
+package ch.qos.logback.classic.sift;
import java.util.ArrayList;
import java.util.HashMap;
@@ -17,6 +17,8 @@
import ch.qos.logback.classic.hoard.tracker.SimulationEvent;
import ch.qos.logback.classic.hoard.tracker.AppenderTrackerTImpl;
+import ch.qos.logback.classic.sift.AppenderTracker;
+import ch.qos.logback.classic.sift.AppenderTrackerImpl;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.appender.NOPAppender;
1
0
Author: ceki
Date: Thu Dec 18 21:11:24 2008
New Revision: 2084
Added:
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
logback/trunk/logback-classic/src/test/input/joran/hoard/completeCycle.xml
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java
Modified:
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
Log:
- added DuplicateMessageFilter
- BasicStatusMessages's internal buffer now has two parts, the head part and the tail part.
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/DuplicateMessageFilter.java Thu Dec 18 21:11:24 2008
@@ -0,0 +1,68 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.turbo;
+
+import org.slf4j.Marker;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.core.spi.FilterReply;
+
+public class DuplicateMessageFilter extends TurboFilter {
+
+ static final int DEFAULT_CACHE_SIZE = 100;
+ static final int DEFAULT_ALLOWED_REPETITIONS = 5;
+
+ public int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;
+ public int cacheSize = DEFAULT_CACHE_SIZE;
+
+ private LRUMessageCache msgCache;
+
+ @Override
+ public void start() {
+ msgCache = new LRUMessageCache(cacheSize);
+ super.start();
+ }
+
+ @Override
+ public void stop() {
+ msgCache.clear();
+ msgCache = null;
+ super.stop();
+ }
+
+ @Override
+ public FilterReply decide(Marker marker, Logger logger, Level level,
+ String format, Object[] params, Throwable t) {
+ int count = msgCache.getMessageCount(format);
+ if(count <= allowedRepetitions) {
+ return FilterReply.NEUTRAL;
+ } else {
+ return FilterReply.DENY;
+ }
+ }
+
+ public int getAllowedRepetitions() {
+ return allowedRepetitions;
+ }
+
+ public void setAllowedRepetitions(int allowedRepetitions) {
+ this.allowedRepetitions = allowedRepetitions;
+ }
+
+ public int getCacheSize() {
+ return cacheSize;
+ }
+
+ public void setCacheSize(int cacheSize) {
+ this.cacheSize = cacheSize;
+ }
+
+}
Added: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/turbo/LRUMessageCache.java Thu Dec 18 21:11:24 2008
@@ -0,0 +1,43 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.turbo;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+class LRUMessageCache extends LinkedHashMap<String, Integer> {
+
+ private static final long serialVersionUID = 1L;
+
+ final int cacheSize;
+
+ LRUMessageCache(int cacheSize) {
+ super((int) (cacheSize * (4.0f / 3)), 0.75f, true);
+ if (cacheSize < 1) {
+ throw new IllegalArgumentException("Cache size cannnot be smaller than 1");
+ }
+ this.cacheSize = cacheSize;
+ }
+
+ int getMessageCount(String msg) {
+ Integer i = super.get(msg);
+ if(i == null) {
+ i = 1;
+ } else {
+ i = new Integer(i.intValue()+1);
+ }
+ super.put(msg, i);
+ return i;
+ }
+
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return (size() > cacheSize);
+ }
+}
Added: logback/trunk/logback-classic/src/test/input/joran/hoard/completeCycle.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/input/joran/hoard/completeCycle.xml Thu Dec 18 21:11:24 2008
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration>
+
+<configuration debug="true">
+
+ <appender name="HOARD"
+ class="ch.qos.logback.classic.hoard.HoardingAppender">
+
+ <mdcKey>cycle</mdcKey>
+ <defaultValue>cycleDefault</defaultValue>
+ <hoard>
+ <appender name="list-${cycle}" class="ch.qos.logback.core.read.ListAppender"/>
+ </hoard>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="HOARD" />
+ </root>
+
+</configuration>
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/AllClassicTest.java Thu Dec 18 21:11:24 2008
@@ -33,7 +33,7 @@
suite.addTest(ch.qos.logback.classic.pattern.PackageTest.suite());
suite.addTest(ch.qos.logback.classic.db.PackageTest.suite());
suite.addTest(ch.qos.logback.classic.spi.PackageTest.suite());
- suite.addTest(ch.qos.logback.classic.turbo.PackageTest.suite());
+ suite.addTest(new JUnit4TestAdapter(ch.qos.logback.classic.turbo.PackageTest.class));
suite.addTest(new JUnit4TestAdapter(
ch.qos.logback.classic.hoard.PackageTest.class));
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/AppenderTrackerTest.java Thu Dec 18 21:11:24 2008
@@ -24,9 +24,17 @@
la.setContext(context);
la.start();
}
+
@Test
- public void empty() {
+ public void empty0() {
+ long now = 3000;
+ appenderTracker.stopStaleAppenders(now);
+ assertEquals(0, appenderTracker.keyList().size());
+ }
+
+ @Test
+ public void empty1() {
long now = 3000;
assertNull(appenderTracker.get("a", now++));
now += AppenderTrackerImpl.THRESHOLD+1000;
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/hoard/HoardingAppenderTest.java Thu Dec 18 21:11:24 2008
@@ -16,7 +16,9 @@
import java.util.List;
import org.junit.Test;
+import org.slf4j.MDC;
+import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
@@ -56,8 +58,8 @@
long timestamp = 0;
HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.appenderTracker.get("smoke", timestamp);
- StatusPrinter.print(loggerContext);
+ StatusPrinter.print(loggerContext);
assertNotNull(listAppender);
List<LoggingEvent> eventList = listAppender.list;
assertEquals(1, listAppender.list.size());
@@ -65,11 +67,28 @@
}
@Test
- public void testLevel() throws JoranException {
- configure(PREFIX + "hoard0.xml");
- logger.debug("ss");
- //StatusPrinter.print(loggerContext);
+ public void testWholeCycle() throws JoranException {
+ String mdcKey = "cycle";
+ configure(PREFIX + "completeCycle.xml");
+ MDC.put(mdcKey, "a");
+ logger.debug("smoke");
+ long timestamp = System.currentTimeMillis();
+ HoardingAppender ha = (HoardingAppender) root.getAppender("HOARD");
+ ListAppender<LoggingEvent> listAppender = (ListAppender<LoggingEvent>) ha.appenderTracker.get("a", timestamp);
+ StatusPrinter.print(loggerContext);
- }
+ assertNotNull(listAppender);
+ List<LoggingEvent> eventList = listAppender.list;
+ assertEquals(1, listAppender.list.size());
+ assertEquals("smoke", eventList.get(0).getMessage());
+ MDC.remove(mdcKey);
+ LoggingEvent le = new LoggingEvent("x", logger, Level.INFO, "hello", null, null);
+ le.setTimeStamp(timestamp+AppenderTracker.THRESHOLD*2);
+ ha.doAppend(le);
+ assertFalse(listAppender.isStarted());
+ assertEquals(1, ha.appenderTracker.keyList().size());
+ assertEquals("cycleDefault", ha.appenderTracker.keyList().get(0));
+
+ }
}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/DuplicateMessageFilterTest.java Thu Dec 18 21:11:24 2008
@@ -0,0 +1,54 @@
+package ch.qos.logback.classic.turbo;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import ch.qos.logback.core.spi.FilterReply;
+
+
+public class DuplicateMessageFilterTest {
+
+
+ @Test
+ public void smoke() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(1);
+ dmf.start();
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "x", null, null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "y", null, null));
+ assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "x", null, null));
+ assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "y", null, null));
+ }
+
+ @Test
+ public void memoryLoss() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(1);
+ dmf.setCacheSize(1);
+ dmf.start();
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a", null, null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "b", null, null));
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a", null, null));
+ }
+
+
+ @Test
+ public void many() {
+ DuplicateMessageFilter dmf = new DuplicateMessageFilter();
+ dmf.setAllowedRepetitions(1);
+ int cacheSize = 10;
+ int margin = 2;
+ dmf.setCacheSize(cacheSize);
+ dmf.start();
+ for(int i = 0; i < cacheSize+margin; i++) {
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a"+i, null, null));
+ }
+ for(int i = cacheSize-1; i >= margin; i--) {
+ assertEquals(FilterReply.DENY, dmf.decide(null, null, null, "a"+i, null, null));
+ }
+ for(int i = margin-1; i >= 0; i--) {
+ assertEquals(FilterReply.NEUTRAL, dmf.decide(null, null, null, "a"+i, null, null));
+ }
+ }
+}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/MarkerFilterTest.java Thu Dec 18 21:11:24 2008
@@ -1,30 +1,23 @@
package ch.qos.logback.classic.turbo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import ch.qos.logback.core.spi.FilterReply;
-import junit.framework.TestCase;
-
-public class MarkerFilterTest extends TestCase {
+public class MarkerFilterTest {
static String MARKER_NAME = "toto";
Marker totoMarker = MarkerFactory.getMarker(MARKER_NAME);
- public MarkerFilterTest(String arg0) {
- super(arg0);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
- }
+ @Test
public void testNoMarker() {
MarkerFilter mkt = new MarkerFilter();
mkt.start();
@@ -33,7 +26,9 @@
assertEquals(FilterReply.NEUTRAL, mkt.decide(null, null, null, null, null, null));
}
-
+
+
+ @Test
public void testBasic() {
MarkerFilter mkt = new MarkerFilter();
mkt.setMarker(MARKER_NAME);
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/turbo/PackageTest.java Thu Dec 18 21:11:24 2008
@@ -10,15 +10,11 @@
package ch.qos.logback.classic.turbo;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
-public class PackageTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(MarkerFilterTest.class);
- return suite;
- }
+(a)RunWith(Suite.class)
+@SuiteClasses( { MarkerFilterTest.class, DuplicateMessageFilterTest.class})
+public class PackageTest {
}
\ No newline at end of file
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/BasicStatusManager.java Thu Dec 18 21:11:24 2008
@@ -12,18 +12,22 @@
import java.util.ArrayList;
import java.util.List;
+import ch.qos.logback.core.helpers.CyclicBuffer;
import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusListener;
import ch.qos.logback.core.status.StatusManager;
public class BasicStatusManager implements StatusManager {
- public static final int MAX_COUNT = 200;
+ public static final int MAX_HEADER_COUNT = 150;
+ public static final int TAIL_SIZE = 150;
int count = 0;
// protected access was requested in http://jira.qos.ch/browse/LBCORE-36
final protected List<Status> statusList = new ArrayList<Status>();
+ final protected CyclicBuffer<Status> tailBuffer = new CyclicBuffer<Status>(
+ TAIL_SIZE);
final protected Object statusListLock = new Object();
int level = Status.INFO;
@@ -34,7 +38,7 @@
// Note on synchronization
// This class contains two separate locks statusListLock and
- // statusListenerListLock guarding respectively the statusList and
+ // statusListenerListLock guarding respectively the statusList+tailBuffer and
// statusListenerList fields. The locks are used internally
// without cycles. They are exposed to derived classes which should be careful
// not to create deadlock cycles.
@@ -49,21 +53,28 @@
// LBCORE-72: fire event before the count check
fireStatusAddEvent(newStatus);
- if (count > MAX_COUNT) {
- return;
- }
count++;
-
if (newStatus.getLevel() > level) {
level = newStatus.getLevel();
}
synchronized (statusListLock) {
- statusList.add(newStatus);
+ if (statusList.size() < MAX_HEADER_COUNT) {
+ statusList.add(newStatus);
+ } else {
+ tailBuffer.add(newStatus);
+ }
}
}
-
+ public List<Status> getCopyOfStatusList() {
+ synchronized (statusListLock) {
+ List<Status> tList = new ArrayList<Status>(statusList);
+ tList.addAll(tailBuffer.asList());
+ return tList;
+ }
+ }
+
private void fireStatusAddEvent(Status status) {
synchronized (statusListenerListLock) {
for (StatusListener sl : statusListenerList) {
@@ -72,12 +83,6 @@
}
}
- public List<Status> getCopyOfStatusList() {
- synchronized (statusListLock) {
- return new ArrayList<Status>(statusList);
- }
- }
-
public int getLevel() {
return level;
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java Thu Dec 18 21:11:24 2008
@@ -10,14 +10,14 @@
package ch.qos.logback.core.helpers;
+import java.util.ArrayList;
+import java.util.List;
/**
+ * CyclicBuffer holds values in a cyclic array.
*
- * CyclicBuffer is used by other appenders to hold
- * objects for immediate or differed display.
- * <p>
- * This buffer gives read access to any element in the buffer not just the first
- * or last element.
+ * <p>It allows read access to any element in the buffer not just the first or
+ * last element.
*
* @author Ceki Gülcü
*/
@@ -35,7 +35,7 @@
* The <code>maxSize</code> argument must a positive integer.
*
* @param maxSize
- * The maximum number of elements in the buffer.
+ * The maximum number of elements in the buffer.
*/
@SuppressWarnings("unchecked")
public CyclicBuffer(int maxSize) throws IllegalArgumentException {
@@ -45,7 +45,7 @@
}
init(maxSize);
}
-
+
@SuppressWarnings("unchecked")
private void init(int maxSize) {
this.maxSize = maxSize;
@@ -54,10 +54,9 @@
last = 0;
numElems = 0;
}
-
+
/**
- * Clears the buffer
- * and resets all attributes.
+ * Clears the buffer and resets all attributes.
*/
public void clear() {
init(this.maxSize);
@@ -94,7 +93,6 @@
return maxSize;
}
-
/**
* Get the oldest (first) element in the buffer. The oldest element is removed
* from the buffer.
@@ -110,6 +108,14 @@
}
return r;
}
+
+ public List<E> asList() {
+ List<E> tList = new ArrayList<E>();
+ for(int i = 0; i < length(); i++) {
+ tList.add(get(i));
+ }
+ return tList;
+ }
/**
* Get the number of elements in the buffer. This number is guaranteed to be
@@ -123,7 +129,7 @@
* Resize the cyclic buffer to <code>newSize</code>.
*
* @throws IllegalArgumentException
- * if <code>newSize</code> is negative.
+ * if <code>newSize</code> is negative.
*/
@SuppressWarnings("unchecked")
public void resize(int newSize) {
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/joran/action/AppenderAction.java Thu Dec 18 21:11:24 2008
@@ -52,7 +52,7 @@
appender.setContext(context);
- String appenderName = attributes.getValue(NAME_ATTRIBUTE);
+ String appenderName = ec.subst(attributes.getValue(NAME_ATTRIBUTE));
if (OptionHelper.isEmpty(appenderName)) {
addWarn("No appender name given for appender of type " + className
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/read/ListAppender.java Thu Dec 18 21:11:24 2008
@@ -1,11 +1,11 @@
/**
- * 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.
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ *
+ * Copyright (C) 2000-2008, 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.core.read;
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/status/StatusBase.java Thu Dec 18 21:11:24 2008
@@ -139,4 +139,33 @@
return buf.toString();
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + level;
+ result = prime * result + ((message == null) ? 0 : message.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final StatusBase other = (StatusBase) obj;
+ if (level != other.level)
+ return false;
+ if (message == null) {
+ if (other.message != null)
+ return false;
+ } else if (!message.equals(other.message))
+ return false;
+ return true;
+ }
+
+
}
Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java (original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/AllCoreTest.java Thu Dec 18 21:11:24 2008
@@ -14,7 +14,8 @@
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
-(a)SuiteClasses({ch.qos.logback.core.util.PackageTest.class,
+(a)SuiteClasses({BasicStatusManagerTest.class,
+ ch.qos.logback.core.util.PackageTest.class,
ch.qos.logback.core.helpers.PackageTest.class,
ch.qos.logback.core.pattern.PackageTest.class,
ch.qos.logback.core.PackageTest.class,
Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/BasicStatusManagerTest.java Thu Dec 18 21:11:24 2008
@@ -0,0 +1,53 @@
+package ch.qos.logback.core;
+
+import static ch.qos.logback.core.BasicStatusManager.MAX_HEADER_COUNT;
+import static ch.qos.logback.core.BasicStatusManager.TAIL_SIZE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import ch.qos.logback.core.status.ErrorStatus;
+import ch.qos.logback.core.status.Status;
+
+
+public class BasicStatusManagerTest {
+
+
+ BasicStatusManager bsm = new BasicStatusManager();
+
+ @Test
+ public void smoke() {
+ bsm.add(new ErrorStatus("hello", this));
+ assertEquals(Status.ERROR, bsm.getLevel());
+
+ List<Status> statusList = bsm.getCopyOfStatusList();
+ assertNotNull(statusList);
+ assertEquals(1, statusList.size());
+ assertEquals("hello", statusList.get(0).getMessage());
+ }
+
+ @Test
+ public void many() {
+ int margin = 300;
+ int len = MAX_HEADER_COUNT+TAIL_SIZE+margin;
+ for(int i = 0; i < len; i++) {
+ bsm.add(new ErrorStatus(""+i, this));
+ }
+
+ List<Status> statusList = bsm.getCopyOfStatusList();
+ assertNotNull(statusList);
+ assertEquals(MAX_HEADER_COUNT+TAIL_SIZE, statusList.size());
+ List<Status> witness = new ArrayList<Status>();
+ for(int i = 0; i < MAX_HEADER_COUNT; i++) {
+ witness.add(new ErrorStatus(""+i, this));
+ }
+ for(int i = 0; i < TAIL_SIZE; i++) {
+ witness.add(new ErrorStatus(""+(MAX_HEADER_COUNT+margin+i), this));
+ }
+ assertEquals(witness, statusList);
+ }
+}
1
0