logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgo...@apache.org
Subject svn commit: r1201589 - in /logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers: log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ log4j2-core/src/test/java/org/apache/logging/log4j/ log4j2-core/src/test/resources/ src/site/ src/site/xdo...
Date Mon, 14 Nov 2011 03:31:12 GMT
Author: rgoers
Date: Mon Nov 14 03:31:11 2011
New Revision: 1201589

URL: http://svn.apache.org/viewvc?rev=1201589&view=rev
Log:
Add Performance documentation and Filter Manual page.

Added:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java
      - copied, changed from r1195339, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/PerformanceComparison.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf-filter.xml
      - copied, changed from r1195339, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf2.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf-filter.xml
      - copied, changed from r1195339, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf2.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/performance.xml
Modified:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/DebugDisabledPerformanceComparison.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j12-perf2.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/site.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/index.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/appenders.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/architecture.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/configuration.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/extending.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/filters.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/layouts.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/lookups.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java Mon Nov 14 03:31:11 2011
@@ -29,6 +29,7 @@ import org.apache.logging.log4j.core.hel
 import org.apache.logging.log4j.message.Message;
 
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 /**
@@ -36,14 +37,32 @@ import java.util.Map;
  */
 @Plugin(name="ThreadContextMapFilter", type="Core", elementType="filter", printObject = true)
 public class ThreadContextMapFilter extends FilterBase {
-    private final Map<String, Object> map;
+    private final Map<String, String> map;
+
+    private final String key;
+    private final String value;
 
     private final boolean isAnd;
 
-    public ThreadContextMapFilter(Map<String, Object> pairs, boolean oper, Result onMatch, Result onMismatch) {
+    private final boolean useMap;
+
+    public ThreadContextMapFilter(Map<String, String> pairs, boolean oper, Result onMatch, Result onMismatch) {
         super(onMatch, onMismatch);
-        this.map = pairs;
-        this.isAnd = oper;
+        if (pairs.size() == 1) {
+            Iterator<Map.Entry<String, String>> iter = pairs.entrySet().iterator();
+            Map.Entry<String, String> entry = iter.next();
+            this.key = entry.getKey();
+            this.value= entry.getValue();
+            this.map = null;
+            this.isAnd = false;
+            this.useMap = false;
+        } else {
+            this.map = pairs;
+            this.isAnd = oper;
+            this.key = null;
+            this.value = null;
+            this.useMap = true;
+        }
     }
 
     @Override
@@ -63,11 +82,15 @@ public class ThreadContextMapFilter exte
 
     private Result filter() {
         boolean match = false;
-        for (String key : map.keySet()) {
-            match = map.get(key).equals(ThreadContext.get(key));
-            if ((!isAnd && match) || (isAnd && !match)) {
-                break;
+        if (useMap) {
+            for (String key : map.keySet()) {
+                match = map.get(key).equals(ThreadContext.get(key));
+                if ((!isAnd && match) || (isAnd && !match)) {
+                    break;
+                }
             }
+        } else {
+            match = key.equals(ThreadContext.get(key));
         }
         return match ? onMatch : onMismatch;
     }
@@ -91,7 +114,7 @@ public class ThreadContextMapFilter exte
         if (map.size() > 0) {
             sb.append(", {");
             boolean first = true;
-            for (Map.Entry<String, Object> entry : map.entrySet()) {
+            for (Map.Entry<String, String> entry : map.entrySet()) {
                 if (!first) {
                     sb.append(", ");
                 }
@@ -112,7 +135,7 @@ public class ThreadContextMapFilter exte
             logger.error("key and value pairs must be specified for the ThreadContextMapFilter");
             return null;
         }
-        Map<String, Object> map = new HashMap<String, Object>();
+        Map<String, String> map = new HashMap<String, String>();
         for (KeyValuePair pair : pairs) {
             String key = pair.getKey();
             if (key == null) {

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/DebugDisabledPerformanceComparison.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/DebugDisabledPerformanceComparison.java?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/DebugDisabledPerformanceComparison.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/DebugDisabledPerformanceComparison.java Mon Nov 14 03:31:11 2011
@@ -41,7 +41,7 @@ public class DebugDisabledPerformanceCom
 
 
     // How many times should we try to log:
-    private static final int COUNT = 1000000;
+    private static final int COUNT = 10000000;
     private static final int PROFILE_COUNT = 500000;
     private static final int WARMUP = 1000;
 
@@ -82,18 +82,45 @@ public class DebugDisabledPerformanceCom
             System.out.println("Log4j 2.0: " + result);
             System.out.println("###############################################");
         } else {
+            System.out.println("Starting isDebugEnabled tests");
             System.out.println("Starting Log4j 2.0");
-            long result3 = log4j2(COUNT);
+            long result3 = log4j2IsDebug(COUNT);
             System.out.println("Starting Log4j");
-            long result1 = log4j(COUNT);
+            long result1 = log4j2IsDebug(COUNT);
             System.out.println("Starting Logback");
-            long result2 = logback(COUNT);
+            long result2 = logbackIsDebug(COUNT );
 
             System.out.println("###############################################");
             System.out.println("Log4j: " + result1);
             System.out.println("Logback: " + result2);
             System.out.println("Log4j 2.0: " + result3);
             System.out.println("###############################################");
+
+            System.out.println("Starting logger.debug tests with String concatenation");
+            System.out.println("Starting Log4j 2.0");
+            result3 = log4j2(COUNT);
+            System.out.println("Starting Log4j");
+            result1 = log4j(COUNT);
+            System.out.println("Starting Logback");
+            result2 = logback(COUNT);
+
+            System.out.println("###############################################");
+            System.out.println("Log4j: " + result1);
+            System.out.println("Logback: " + result2);
+            System.out.println("Log4j 2.0: " + result3);
+            System.out.println("###############################################");
+
+            System.out.println("Starting logger.debug tests without String concatenation");
+            System.out.println("Starting Log4j 2.0");
+            result3 = log4j2Debug(COUNT);
+            System.out.println("Starting Logback");
+            result2 = logbackDebug(COUNT);
+
+            System.out.println("###############################################");
+            System.out.println("Log4j: Not supported");
+            System.out.println("Logback: " + result2);
+            System.out.println("Log4j 2.0: " + result3);
+            System.out.println("###############################################");
         }
     }
 
@@ -120,6 +147,37 @@ public class DebugDisabledPerformanceCom
         System.out.println("###############################################");
     }
 
+
+    private long log4jIsDebug(int loop) {
+        Integer j = new Integer(2);
+        long start = System.nanoTime();
+        for (int i = 0; i < loop; i++) {
+            log4jlogger.isDebugEnabled();
+        }
+        return (System.nanoTime() - start) / loop;
+    }
+
+    private long logbackIsDebug(int loop) {
+        Integer j = new Integer(2);
+        long start = System.nanoTime();
+        for (int i = 0; i < loop; i++) {
+            logbacklogger.isDebugEnabled();
+        }
+        return (System.nanoTime() - start) / loop;
+    }
+
+
+    private long log4j2IsDebug(int loop) {
+        Integer j = new Integer(2);
+        long start = System.nanoTime();
+        for (int i = 0; i < loop; i++) {
+            logger.isDebugEnabled();
+        }
+        return (System.nanoTime() - start) / loop;
+    }
+
+
+
     private long log4j(int loop) {
         Integer j = new Integer(2);
         long start = System.nanoTime();
@@ -138,6 +196,15 @@ public class DebugDisabledPerformanceCom
         return (System.nanoTime() - start) / loop;
     }
 
+    private long logbackDebug(int loop) {
+        Integer j = new Integer(2);
+        long start = System.nanoTime();
+        for (int i = 0; i < loop; i++) {
+            logbacklogger.debug("SEE IF THIS IS LOGGED {} .", j);
+        }
+        return (System.nanoTime() - start) / loop;
+    }
+
 
     private long log4j2(int loop) {
         Integer j = new Integer(2);
@@ -148,6 +215,15 @@ public class DebugDisabledPerformanceCom
         return (System.nanoTime() - start) / loop;
     }
 
+     private long log4j2Debug(int loop) {
+        Integer j = new Integer(2);
+        long start = System.nanoTime();
+        for (int i = 0; i < loop; i++) {
+            logger.debug("SEE IF THIS IS LOGGED {} .", j);
+        }
+        return (System.nanoTime() - start) / loop;
+    }
+
 
     private long writeToWriter(int loop, Writer w) throws Exception {
         Integer j = new Integer(2);

Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java (from r1195339, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/PerformanceComparison.java)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/PerformanceComparison.java&r1=1195339&r2=1201589&rev=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/PerformanceComparison.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java Mon Nov 14 03:31:11 2011
@@ -29,112 +29,100 @@ import java.io.OutputStream;
 import java.io.Writer;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
 
 /**
  *
  */
-public class PerformanceComparison {
+public class FilterPerformanceComparison {
 
-    private Logger logger = LogManager.getLogger(PerformanceComparison.class.getName());
-    private org.slf4j.Logger logbacklogger = org.slf4j.LoggerFactory.getLogger(PerformanceComparison.class);
-    private org.apache.log4j.Logger log4jlogger = org.apache.log4j.Logger.getLogger(PerformanceComparison.class);
+    private Logger logger = LogManager.getLogger(FilterPerformanceComparison.class.getName());
+    private org.slf4j.Logger logbacklogger = org.slf4j.LoggerFactory.getLogger(FilterPerformanceComparison.class);
 
 
     // How many times should we try to log:
-    private static final int COUNT = 1000000;
-    private static final int PROFILE_COUNT = 500000;
+    private static final int COUNT = 10000000;
+    private static final int THREADED_COUNT = 100000;
     private static final int WARMUP = 1000;
 
-    private static final String CONFIG = "log4j2-perf.xml";
-    private static final String LOGBACK_CONFIG = "logback-perf.xml";
-    private static final String LOG4J_CONFIG = "log4j12-perf.xml";
+    private static final String CONFIG = "log4j2-perf-filter.xml";
+    private static final String LOGBACK_CONFIG = "logback-perf-filter.xml";
 
     private static final String LOGBACK_CONF = "logback.configurationFile";
-    private static final String LOG4J_CONF = "log4j.configuration";
 
     @BeforeClass
     public static void setupClass() {
         System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
         System.setProperty(LOGBACK_CONF, LOGBACK_CONFIG);
-        System.setProperty(LOG4J_CONF, LOG4J_CONFIG);
     }
 
     @AfterClass
     public static void cleanupClass() {
         System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
         System.clearProperty(LOGBACK_CONF);
-        System.clearProperty(LOG4J_CONF);
     }
 
     @Test
     public void testPerformance() throws Exception {
-
-        log4j(WARMUP);
         logback(WARMUP);
         log4j2(WARMUP);
 
-        if (Profiler.isActive()) {
-            System.out.println("Profiling Log4j 2.0");
-            Profiler.start();
-            long result = log4j2(PROFILE_COUNT);
-            Profiler.stop();
-            System.out.println("###############################################");
-            System.out.println("Log4j 2.0: " + result);
-            System.out.println("###############################################");
-        } else {
-            System.out.println("Starting Log4j 2.0");
-            long result3 = log4j2(COUNT);
-            System.out.println("Starting Log4j");
-            long result1 = log4j(COUNT);
-            System.out.println("Starting Logback");
-            long result2 = logback(COUNT);
-
-            System.out.println("###############################################");
-            System.out.println("Log4j: " + result1);
-            System.out.println("Logback: " + result2);
-            System.out.println("Log4j 2.0: " + result3);
-            System.out.println("###############################################");
-        }
-    }
+        System.out.println("Starting Log4j 2.0");
+        long result3 = log4j2(COUNT);
+        System.out.println("Starting Logback");
+        long result2 = logback(COUNT);
 
-    //@Test
-    public void testRawPerformance() throws Exception {
-        OutputStream os = new FileOutputStream("target/testos.log", true);
-        long result1 = writeToStream(COUNT, os);
-        os.close();
-        OutputStream bos = new BufferedOutputStream(new FileOutputStream("target/testbuffer.log", true));
-        long result2 = writeToStream(COUNT, bos);
-        bos.close();
-        Writer w = new FileWriter("target/testwriter.log", true);
-        long result3 = writeToWriter(COUNT, w);
-        w.close();
-        FileOutputStream cos = new FileOutputStream("target/testchannel.log", true);
-        FileChannel channel = cos.getChannel();
-        long result4 = writeToChannel(COUNT, channel);
-        cos.close();
         System.out.println("###############################################");
-        System.out.println("FileOutputStream: " + result1);
-        System.out.println("BufferedOutputStream: " + result2);
-        System.out.println("FileWriter: " + result3);
-        System.out.println("FileChannel: " + result4);
+        System.out.println("Logback: " + result2);
+        System.out.println("Log4j 2.0: " + result3);
         System.out.println("###############################################");
     }
 
-    private long log4j(int loop) {
-        Integer j = new Integer(2);
-        long start = System.nanoTime();
-        for (int i = 0; i < loop; i++) {
-            log4jlogger.debug("SEE IF THIS IS LOGGED " + j + ".");
+    @Test
+    public void testThreads() throws Exception {
+        System.out.println("Testing multithreading");
+        int threadedCount = COUNT; // THREADED_COUNT * threadCount < COUNT ? COUNT / threadCount : THREADED_COUNT;
+        int[] threadCounts = new int[] {1, 2, 5, 10, 20, 50};
+        for (int threadCount : threadCounts) {
+            System.out.println("Testing " + threadCount + " threads");
+            Worker[] workers = new Worker[threadCount];
+            long[] results = new long[threadCount];
+            for (int i=0; i < threadCount; ++i) {
+                workers[i] = new Worker(true, threadedCount, results, i);
+            }
+            for (int i=0; i < threadCount; ++i) {
+                workers[i].start();
+            }
+            long total = 0;
+            for (int i=0; i < threadCount; ++i) {
+                workers[i].join();
+                total += results[i];
+            }
+            long result3 = total / threadCount;
+            total = 0;
+            for (int i=0; i < threadCount; ++i) {
+                workers[i] = new Worker(false, threadedCount, results, i);
+            }
+            for (int i=0; i < threadCount; ++i) {
+                workers[i].start();
+            }
+            for (int i=0; i < threadCount; ++i) {
+                workers[i].join();
+                total += results[i];
+            }
+            long result2 = total / threadCount;
+            System.out.println("###############################################");
+            System.out.println("Logback: " + result2);
+            System.out.println("Log4j 2.0: " + result3 );
+            System.out.println("###############################################");
         }
-        return (System.nanoTime() - start) / loop;
+
     }
 
     private long logback(int loop) {
         Integer j = new Integer(2);
         long start = System.nanoTime();
         for (int i = 0; i < loop; i++) {
-            logbacklogger.debug("SEE IF THIS IS LOGGED " + j + ".");
+            logbacklogger.debug("SEE IF THIS IS LOGGED {}.", j);
         }
         return (System.nanoTime() - start) / loop;
     }
@@ -144,49 +132,28 @@ public class PerformanceComparison {
         Integer j = new Integer(2);
         long start = System.nanoTime();
         for (int i = 0; i < loop; i++) {
-            logger.debug("SEE IF THIS IS LOGGED " + j + ".");
+            logger.debug("SEE IF THIS IS LOGGED {}.", j);
         }
         return (System.nanoTime() - start) / loop;
     }
 
+    private class Worker extends Thread {
 
-    private long writeToWriter(int loop, Writer w) throws Exception {
-        Integer j = new Integer(2);
-        long start = System.nanoTime();
-        for (int i = 0; i < loop; i++) {
-            w.write("SEE IF THIS IS LOGGED " + j + ".");
-        }
-        return (System.nanoTime() - start) / loop;
-    }
+        private boolean isLog4j;
+        private int count;
+        private long[] results;
+        private int index;
 
-    private long writeToStream(int loop, OutputStream os) throws Exception {
-        Integer j = new Integer(2);
-        long start = System.nanoTime();
-        for (int i = 0; i < loop; i++) {
-            os.write(getBytes("SEE IF THIS IS LOGGED " + j + "."));
+        public Worker(boolean isLog4j, int count, long[] results, int index) {
+            this.isLog4j = isLog4j;
+            this.count = count;
+            this.results = results;
+            this.index = index;
         }
-        return (System.nanoTime() - start) / loop;
-    }
 
-    private long writeToChannel(int loop, FileChannel channel) throws Exception {
-        Integer j = new Integer(2);
-        ByteBuffer buf = ByteBuffer.allocateDirect(8*1024);
-        long start = System.nanoTime();
-        for (int i = 0; i < loop; i++) {
-            channel.write(getByteBuffer(buf, "SEE IF THIS IS LOGGED " + j + "."));
+        public void run() {
+            results[index] = isLog4j ? log4j2(count) : logback(count);
         }
-        return (System.nanoTime() - start) / loop;
-    }
-
-    private ByteBuffer getByteBuffer(ByteBuffer buf, String s) {
-        buf.clear();
-        buf.put(s.getBytes());
-        buf.flip();
-        return buf;
-    }
-
-    private byte[] getBytes(String s) {
-        return s.getBytes();
     }
 
 }
\ No newline at end of file

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j12-perf2.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j12-perf2.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j12-perf2.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j12-perf2.xml Mon Nov 14 03:31:11 2011
@@ -8,7 +8,7 @@
    </layout>
  </appender>
  <root>
-   <level value="debug"/>
+   <level value="error"/>
    <appender-ref ref="TestLogfile"/>
  </root>
 </log4j:configuration>
\ No newline at end of file

Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf-filter.xml (from r1195339, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf2.xml)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf-filter.xml?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf-filter.xml&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf2.xml&r1=1195339&r2=1201589&rev=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf2.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf-filter.xml Mon Nov 14 03:31:11 2011
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration packages="" name="XMLPerfTest" status="error">
+  <!-- <MarkerFilter marker="LOG4J" onMismatch="NEUTRAL"/> -->
+  <ThreadContextMapFilter onMismatch="NEUTRAL">
+      <KeyValuePair key="LOG4J" value="test"/>
+  </ThreadContextMapFilter>
   <appenders>
     <File name="TestLogfile" fileName="target/testlog4j2.log" immediateFlush="false">
       <PatternLayout>

Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf-filter.xml (from r1195339, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf2.xml)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf-filter.xml?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf-filter.xml&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf2.xml&r1=1195339&r2=1201589&rev=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf2.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf-filter.xml Mon Nov 14 03:31:11 2011
@@ -1,4 +1,11 @@
 <configuration>
+  <!--<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
+    <Marker>LOG4J</Marker>
+  </turboFilter> -->
+ <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
+   <MDCKey>LOG4J</MDCKey>
+   <value>test</value>
+ </turboFilter>
  <appender name="TestLogfile" class="ch.qos.logback.core.FileAppender">
    <file>target/testlogback.log</file>
    <encoder>

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/site.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/site.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/site.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/site.xml Mon Nov 14 03:31:11 2011
@@ -70,7 +70,9 @@
         </item>
         <item name="Filters"               href="/manual/filters.html" collapse="true">
           <item name="Burst"               href="/manual/filters.html#BurstFilter"/>
+          <item name="CompositeFilter"     href="/manual/filters.html#CompositeFilter"/>
           <item name="DynamicThreshold"    href="/manual/filters.html#DynamicThresholdFilter"/>
+          <item name="Map"                 href="/manual/filters.html#MapFilter"/>
           <item name="Marker"              href="/manual/filters.html#MarkerFilter"/>
           <item name="Regex"               href="/manual/filters.html#RegexFilter"/>
           <item name="StructuredData"      href="/manual/filters.html#StructuredDataFilter"/>

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/index.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/index.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/index.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/index.xml Mon Nov 14 03:31:11 2011
@@ -42,7 +42,7 @@
             <h3>Improved Performance</h3>
             <p>
               Faster performance than Log4j 1.x in critical areas and similar performance to Logback in
-              most circumstances.
+              most circumstances. See <a href="performance.html">Performance</a> for more information.
             </p>
             <h3>Support for multiple APIs</h3>
             <p>

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/appenders.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/appenders.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/appenders.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/appenders.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Overview</title>
+        <title>Log4j 2 Appenders</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/architecture.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/architecture.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/architecture.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/architecture.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
   <properties>
-    <title>Overview</title>
+    <title>Log4j 2 Architecture</title>
     <author email="rgoers@apache.org">Ralph Goers</author>
   </properties>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/configuration.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/configuration.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/configuration.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/configuration.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Overview</title>
+        <title>Configuring Log4j 2</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/extending.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/extending.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/extending.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/extending.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Extending Log4j</title>
+        <title>Extending Log4j 2</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/filters.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/filters.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/filters.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/filters.xml Mon Nov 14 03:31:11 2011
@@ -18,47 +18,640 @@
 
 <document>
     <properties>
-        <title>Overview</title>
+        <title>Log4J 2 Filters</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 
     <body>
       <section name="Filters">
+        <p>
+          Filters allow Log Events to be evaluated to determine if or how they should be published. A Filter
+          will be called on one if its filter methods and will return a Result, which is an Enum that has
+          one of 3 values - ACCEPT, DENY or NEUTRAL.
+        </p>
+        <p>
+          Filters may be configured in one of three locations;
+          <ol>
+            <li>Context-wide Filters are configured directly in the configuration. Events that are
+            rejected by these filters will not be passed to loggers for further processing. Once an
+            event has been accepted by a Context-wide filter it will not be evaluated by any other
+            Context-wide Filters nor will the Logger's Level be used to filter the event. The event
+            will be evaluated by Logger and Appender Filters however.</li>
+            <li>Logger Filters are configured on a specified Logger. These are evaluated after the
+            Context-wide Filters and the Log Level for the Logger. Events that are rejected by these
+            filters will be discarded and the event will not be passed to a parent Logger regardless
+            of the additivity setting.</li>
+            <li>Appender Filters are used to determine if a specific Appender should handle the
+            formatting and publication of the event.</li>
+          </ol>
+        </p>
         <a name="BurstFilter"/>
         <subsection name="BurstFilter">
-
+          <p>
+            The BurstFilter provides a mechanism to control the rate at which LogEvents are processed by
+            silently discarding events after the maximum limit has been reached.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>level</td>
+              <td>String</td>
+              <td>Level of messages to be filtered. Anything at or below this level will be
+                filtered out if <code>maxBurst</code> has been exceeded. The default is
+                WARN meaning any messages that are higher than warn will be logged
+                regardless of the size of a burst.
+              </td>
+            </tr>
+            <tr>
+              <td>rate</td>
+              <td>float</td>
+              <td>The average number of events per second to allow.</td>
+            </tr>
+            <tr>
+              <td>maxBurst</td>
+              <td>integer</td>
+              <td>The maximum number of events that can occur before events are filtered for exceeding the
+                average rate. The default is 10 times the rate.</td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Burst Filter Parameters</caption>
+          </table>
+           <p>
+            A configuration containing the BurstFilter might look like:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="CompositeFilter"/>
         <subsection name="CompositeFilter">
-
+          <p>
+            The CompositeFilter provides a way to specify more than one filter. It is added to the
+            configuration as a filters element and contains other filters to be evaluated. The filters
+            element accepts no parameters.
+          </p>
+           <p>
+            A configuration containing the CompositeFilter might look like:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <filters>
+    <Marker marker="EVENT" onMatch="ACCEPT" onMismatch="NETURAL"/>
+    <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR" onMatch="ACCEPT" onMismatch="NEUTRAL">
+      <KeyValuePair key="User1" value="DEBUG"/>
+    </DynamicThresholdFilter>
+  </filters>
+  <appenders>
+    <File name="Audit" fileName="logs/audit.log">
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+    </File>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <logger name="EventLogger" level="info">
+      <appender-ref ref="Audit"/>
+    </logger>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="DynamicThresholdFilter"/>
         <subsection name="DynamicThresholdFilter">
-
+          <p>
+            The DynamicThresholdFilter allows filtering by log level based on specific attributes. For example,
+            if the user's loginid is being captured in the ThreadContext Map then it is possible to enable
+            debug logging for only that user.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>defaultThreshold</td>
+              <td>String</td>
+              <td>Level of messages to be filtered. If there is no matching key in the key/value pairs
+                then this level will be compared against the event's level.
+              </td>
+            </tr>
+            <tr>
+              <td>keyValuePair</td>
+              <td>KeyValuePair[]</td>
+              <td>One or more KeyValuePair elements that define the matching value for the key and the Level
+                to evaluate when the key matches.</td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Dynamic Threshold Filter Parameters</caption>
+          </table>
+           <p>
+            Here is a sample configuration containing the DynamicThresholdFilter:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+    <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR" onMatch="ACCEPT" onMismatch="NEUTRAL">
+      <KeyValuePair key="User1" value="DEBUG"/>
+    </DynamicThresholdFilter>
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
+        </subsection>
+        <a name="MapFilter"/>
+        <subsection name="MapFilter">
+          <p>
+            The MapFilter allows filtering against data elements that are in a MapMessage.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>keyValuePair</td>
+              <td>KeyValuePair[]</td>
+              <td>One or more KeyValuePair elements that define the key in the map and the value to match on.</td>
+            </tr>
+            <tr>
+              <td>operator</td>
+              <td>String</td>
+              <td>If the operator is "or" then a match by any one of the key/value pairs will be considered to be
+                a match, otherwise all the key/value pairs must match.</td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Map Filter Parameters</caption>
+          </table>
+           <p>
+            As in this configuration, the MapFilter can be used to log particular events:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+    <KeyValuePair key="eventId" value="Login"/>
+    <KeyValuePari key="eventId" value="Logout"/>
+  </MapFilter>
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="MarkerFilter"/>
         <subsection name="MarkerFilter">
-
+          <p>
+            The MarkerFilter compares the configured Marker value against the Marker that is included
+            in the LogEvent. A match occurs when the Marker name matches either the Log Event's Marker
+            or one of its parents.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>marker</td>
+              <td>String</td>
+              <td>
+                The name of the Marker to compare.
+              </td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Marker Filter Parameters</caption>
+          </table>
+           <p>
+             A sample configuration that only allows the event to be written by the appender if the Marker matches:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="RegexFilter"/>
         <subsection name="RegexFilter">
-
+           <p>
+            The RegexFilter allows the formatted or unformatted message to be compared against a regular expression.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>regex</td>
+              <td>String</td>
+              <td>
+                The regular expression.
+              </td>
+            </tr>
+            <tr>
+              <td>useRawMsg</td>
+              <td>boolean</td>
+              <td>If true the unformatted message will be used, otherwise the formatted message will be used. The
+                default value is false.</td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Regex Filter Parameters</caption>
+          </table>
+           <p>
+             A sample configuration that only allows the event to be written by the appender if it contains the word "test":
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <RegexFilter regex=".* test .*" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="StructuredDataFilter"/>
         <subsection name="StructuredDataFilter">
-
+          <p>
+            The StructuredDataFilter is a MapFilter that also allows filtering on the event id, type and message.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>keyValuePair</td>
+              <td>KeyValuePair[]</td>
+              <td>One or more KeyValuePair elements that define the key in the map and the value to match on. "id",
+                "id.name", "type", and "message" should be used to match on the StructuredDataId, the name
+                portion of the StructuredDataId, the type, and the formatted message respectively.
+              </td>
+            </tr>
+            <tr>
+              <td>operator</td>
+              <td>String</td>
+              <td>If the operator is "or" then a match by any one of the key/value pairs will be considered to be
+                a match, otherwise all the key/value pairs must match.</td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">StructuredData Filter Parameters</caption>
+          </table>
+           <p>
+            As in this configuration, the StructuredDataFilter can be used to log particular events:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <StructuredDataFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+    <KeyValuePair key="id" value="Login"/>
+    <KeyValuePari key="id" value="Logout"/>
+  </StructuredDataFilter>
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="ThreadContextMapFilter"/>
         <subsection name="ThreadContextMapFilter">
-
+          <p>
+            The ThreadContextMapFilter allows filtering against data elements that are in the ThreadContext Map.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>keyValuePair</td>
+              <td>KeyValuePair[]</td>
+              <td>One or more KeyValuePair elements that define the key in the map and the value to match on.</td>
+            </tr>
+            <tr>
+              <td>operator</td>
+              <td>String</td>
+              <td>If the operator is "or" then a match by any one of the key/value pairs will be considered to be
+                a match, otherwise all the key/value pairs must match.</td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">ThreadContext Map Filter Parameters</caption>
+          </table>
+           <p>
+            A configuration containing the ThreadContextMapFilter might look like:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR" onMatch="ACCEPT" onMismatch="NEUTRAL">
+    <KeyValuePair key="User1" value="DEBUG"/>
+  </DynamicThresholdFilter>
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="ThresholdFilter"/>
         <subsection name="ThresholdFilter">
-
+           <p>
+            This filter returns the onMatch result if the level in the LogEvent is the same or more specific
+            than the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter
+            is configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value will
+            be returned since ERROR events are more specific than DEBUG.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>level</td>
+              <td>String</td>
+              <td>
+                A valid Level name to match on.
+              </td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Threshold Filter Parameters</caption>
+          </table>
+           <p>
+             A sample configuration that only allows the event to be written by the appender if the level matches:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
         <a name="TimeFilter"/>
         <subsection name="TimeFilter">
-
+           <p>
+            The time filter can be used to restrict filter to only a certain portion of the day.
+          </p>
+          <table border="1" width="100%">
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>start</td>
+              <td>String</td>
+              <td>
+                A time in HH:mm:ss format.
+              </td>
+            </tr>
+            <tr>
+              <td>end</td>
+              <td>String</td>
+              <td>
+                A time in HH:mm:ss format. Specifying an end time less than the start time will result in no
+                log entries being written.
+              </td>
+            </tr>
+            <tr>
+              <td>timezone</td>
+              <td>String</td>
+              <td>
+                The timezone to use when comparing to the event timestamp.
+              </td>
+            </tr>
+            <tr>
+              <td>omMatch</td>
+              <td>String</td>
+              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
+            </tr>
+            <tr>
+              <td>omMismatch</td>
+              <td>String</td>
+              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
+                DENY.</td>
+            </tr>
+            <caption align="top">Time Filter Parameters</caption>
+          </table>
+           <p>
+             A sample configuration that only allows the event to be written by the appender from 5:00 to 5:30 am each
+             day using the default timezone:
+
+            <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="warn" name="MyApp" packages="">
+  <appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <TiemFilter start="05:00:00" end="05:30:00" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </appenders>
+  <loggers>
+    <root level="error">
+      <appender-ref ref="RollingFile"/>
+    </root>
+  </loggers>
+</configuration>
+  ]]></source>
+          </p>
         </subsection>
       </section>
     </body>

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/layouts.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/layouts.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/layouts.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/layouts.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Log4j Layouts</title>
+        <title>Log4j 2 Layouts</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 
@@ -34,6 +34,9 @@
         </p>
         <a name="HTMLLayout"/>
         <subsection name="HTMLLayout">
+          <p>
+            The HTMLLayout generates an HTML page and adds each LogEvent to a row in a table.
+          </p>
           <table border="1" width="100%">
             <tr>
               <th>Parameter Name</th>

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/lookups.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/lookups.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/lookups.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/lookups.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Overview</title>
+        <title>Log4j 2 Lookups</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Overview</title>
+        <title>Log4j 2 Plugins</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml?rev=1201589&r1=1201588&r2=1201589&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml Mon Nov 14 03:31:11 2011
@@ -18,7 +18,7 @@
 
 <document>
     <properties>
-        <title>Overview</title>
+        <title>Log4j 2 Thread Context</title>
         <author email="rgoers@apache.org">Ralph Goers</author>
     </properties>
 

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/performance.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/performance.xml?rev=1201589&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/performance.xml (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/performance.xml Mon Nov 14 03:31:11 2011
@@ -0,0 +1,209 @@
+<?xml version="1.0"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<document>
+  <properties>
+    <title>Performance</title>
+    <author email="rgoers@apache.org">Ralph Goers</author>
+  </properties>
+
+  <body>
+    <section name="Performance">
+      <p>One of the often-cited arguments against logging is its
+        computational cost. This is a legitimate concern as even moderately
+        sized applications can generate thousands of log requests. Much
+        effort was spent measuring and tweaking logging performance. Log4j
+        claims to be fast and flexible: speed first, flexibility second.
+      </p>
+      <p>The user should be aware of the following performance issues.</p>
+      <ol>
+        <li>
+          <b>Logging performance when logging is turned off.</b>
+          <br/>
+          <p>When logging is turned off entirely or just for a set of Levels, the cost of a log request consists of
+            two method invocations plus an integer comparison. On a 2.53 GHz Intel Core 2 Duo MacBook Pro
+            calling isDebugEnabled 10 million times produces an average result in nanoseconds of: <br />
+            <pre>
+            Log4j: 4
+            Logback: 5
+            Log4j 2.0: 3
+            </pre>
+            The numbers above will vary slightly from run to run so the only conclusion that should be
+            drawn is that all 3 frameworks perform similarly on this task.
+          </p>
+          <p>However, The method invocation involves the "hidden" cost of parameter construction.
+          </p>
+          <p>For example,
+            <pre>
+              logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
+            </pre>
+            incurs the cost of constructing the message parameter, i.e. converting both integer
+            <code>i</code> and <code>entry[i]</code> to a String, and concatenating intermediate strings,
+            regardless of whether the message will be logged or not.
+
+            This cost of parameter construction can be quite high and it
+            depends on the size of the parameters involved.
+
+            A comparison run on the same hardware as above yields:
+            <pre>
+            Log4j: 188
+            Logback: 183
+            Log4j 2.0: 188
+            </pre>
+
+            Again, no conclusion should be drawn regarding relative differences between the frameworks on
+            this task, but it should be obvious that it is considerably more expensive than simply testing
+            the level.
+          </p>
+          <p>
+            The best approach to avoid the cost of parameter construction is to use Log4J 2.0's formatting
+            capabilities. For example, instead of the above write:
+            <pre>
+            logger.debug("Entry number: {} is {}", i, entry[i]);
+            </pre>
+            Using this approach, a comparison run again on the same hardware produces:
+            <pre>
+            Log4j: Not supported
+            Logback: 9
+            Log4j 2.0: 4
+            </pre>
+            These results show that the difference in performance between the call to isDebugEnabled and
+            logger.debug is barely discernable.
+          </p>
+          <p>In some circumstances one of the parameters to logger.debug will be a costly method call that
+            should be avoided if debugging is disabled. In those cases write:
+            <pre>
+            if(logger.isDebugEnabled() {
+                logger.debug("Entry number: " + i + " is " + entry[i].toString());
+            }
+            </pre>
+          </p>
+          <p>This will not incur the cost of whatever the toString() method needs to do if debugging is disabled.
+            On the other hand, if the logger is enabled for the debug level, it will incur twice the cost of
+            evaluating whether the logger is enabled or not: once
+            in <code>isDebugEnabled</code> and once in <code>debug</code>. This is an insignificant
+            overhead because evaluating a logger takes about 1% of the time it takes to actually log.
+          </p>
+          <p>Certain users resort to preprocessing or compile-time
+            techniques to compile out all log statements. This leads to perfect
+            performance efficiency with respect to logging. However, since the
+            resulting application binary does not contain any log statements,
+            logging cannot be turned on for that binary. This seems to be
+            a disproportionate price to pay in exchange for a small performance
+            gain.
+          </p>
+        </li>
+        <li>
+          <b>The performance of deciding whether to log or not to log when logging is turned on.</b>
+          <br/>
+          <p>
+            Unlike Log4j and Logback, Log4j 2 Loggers don't "walk a hierarchy". Loggers point directly to the
+            Logger configuration that best matches the Logger's name. This incurs extra overhead when the Logger
+            is first created but reduces the overhead every time the Logger is used.
+          </p>
+        </li>
+        <li>
+          <b>Actually outputting log messages</b>
+          <br/>
+          <p>This is the cost of formatting the log output and sending it to its target destination. Here again,
+            a serious effort was made to make layouts (formatters) perform as quickly as possible. The same
+            is true for appenders. One of the fundamental tenants of Log4j 2.0 is to use immutable objects whenever
+            possible and to lock at the lowest granularity possible. However, the cost of actually formatting and
+            delivering log events will never be insignificant. For example, the results of writing to a simple log
+            file using the same format using Log4j, Logback and Log4j 2 are:
+            <pre>
+            Log4j: 4220
+            Logback: 9671
+            Log4j 2.0: 4615
+            </pre>
+          </p>
+          <p>
+            These results show that actually writing out the events can be at least 1000 times more expensive than
+            when they are disabled.
+          </p>
+        </li>
+        <li>
+          <b>Advanced Filtering</b>
+          <br />
+          <p>
+            Both Logback and Log4j 2 support advanced filtering. Logback calls them TurboFilters while
+            Log4j 2 has a single Filter object. Advanced filtering provides the capability to filter
+            LogEvents using more than just the Level before the events are passed to Appenders.
+            However, this flexibility does come with some cost. Since multi-threading can also have an impact on the
+            performance of advanced filtering, the table below shows the difference in performance in two different
+            sets of context-wide filters running on the same hardware as the previous tests using
+            various numbers of threads.
+          </p>
+          <table>
+            <tr>
+              <th>Test</th>
+              <th>1 thread</th>
+              <th>2 threads</th>
+              <th>5 threads</th>
+              <th>10 threads</th>
+              <th>20 threads</th>
+              <th>50 threads</th>
+            </tr>
+            <tr>
+              <td>Logback MDCFilter</td>
+              <td>37</td>
+              <td>50</td>
+              <td>145</td>
+              <td>316</td>
+              <td>606</td>
+              <td>1670</td>
+            </tr>
+            <tr>
+              <td>Log4j 2 ThreadContextMapFilter</td>
+              <td>30</td>
+              <td>35</td>
+              <td>85</td>
+              <td>165</td>
+              <td>341</td>
+              <td>864</td>
+            </tr>
+            <tr>
+              <td>Logback MarkerFilter</td>
+              <td>17</td>
+              <td>24</td>
+              <td>59</td>
+              <td>115</td>
+              <td>234</td>
+              <td>547</td>
+            </tr>
+             <tr>
+              <td>Log4j 2 MarkerFilter</td>
+              <td>4</td>
+              <td>5</td>
+              <td>7</td>
+              <td>20</td>
+              <td>35</td>
+              <td>92</td>
+            </tr>
+          </table>
+        </li>
+
+      </ol>
+      <p>
+        The performance results above were all derived from running the DebugDisabledPerformanceComparison,
+        FilterPerformanceComparison, and PerformanceComparison junit tests which can be found in the
+        Log4j 2 unit test source directory.
+      </p>
+    </section>
+  </body>
+</document>
\ No newline at end of file



Mime
View raw message