[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch master updated. v_1.0.2-5-gdf62eeb

Gitbot git-noreply at pixie.qos.ch
Thu May 3 15:35:16 CEST 2012


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".

The branch, master has been updated
       via  df62eebfa7bbd7053a84aca740ed8aa63c548315 (commit)
       via  174573f53b1e2cc878ac846efb3c83abede1574b (commit)
       via  09aee6ec5a27a4be4ae7250ffeed2b058c812346 (commit)
      from  8b064299b7d22094542777b0617290e3e4625850 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=df62eebfa7bbd7053a84aca740ed8aa63c548315
http://github.com/ceki/logback/commit/df62eebfa7bbd7053a84aca740ed8aa63c548315

commit df62eebfa7bbd7053a84aca740ed8aa63c548315
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Thu May 3 15:34:32 2012 +0200

    fix LBCORE-243

diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
index 5f15b8e..f186f9d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
@@ -1,12 +1,5 @@
 package ch.qos.logback.classic.issue.lbcore243;
 
-/**
- * Created with IntelliJ IDEA.
- * User: ceki
- * Date: 27.04.12
- * Time: 00:05
- * To change this template use File | Settings | File Templates.
- */
 public class Common {
 
    // How many times should we try to log:
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
index 0be7c6f..e1e5c0d 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
@@ -1,12 +1,6 @@
 package ch.qos.logback.classic.issue.lbcore243;
 
-/**
- * Created with IntelliJ IDEA.
- * User: ceki
- * Date: 26.04.12
- * Time: 21:52
- * To change this template use File | Settings | File Templates.
- */
+
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.joran.JoranConfigurator;
 import ch.qos.logback.core.joran.spi.JoranException;
@@ -14,6 +8,10 @@ import org.apache.log4j.xml.DOMConfigurator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
+// WARNING This code compiles but does not measure anything useful because log4j-over-slf4j is a dependency. Log4j
+// should be used instead
+
 public class PerformanceComparatorLog4j {
 
    static org.apache.log4j.Logger log4jlogger = org.apache.log4j.Logger.getLogger(PerformanceComparatorLog4j.class);
@@ -24,7 +22,6 @@ public class PerformanceComparatorLog4j {
      // Let's run once for Just In Time compiler
      log4jDirectDebugCall();
 
-
      System.out.println("###############################################");
      System.out.println("Log4j    without immediate flush: " + log4jDirectDebugCall()+ " nanos per call");
      System.out.println("###############################################");
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
index b6c40fb..aacc7c6 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
@@ -14,6 +14,10 @@ import ch.qos.logback.core.joran.spi.JoranException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+// Results AMD Phenom II X6 1110T processor and SSD disk
+//Logback  with    immediate flush: 8356 nanos per call
+//Logback  without immediate flush: 1758 nanos per call
+
 public class PerformanceComparatorLogback {
   static Logger logbacklogger = LoggerFactory.getLogger(PerformanceComparatorLogback.class);
 
@@ -21,8 +25,14 @@ public class PerformanceComparatorLogback {
     initLogbackWithoutImmediateFlush();
     logbackParametrizedDebugCall();
 
+    initLogbackWithImmediateFlush();
+    logbackParametrizedDebugCall();
     System.out.println("###############################################");
+    System.out.println("Logback  with    immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
+
+    initLogbackWithoutImmediateFlush();
     System.out.println("Logback  without immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
+
     System.out.println("###############################################");
   }
 
@@ -38,13 +48,21 @@ public class PerformanceComparatorLogback {
 
   static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
 
-  private static void initLogbackWithoutImmediateFlush() throws JoranException {
+
+  static void configure(String file)  throws JoranException {
     LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
-    JoranConfigurator jc = new JoranConfigurator();
-    jc.setContext(loggerContext);
-    loggerContext.reset();
-    jc.doConfigure(DIR_PREFIX + "logback.xml");
+      JoranConfigurator jc = new JoranConfigurator();
+      jc.setContext(loggerContext);
+      loggerContext.reset();
+      jc.doConfigure(file);
   }
 
 
+  private static void initLogbackWithoutImmediateFlush() throws JoranException {
+    configure(DIR_PREFIX + "logback_without_immediateFlush.xml");
+  }
+
+  private static void initLogbackWithImmediateFlush() throws JoranException {
+    configure(DIR_PREFIX + "logback_with_immediateFlush.xml");
+  }
 }
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_with_immediateFlush.xml
similarity index 74%
copy from logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml
copy to logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_with_immediateFlush.xml
index c4978f7..ec34915 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_with_immediateFlush.xml
@@ -1,8 +1,8 @@
 <configuration>
   <appender name="TestLogfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
-    <file>d:/test/logback_without_flush.log</file>
+    <file>target/test-output/perf/logback_with_flush.log</file>
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
-      <fileNamePattern>d:/test/logback_without_flush.log.%i</fileNamePattern>
+      <fileNamePattern>target/test-output/perf/logback_with_flush.log.%i</fileNamePattern>
       <minIndex>1</minIndex>
       <maxIndex>1</maxIndex>
     </rollingPolicy>
@@ -11,7 +11,7 @@
     </triggeringPolicy>
     <encoder>
       <Pattern>%d{ISO8601} %5p [%t] %c - %m%n</Pattern>
-      <immediateFlush>false</immediateFlush>
+      <immediateFlush>true</immediateFlush>
       <!--<charset>UTF-8</charset>-->
     </encoder>
   </appender>
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_without_immediateFlush.xml
similarity index 79%
rename from logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml
rename to logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_without_immediateFlush.xml
index c4978f7..3d4f49e 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_without_immediateFlush.xml
@@ -1,8 +1,8 @@
 <configuration>
   <appender name="TestLogfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
-    <file>d:/test/logback_without_flush.log</file>
+    <file>target/test-output/perf/logback_without_flush.log</file>
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
-      <fileNamePattern>d:/test/logback_without_flush.log.%i</fileNamePattern>
+      <fileNamePattern>target/test-output/perf/logback_without_flush.log.%i</fileNamePattern>
       <minIndex>1</minIndex>
       <maxIndex>1</maxIndex>
     </rollingPolicy>
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
index 2784676..0ac7d31 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
@@ -26,6 +26,7 @@ public class EchoEncoder<E> extends EncoderBase<E> {
   public void doEncode(E event) throws IOException {
     String val = event + CoreConstants.LINE_SEPARATOR;
     outputStream.write(val.getBytes());
+    // necessary if ResilientFileOutputStream is buffered
     outputStream.flush();
   }
 
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
index 1dee67a..fa5cfab 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java
@@ -34,7 +34,7 @@ abstract public class PatternLayoutBase<E> extends LayoutBase<E> {
 
 
   Map<String, String> instanceConverterMap = new HashMap<String, String>();
-  protected boolean outputPatternAsPresentationHeader = true;
+  protected boolean outputPatternAsHeader = true;
 
   /**
    * Concrete implementations of this class are responsible for elaborating the
@@ -144,20 +144,19 @@ abstract public class PatternLayoutBase<E> extends LayoutBase<E> {
     return CoreConstants.EMPTY_STRING;
   }
 
-  public boolean isOutputPatternAsPresentationHeader() {
-    return outputPatternAsPresentationHeader;
+  public boolean isOutputPatternAsHeader() {
+    return outputPatternAsHeader;
   }
 
-  public void setOutputPatternAsPresentationHeader(boolean outputPatternAsPresentationHeader) {
-    this.outputPatternAsPresentationHeader = outputPatternAsPresentationHeader;
+  public void setOutputPatternAsHeader(boolean outputPatternAsHeader) {
+    this.outputPatternAsHeader = outputPatternAsHeader;
   }
-  
+
   @Override
   public String getPresentationHeader() {
-    if(outputPatternAsPresentationHeader)
+    if(outputPatternAsHeader)
       return getPresentationHeaderPrefix()+pattern;
     else
       return super.getPresentationHeader();
-
   }
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java
index eaccd55..a094dcc 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutEncoderBase.java
@@ -19,7 +19,9 @@ import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
 public class PatternLayoutEncoderBase<E> extends LayoutWrappingEncoder<E> {
 
   String pattern;
-  protected boolean outputPatternAsPresentationHeader = true;
+
+  // due to popular demand outputPatternAsHeader is set to false by default
+  protected boolean outputPatternAsHeader = false;
 
   public String getPattern() {
     return pattern;
@@ -29,12 +31,32 @@ public class PatternLayoutEncoderBase<E> extends LayoutWrappingEncoder<E> {
     this.pattern = pattern;
   }
 
+  public boolean isOutputPatternAsHeader() {
+    return outputPatternAsHeader;
+  }
+
+
+  /**
+   * Print the pattern string as a header in log files
+   *
+   * @param outputPatternAsHeader
+   * @since 1.0.3
+   */
+  public void setOutputPatternAsHeader(boolean outputPatternAsHeader) {
+    this.outputPatternAsHeader = outputPatternAsHeader;
+  }
+
+
   public boolean isOutputPatternAsPresentationHeader() {
-    return outputPatternAsPresentationHeader;
+    return outputPatternAsHeader;
   }
 
-  public void setOutputPatternAsPresentationHeader(boolean outputPatternAsPresentationHeader) {
-    this.outputPatternAsPresentationHeader = outputPatternAsPresentationHeader;
+  /**
+   * @deprecated replaced by {@link #setOutputPatternAsHeader(boolean)}
+   */
+  public void setOutputPatternAsPresentationHeader(boolean outputPatternAsHeader) {
+    addWarn("outputPatternAsPresentationHeader option is deprecated. Use outputPatternAsHeader option instead.");
+    this.outputPatternAsHeader = outputPatternAsHeader;
   }
 
   @Override
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index 86f640d..26126fe 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -8,11 +8,12 @@
     <link rel="stylesheet" type="text/css" href="css/common.css" />
     <link rel="stylesheet" type="text/css" href="css/screen.css" media="screen" />
     <link rel="stylesheet" type="text/css" href="css/_print.css" media="print" />
-    
+    <link rel="stylesheet" type="text/css" href="css/prettify.css" media="screen" />    
   </head>
-  <body>
-    <script type="text/javascript">prefix='';</script>
 
+  <body onload="prettyPrint()">
+    <script type="text/javascript">prefix='';</script>
+    <script type="text/javascript" src="js/prettify.js"></script>
     <script src="templates/header.js" type="text/javascript"></script>
     <div id="left">
       <noscript>Please turn on Javascript to view this menu</noscript>
@@ -29,20 +30,35 @@
 
     <hr width="80%" align="center" />
 
-    <h3>26th of April, 2012 - Release of version 1.0.2</h3>
+    <h3>3rd of May, 2012 - Release of version 1.0.3</h3>
 
-    <div style="border: 1px solid #F44; background-color: #FED; padding-left: 1ex; padding-right: 1ex;">
+    <p><code>PatternLayoutEncoder</code> now admits the <span
+    class="option">immediateFlush</span> option (set to true by
+    default). By setting this option to false, logging throughput can
+    be quadrupled, although your mileage may vary. This option was
+    requested in <a
+    href="http://jira.qos.ch/browse/LBCORE-243">LBCORE-243</a>.
+    </p>
 
-    <h4>Breaking change: <code>PatternLayout</code> will now output
-    its pattern at the top of log files</h4>
 
-    <p>In order to facilitate parsing of log files, logback now
-    inserts the pattern used for the log output at the top of each log
-    file. This feature was requested by James Strachan in <a
+    <p>In order to facilitate parsing of log files, logback can now
+    insert the pattern used for the log output at the top of log
+    files. This feature was requested by James Strachan in <a
     href="http://jira.qos.ch/browse/LBCORE-234">LBCORE-234</a>.
-    </p>
+    However, this feature is <b>not</b> enabled by default. It can be
+    enabled by setting the <span
+    class="option">outputPatternAsHeader</span> option to 'true' for
+    the relevant encoder. Here is an example:</p>
 
-    <p>Here an example:</p>
+<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
+  <file>foo.log</file>
+  <encoder>
+    <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
+    <b><outputPatternAsHeader>true</outputPatternAsHeader></b>
+  </encoder> 
+</appender></pre>
+    
+    <p>This will result output akin to the following in the log file:</p>
 
     <pre>#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n
 2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hello world
@@ -52,17 +68,18 @@
      <p>The line starting with "#logback.classic pattern" is newly
      inserted pattern line.</p>
 
-     <p>If you wish to disable printing this line, set the
-     <span class="option">outputPatternAsPresentationHeader</span> option to false for the
-     relevant encoder. Here is an example:</p>
+    <h3>26th of April, 2012 - Release of version 1.0.2</h3>
+
+    <div style="border: 1px solid #F44; background-color: #FED; padding-left: 1ex; padding-right: 1ex;">
+
+    <h4><span class="label">Breaking change partially reverted in
+    1.0.3</span><br/>By default <code>PatternLayout</code> will now output
+    its pattern at the top of log files</h4>
+
+    <p>This feature, although still available, is no longer enabled by
+    default. See release 1.0.3 for details.
+    </p>
 
-<pre><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-  <encoder>
-    <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
-   <b><-- do not print pattern as a header --></b>
-   <b><outputPatternAsPresentationHeader>false</outputPatternAsPresentationHeader></b>
-  </encoder>
-</appender> </pre>
 
     </div>
     

http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=174573f53b1e2cc878ac846efb3c83abede1574b
http://github.com/ceki/logback/commit/174573f53b1e2cc878ac846efb3c83abede1574b

commit 174573f53b1e2cc878ac846efb3c83abede1574b
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Wed May 2 21:55:07 2012 +0200

    Fixing LBCORE-243 by reintroducing buffered streaming and immediate flush as an option

diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
new file mode 100644
index 0000000..5f15b8e
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
@@ -0,0 +1,15 @@
+package ch.qos.logback.classic.issue.lbcore243;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: ceki
+ * Date: 27.04.12
+ * Time: 00:05
+ * To change this template use File | Settings | File Templates.
+ */
+public class Common {
+
+   // How many times should we try to log:
+   static int loop = 800*1000;
+
+}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
new file mode 100644
index 0000000..0be7c6f
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
@@ -0,0 +1,52 @@
+package ch.qos.logback.classic.issue.lbcore243;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: ceki
+ * Date: 26.04.12
+ * Time: 21:52
+ * To change this template use File | Settings | File Templates.
+ */
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PerformanceComparatorLog4j {
+
+   static org.apache.log4j.Logger log4jlogger = org.apache.log4j.Logger.getLogger(PerformanceComparatorLog4j.class);
+
+   public static void main(String[] args) throws JoranException, InterruptedException {
+     initLog4jWithoutImmediateFlush();
+
+     // Let's run once for Just In Time compiler
+     log4jDirectDebugCall();
+
+
+     System.out.println("###############################################");
+     System.out.println("Log4j    without immediate flush: " + log4jDirectDebugCall()+ " nanos per call");
+     System.out.println("###############################################");
+   }
+
+   private static long log4jDirectDebugCall() {
+     Integer j = new Integer(2);
+     long start = System.nanoTime();
+     for (int i = 0; i < Common.loop; i++) {
+       log4jlogger.debug("SEE IF THIS IS LOGGED " + j + ".");
+     }
+     return (System.nanoTime() - start) / Common.loop;
+   }
+
+   static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
+
+   static void initLog4jWithoutImmediateFlush() {
+     DOMConfigurator domConfigurator = new DOMConfigurator();
+     domConfigurator.configure(DIR_PREFIX+"log4j_without_immediateFlush.xml");
+   }
+   static void initLog4jWithImmediateFlush() {
+     DOMConfigurator domConfigurator = new DOMConfigurator();
+     domConfigurator.configure(DIR_PREFIX+"log4j_with_immediateFlush.xml");
+   }
+}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
new file mode 100644
index 0000000..b6c40fb
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
@@ -0,0 +1,50 @@
+package ch.qos.logback.classic.issue.lbcore243;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: ceki
+ * Date: 26.04.12
+ * Time: 21:52
+ * To change this template use File | Settings | File Templates.
+ */
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PerformanceComparatorLogback {
+  static Logger logbacklogger = LoggerFactory.getLogger(PerformanceComparatorLogback.class);
+
+  public static void main(String[] args) throws JoranException, InterruptedException {
+    initLogbackWithoutImmediateFlush();
+    logbackParametrizedDebugCall();
+
+    System.out.println("###############################################");
+    System.out.println("Logback  without immediate flush: " + logbackParametrizedDebugCall() + " nanos per call");
+    System.out.println("###############################################");
+  }
+
+  private static long logbackParametrizedDebugCall() {
+
+    Integer j = new Integer(2);
+    long start = System.nanoTime();
+    for (int i = 0; i < Common.loop; i++) {
+      logbacklogger.debug("SEE IF THIS IS LOGGED {}.", j);
+    }
+    return (System.nanoTime() - start) / Common.loop;
+  }
+
+  static String DIR_PREFIX = "src/test/java/ch/qos/logback/classic/issue/lbcore243/";
+
+  private static void initLogbackWithoutImmediateFlush() throws JoranException {
+    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+    JoranConfigurator jc = new JoranConfigurator();
+    jc.setContext(loggerContext);
+    loggerContext.reset();
+    jc.doConfigure(DIR_PREFIX + "logback.xml");
+  }
+
+
+}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_with_immediateFlush.xml b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_with_immediateFlush.xml
new file mode 100644
index 0000000..d885b58
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_with_immediateFlush.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+  <appender name="TestLogfile" class="org.apache.log4j.RollingFileAppender">
+    <param name="File" value="d:/test/log4j_with_flush.log"/>
+    <param name="MaxFileSize" value="1000KB"/>
+    <param name="maxBackupIndex" value="1"/>
+    <param name="immediateFlush" value="true"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d{ISO8601} %5p [%t] %c %X{transactionId} - %m%n"/>
+    </layout>
+  </appender>
+  <root>
+    <level value="debug"/>
+    <appender-ref ref="TestLogfile"/>
+  </root>
+</log4j:configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_without_immediateFlush.xml b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_without_immediateFlush.xml
new file mode 100644
index 0000000..51ed4f0
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_without_immediateFlush.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+  <appender name="TestLogfile" class="org.apache.log4j.RollingFileAppender">
+    <param name="File" value="c:/test/log4j_without_flush.log"/>
+    <param name="MaxFileSize" value="1000KB"/>
+    <param name="maxBackupIndex" value="1"/>
+    <param name="immediateFlush" value="false"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d{ISO8601} %5p [%t] %c %X{transactionId} - %m%n"/>
+    </layout>
+  </appender>
+  <root>
+    <level value="debug"/>
+    <appender-ref ref="TestLogfile"/>
+  </root>
+</log4j:configuration>
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml
new file mode 100644
index 0000000..c4978f7
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback.xml
@@ -0,0 +1,22 @@
+<configuration>
+  <appender name="TestLogfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>d:/test/logback_without_flush.log</file>
+    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+      <fileNamePattern>d:/test/logback_without_flush.log.%i</fileNamePattern>
+      <minIndex>1</minIndex>
+      <maxIndex>1</maxIndex>
+    </rollingPolicy>
+    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>1000KB</maxFileSize>
+    </triggeringPolicy>
+    <encoder>
+      <Pattern>%d{ISO8601} %5p [%t] %c - %m%n</Pattern>
+      <immediateFlush>false</immediateFlush>
+      <!--<charset>UTF-8</charset>-->
+    </encoder>
+  </appender>
+  <root>
+    <level value="debug"/>
+    <appender-ref ref="TestLogfile"/>
+  </root>
+</configuration>
\ No newline at end of file
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
index 7e72707..2784676 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EchoEncoder.java
@@ -26,6 +26,7 @@ public class EchoEncoder<E> extends EncoderBase<E> {
   public void doEncode(E event) throws IOException {
     String val = event + CoreConstants.LINE_SEPARATOR;
     outputStream.write(val.getBytes());
+    outputStream.flush();
   }
 
   public void close() throws IOException {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java
index c030ee1..e7ac7aa 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/LayoutWrappingEncoder.java
@@ -27,13 +27,33 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
 
   /**
    * The charset to use when converting a String into bytes.
-   * <p>
+   * <p/>
    * By default this property has the value
-   * <code>null</null> which corresponds to 
+   * <code>null</null> which corresponds to
    * the system's default charset.
    */
   private Charset charset;
 
+  private boolean immediateFlush = true;
+
+
+  /**
+   * Sets the immediateFlush option. The default value for immediateFlush is 'true'. If set to true,
+   * the doEncode() method will immediately flush the underlying OutputStream. Although immediate flushing
+   * is safer, it also significantly degrades logging throughput.
+   *
+   * @since 1.0.3
+   */
+  public void setImmediateFlush(boolean immediateFlush) {
+    this.immediateFlush = immediateFlush;
+  }
+
+
+  public boolean isImmediateFlush() {
+    return immediateFlush;
+  }
+
+
   public Layout<E> getLayout() {
     return layout;
   }
@@ -49,11 +69,11 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
   /**
    * Set the charset to use when converting the string returned by the layout
    * into bytes.
-   * <p>
+   * <p/>
    * By default this property has the value
-   * <code>null</null> which corresponds to 
+   * <code>null</null> which corresponds to
    * the system's default charset.
-   * 
+   *
    * @param charset
    */
   public void setCharset(Charset charset) {
@@ -94,7 +114,6 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
         outputStream.write(convertToBytes(sb.toString()));
         outputStream.flush();
       }
-
     }
   }
 
@@ -106,7 +125,7 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
         return s.getBytes(charset.name());
       } catch (UnsupportedEncodingException e) {
         throw new IllegalStateException(
-            "An existing charset cannot possibly be unsupported.");
+                "An existing charset cannot possibly be unsupported.");
       }
     }
   }
@@ -114,7 +133,8 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
   public void doEncode(E event) throws IOException {
     String txt = layout.doLayout(event);
     outputStream.write(convertToBytes(txt));
-    outputStream.flush();
+    if (immediateFlush)
+      outputStream.flush();
   }
 
   public boolean isStarted() {
@@ -127,6 +147,12 @@ public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
 
   public void stop() {
     started = false;
+    if(outputStream != null) {
+      try {
+        outputStream.flush();
+      } catch (IOException e) {
+      }
+    }
   }
 
   private void appendIfNotNull(StringBuilder sb, String s) {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
index 60c7245..9710042 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
@@ -13,21 +13,20 @@
  */
 package ch.qos.logback.core.recovery;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.io.*;
 import java.nio.channels.FileChannel;
 
 public class ResilientFileOutputStream extends ResilientOutputStreamBase {
 
-  File file;
+  private File file;
+  private FileOutputStream fos;
+
 
   public ResilientFileOutputStream(File file, boolean append)
       throws FileNotFoundException {
     this.file = file;
-    this.os = new FileOutputStream(file, append);
+    fos = new FileOutputStream(file, append);
+    this.os = new BufferedOutputStream(fos);
     this.presumedClean = true;
   }
 
@@ -35,7 +34,6 @@ public class ResilientFileOutputStream extends ResilientOutputStreamBase {
     if (os == null) {
       return null;
     }
-    final FileOutputStream fos = (FileOutputStream) os;
     return fos.getChannel();
   }
 
diff --git a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
index c665dc1..088ead5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
@@ -16,6 +16,7 @@ package ch.qos.logback.core.rolling;
 import java.io.File;
 
 import ch.qos.logback.core.util.FileSize;
+import ch.qos.logback.core.util.InvocationGate;
 
 /**
  * SizeBasedTriggeringPolicy looks at size of the file being currently written
@@ -46,17 +47,14 @@ public class SizeBasedTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
     setMaxFileSize(maxFileSize);
   }
 
-  // IMPORTANT: This field can be updated by multiple threads. It follows that
-  // its values may *not* be incremented sequentially. However, we don't care
-  // about the actual value of the field except that from time to time the
-  // expression (invocationCounter++ & 0xF) == 0xF) should be true.
-  private int invocationCounter = 0xF;
+  private InvocationGate invocationGate = new InvocationGate();
 
   public boolean isTriggeringEvent(final File activeFile, final E event) {
-    // for performance reasons, check for changes every 16 invocations
-    if (((invocationCounter++) & 0xF) != 0xF) {
+  if(invocationGate.skipFurtherWork())
       return false;
-    }
+
+    long now = System.currentTimeMillis();
+    invocationGate.updateMaskIfNecessary(now);
 
     return (activeFile.length() >= maxFileSize.getSize());
   }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java b/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java
new file mode 100644
index 0000000..8e00df5
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java
@@ -0,0 +1,48 @@
+package ch.qos.logback.core.util;
+
+/**
+ * This class serves as a gateway for invocations of a "costly" operation on a critical execution path.
+ *
+ * @author Ceki Gülcü
+ */
+public class InvocationGate {
+
+  // experiments indicate that even for the most CPU intensive applications with 200 or more threads MASK
+  // values in the order of 0xFFFF is appropriate
+  private static final int MAX_MASK = 0xFFFF;
+
+  private volatile long mask = 0xF;
+  private volatile long lastMaskCheck = System.currentTimeMillis();
+
+
+   // IMPORTANT: This field can be updated by multiple threads. It follows that
+  // its values may *not* be incremented sequentially. However, we don't care
+  // about the actual value of the field except that from time to time the
+  // expression (invocationCounter++ & mask) == mask) should be true.
+  private long invocationCounter = 0;
+
+
+  // if less than thresholdForMaskIncrease milliseconds elapse between invocations of updateMaskIfNecessary()
+  // method, then the mask should be increased
+  private static final long thresholdForMaskIncrease = 100;
+
+  // if more than thresholdForMaskDecrease milliseconds elapse between invocations of updateMaskIfNecessary() method,
+  // then the mask should be decreased
+  private final long thresholdForMaskDecrease = thresholdForMaskIncrease*8;
+
+
+  public boolean skipFurtherWork() {
+     return ((invocationCounter++) & mask) != mask;
+  }
+
+  // update the mask so as to execute change detection code about once every 100 to 8000 milliseconds.
+  public void updateMaskIfNecessary(long now) {
+    final long timeElapsedSinceLastMaskUpdateCheck = now - lastMaskCheck;
+    lastMaskCheck = now;
+    if (timeElapsedSinceLastMaskUpdateCheck < thresholdForMaskIncrease && (mask < MAX_MASK)) {
+      mask = (mask << 1) | 1;
+    } else if (timeElapsedSinceLastMaskUpdateCheck > thresholdForMaskDecrease) {
+      mask = mask >>> 2;
+    }
+  }
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
index 88d4de9..40a99d7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
@@ -17,6 +17,7 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.channels.FileChannel;
 
+import ch.qos.logback.core.util.StatusPrinter;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -86,8 +87,9 @@ public class FileAppenderResilienceTest {
 
     double bestCaseSuccessRatio = 1/delayCoefficient;
     double lossinessFactor = 0.8;
+
     ResilienceUtil
-        .verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter(), bestCaseSuccessRatio * lossinessFactor);
+              .verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter(), bestCaseSuccessRatio * lossinessFactor);
   }
 
   private void closeLogFileOnPurpose() throws IOException {
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java b/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
index fc4c2ab..c051065 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
@@ -39,7 +39,7 @@ public class ResilienceUtil {
         totalLines++;
         String g = m.group(1);
         int num = Integer.parseInt(g);
-        if(num != oldNum+1) {
+        if(oldNum != -1 && num != oldNum+1) {
           gaps++;
         }
         oldNum = num;
@@ -51,8 +51,8 @@ public class ResilienceUtil {
     int lowerLimit = (int) (totalSteps*successRatioLowerBound);
     assertTrue("totalLines="+totalLines+" less than "+lowerLimit, totalLines > lowerLimit);
     
-    // we want some gaps which indicate recuperation
-    assertTrue("gaps="+gaps+" less than 3", gaps >= 3);
+    // we want at least one gap indicating recuperation
+    assertTrue("gaps="+gaps+" less than 1", gaps >= 1);
     
   }
 }
diff --git a/logback-core/src/test/scala/ch/qos/logback/core/rolling/SizeBasedRolling_STest.scala b/logback-core/src/test/scala/ch/qos/logback/core/rolling/SizeBasedRolling_STest.scala
index ebeff2b..c9002ad 100644
--- a/logback-core/src/test/scala/ch/qos/logback/core/rolling/SizeBasedRolling_STest.scala
+++ b/logback-core/src/test/scala/ch/qos/logback/core/rolling/SizeBasedRolling_STest.scala
@@ -80,6 +80,7 @@ class SizeBasedRolling_STest extends RollingScaffolding {
       Thread.sleep(10)
       rfa.doAppend(prefix + i)
     }
+    rfa.stop()
 
     existenceCheck(expectedFilenameList)
     reverseSortedContentCheck(randomOutputDir, runLength, prefix)
diff --git a/logback-core/src/test/scala/ch/qos/logback/core/rolling/TimeBasedRolling_STest.scala b/logback-core/src/test/scala/ch/qos/logback/core/rolling/TimeBasedRolling_STest.scala
index ce09a22..64c7cad 100644
--- a/logback-core/src/test/scala/ch/qos/logback/core/rolling/TimeBasedRolling_STest.scala
+++ b/logback-core/src/test/scala/ch/qos/logback/core/rolling/TimeBasedRolling_STest.scala
@@ -132,6 +132,7 @@ class TimeBasedRolling_STest extends RollingScaffolding {
       incCurrentTime(100)
       tbrp2.timeBasedFileNamingAndTriggeringPolicy.setCurrentTime(currentTime)
     }
+    rfa2.stop();
   }
 
   val NO_RESTART = 0
diff --git a/logback-site/src/site/pages/templates/header.js b/logback-site/src/site/pages/templates/header.js
index 4ee3250..96a6a46 100644
--- a/logback-site/src/site/pages/templates/header.js
+++ b/logback-site/src/site/pages/templates/header.js
@@ -5,7 +5,11 @@ document.write('</a></td>')
 
 document.write('<td> </td>');
 
+document.write('<td width=70%"><span style="font-weight: bold;  font-size: medium;  background-color: #FFDDDD">Due to an error, <a href="http://repo1.maven.org/maven2/ch/qos/logback/logback-classic/maven-metadata.xml">metadata</a> for logback on Maven central only mentions version 1.0.2. As such such, "mvn" can no longer fetch earlier versions of logback from Maven central. Until this issue is resolved, one simple workaround is to upgrade to logback 1.0.2 in your project' pom.xml file. Please also vote for <a href="https://issues.sonatype.org/browse/OSSRH-3437">OSSRH-3437</a>.</span></td>');
+
 document.write('</tr></table>')
 
 
 document.write('<div id="headerLine"></div>');
+
+

http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=09aee6ec5a27a4be4ae7250ffeed2b058c812346
http://github.com/ceki/logback/commit/09aee6ec5a27a4be4ae7250ffeed2b058c812346

commit 09aee6ec5a27a4be4ae7250ffeed2b058c812346
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Wed May 2 21:53:30 2012 +0200

    The ConsoleAppender created by BasicConfigurator should not output its pattern string

diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
index 8c8de83..6890b9e 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
@@ -46,6 +46,7 @@ public class BasicConfigurator {
     ca.setName("console");
     PatternLayoutEncoder pl = new PatternLayoutEncoder();
     pl.setContext(lc);
+    pl.setOutputPatternAsPresentationHeader(false);
     pl.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
     pl.start();
 

-----------------------------------------------------------------------

Summary of changes:
 .../ch/qos/logback/classic/BasicConfigurator.java  |    1 +
 .../logback/classic/issue/lbcore243/Common.java    |    8 ++
 .../lbcore243/PerformanceComparatorLog4j.java      |   49 ++++++++++++++
 .../lbcore243/PerformanceComparatorLogback.java    |   68 ++++++++++++++++++++
 .../issue/lbcore243/log4j_with_immediateFlush.xml  |   17 +++++
 .../lbcore243/log4j_without_immediateFlush.xml     |   17 +++++
 .../lbcore243/logback_with_immediateFlush.xml      |   22 ++++++
 .../lbcore243/logback_without_immediateFlush.xml   |   22 ++++++
 .../ch/qos/logback/core/encoder/EchoEncoder.java   |    2 +
 .../core/encoder/LayoutWrappingEncoder.java        |   42 ++++++++++--
 .../logback/core/pattern/PatternLayoutBase.java    |   15 ++--
 .../core/pattern/PatternLayoutEncoderBase.java     |   30 ++++++++-
 .../core/recovery/ResilientFileOutputStream.java   |   14 ++--
 .../core/rolling/SizeBasedTriggeringPolicy.java    |   14 ++--
 .../ch/qos/logback/core/util/InvocationGate.java   |   48 ++++++++++++++
 .../logback/core/FileAppenderResilienceTest.java   |    4 +-
 .../ch/qos/logback/core/util/ResilienceUtil.java   |    6 +-
 .../core/rolling/SizeBasedRolling_STest.scala      |    1 +
 .../core/rolling/TimeBasedRolling_STest.scala      |    1 +
 logback-site/src/site/pages/news.html              |   61 +++++++++++------
 logback-site/src/site/pages/templates/header.js    |    4 +
 21 files changed, 384 insertions(+), 62 deletions(-)
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/Common.java
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLog4j.java
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/PerformanceComparatorLogback.java
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_with_immediateFlush.xml
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/log4j_without_immediateFlush.xml
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_with_immediateFlush.xml
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/issue/lbcore243/logback_without_immediateFlush.xml
 create mode 100644 logback-core/src/main/java/ch/qos/logback/core/util/InvocationGate.java


hooks/post-receive
-- 
Logback: the generic, reliable, fast and flexible logging framework.


More information about the logback-dev mailing list