[logback-dev] svn commit: r1974 - in logback/trunk: logback-classic/src/test/java/ch/qos/logback/classic/multiJVM logback-core/src/main/java/ch/qos/logback/core logback-core/src/main/java/ch/qos/logback/core/rolling logback-core/src/main/java/ch/qos/logback/core/rolling/helper logback-core/src/test/java/ch/qos/logback/core/appender logback-core/src/test/java/ch/qos/logback/core/rolling logback-examples/src/main/java/chapter4/conf logback-site/src/site/pages logback-site/src/site/pages/css logback-site/src/site/pages/manual

noreply.ceki at qos.ch noreply.ceki at qos.ch
Mon Nov 17 15:45:23 CET 2008


Author: ceki
Date: Mon Nov 17 15:45:23 2008
New Revision: 1974

Added:
   logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
   logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
   logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-PrudentTimeBasedRolling.xml
Modified:
   logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
   logback/trunk/logback-site/src/site/pages/codes.html
   logback/trunk/logback-site/src/site/pages/css/common.css
   logback/trunk/logback-site/src/site/pages/manual/appenders.html
   logback/trunk/logback-site/src/site/pages/manual/joran.html
   logback/trunk/logback-site/src/site/pages/manual/layouts.html
   logback/trunk/logback-site/src/site/pages/news.html

Log:
Added support for file appending in prudent mode. Thus, multiple FileAppender 
instances running on multiple JVMs can safely write to the same log file. With 
certain limitations, prudent mode extends to RollingFileAppender. 

Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java	Mon Nov 17 15:45:23 2008
@@ -0,0 +1,96 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2008, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.classic.multiJVM;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.FileAppender;
+import ch.qos.logback.core.testUtil.RandomUtil;
+
+public class FileAppenderPerf {
+  static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
+
+  static long LEN = 100 * 1000;
+  static int DIFF = RandomUtil.getPositiveInt() % 1000;
+  static String FILENAME;
+
+  static LoggerContext buildLoggerContext(String filename, boolean safetyMode) {
+    LoggerContext loggerContext = new LoggerContext();
+
+    FileAppender<LoggingEvent> fa = new FileAppender<LoggingEvent>();
+
+    PatternLayout patternLayout = new PatternLayout();
+    patternLayout.setPattern("%5p %c - %m%n");
+    patternLayout.setContext(loggerContext);
+    patternLayout.start();
+
+    fa.setLayout(patternLayout);
+    fa.setFile(filename);
+    fa.setAppend(false);
+    fa.setImmediateFlush(true);
+    fa.setBufferedIO(false);
+    fa.setPrudent(safetyMode);
+    fa.setContext(loggerContext);
+    fa.start();
+
+    ch.qos.logback.classic.Logger root = loggerContext
+        .getLogger(LoggerContext.ROOT_NAME);
+    root.addAppender(fa);
+
+    return loggerContext;
+  }
+
+  static void usage(String msg) {
+    System.err.println(msg);
+    System.err.println("Usage: java " + FileAppenderPerf.class.getName()
+        + " filename");
+
+    System.exit(1);
+  }
+
+  public static void main(String[] argv) throws Exception {
+    if (argv.length > 1) {
+      usage("Wrong number of arguments.");
+    }
+
+    if (argv.length == 0) {
+      FILENAME = DIFF+"";
+    } else {
+      FILENAME = argv[0];
+    }
+
+    perfCase(false);
+    perfCase(true);
+  }
+
+  static void perfCase(boolean safetyMode) throws Exception {
+    LoggerContext lc = buildLoggerContext(FILENAME + "-" + safetyMode + ".log",
+        safetyMode);
+    Logger logger = lc.getLogger(FileAppenderPerf.class);
+
+    long start = System.nanoTime();
+    for (int i = 0; i < LEN; i++) {
+      logger.debug(msgLong + " " + i);
+    }
+    // in microseconds
+    double durationPerLog = (System.nanoTime() - start) / (LEN * 1000.0);
+
+    lc.stop();
+
+    System.out.println("Average duration of " + (durationPerLog)
+        + " microseconds per log. Prudent mode=" + safetyMode);
+    System.out.println("------------------------------------------------");
+  }
+
+}

Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java	(original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java	Mon Nov 17 15:45:23 2008
@@ -65,7 +65,7 @@
     fa.setAppend(true);
     fa.setImmediateFlush(true);
     fa.setBufferedIO(false);
-    fa.setSafeMode(safetyMode);
+    fa.setPrudent(safetyMode);
     fa.setContext(loggerContext);
     fa.start();
 

Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java	Mon Nov 17 15:45:23 2008
@@ -0,0 +1,110 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2008, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package ch.qos.logback.classic.multiJVM;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.rolling.RollingFileAppender;
+import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
+import ch.qos.logback.core.util.StatusPrinter;
+
+/**
+ * An application to write to a file using a RollingFileAppender in safe mode.
+ * 
+ * @author Ceki Gulcu
+ * 
+ */
+public class SafeModeRollingFileAppender {
+
+  static long LEN;
+  static String FILENAME;
+  static String STAMP;
+  
+  static final String DATE_PATTERN = "yyyy-MM-dd_HH_mm_ss";
+
+  static public void main(String[] argv) throws Exception {
+    if (argv.length != 3) {
+      usage("Wrong number of arguments.");
+    }
+
+    STAMP = argv[0];
+    LEN = Integer.parseInt(argv[1]);
+    FILENAME = argv[2];
+    writeContinously(STAMP, FILENAME, true);
+  }
+
+  static void usage(String msg) {
+    System.err.println(msg);
+    System.err.println("Usage: java " + SafeModeRollingFileAppender.class.getName()
+        + " stamp runLength filename\n" + " stamp JVM instance stamp\n"
+        + "   runLength (integer) the number of logs to generate perthread"
+        + "    filename (string) the filename where to write\n");
+    System.exit(1);
+  }
+
+  static LoggerContext buildLoggerContext(String stamp, String filename,
+      boolean safetyMode) {
+    LoggerContext loggerContext = new LoggerContext();
+
+    RollingFileAppender<LoggingEvent> rfa = new RollingFileAppender<LoggingEvent>();
+    PatternLayout patternLayout = new PatternLayout();
+    patternLayout.setPattern(stamp + " %5p - %-50m%n");
+    patternLayout.setContext(loggerContext);
+    patternLayout.start();
+
+    rfa.setLayout(patternLayout);
+    
+    rfa.setAppend(true);
+    rfa.setImmediateFlush(true);
+    rfa.setBufferedIO(false);
+    rfa.setPrudent(safetyMode);
+    rfa.setContext(loggerContext);
+
+    TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
+    
+    tbrp.setContext(loggerContext);
+    tbrp.setFileNamePattern(filename+"-%d{"+DATE_PATTERN+"}.log");
+    tbrp.setParent(rfa);
+    tbrp.start();
+  
+    rfa.setRollingPolicy(tbrp);
+
+    
+    rfa.start();
+
+    ch.qos.logback.classic.Logger root = loggerContext
+        .getLogger(LoggerContext.ROOT_NAME);
+    root.addAppender(rfa);
+
+    return loggerContext;
+  }
+
+  static void writeContinously(String stamp, String filename, boolean safetyMode)
+      throws Exception {
+    LoggerContext lc = buildLoggerContext(stamp, filename, safetyMode);
+    Logger logger = lc.getLogger(SafeModeRollingFileAppender.class);
+
+    long before = System.nanoTime();
+    for (int i = 0; i < LEN; i++) {
+      logger.debug(LoggingThread.msgLong + " " + i);
+    }
+    lc.stop();
+    StatusPrinter.print(lc);
+    double durationPerLog = (System.nanoTime() - before) / (LEN * 1000.0);
+
+    System.out.println("Average duration of " + (durationPerLog)
+        + " microseconds per log. Safety mode " + safetyMode);
+    System.out.println("------------------------------------------------");
+  }
+}

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java	Mon Nov 17 15:45:23 2008
@@ -17,8 +17,6 @@
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 
-import ch.qos.logback.core.status.ErrorStatus;
-import ch.qos.logback.core.status.InfoStatus;
 import ch.qos.logback.core.util.FileUtil;
 
 /**
@@ -53,7 +51,7 @@
    */
   protected int bufferSize = 8 * 1024;
 
-  private boolean safeMode = false;
+  private boolean prudent = false;
 
   private FileChannel fileChannel = null;
 
@@ -68,20 +66,49 @@
    * the file to append to.
    */
   public void setFile(String file) {
-    // Trim spaces from both ends. The users probably does not want
-    // trailing spaces in file names.
-    String val = file.trim();
-    fileName = val;
+    if(file == null) {
+      fileName = file;
+    } else {
+      // Trim spaces from both ends. The users probably does not want
+      // trailing spaces in file names.
+      String val = file.trim();
+      fileName = val;      
+
+    }
+
   }
 
   /**
-   * Returns the value of the <b>Append</b> option.
+   * @deprecated Use isAppend instead
    */
   public boolean getAppend() {
     return append;
   }
 
-  /** Returns the value of the <b>File</b> option. */
+  /**
+   * Returns the value of the <b>Append</b> property.
+   */
+  public boolean isAppend() {
+    return append;
+  }
+
+  
+  /**
+   * This method is used by derived classes to obtain the raw file property.
+   * Regular users should not be using calling method.
+   * 
+   * @return the value of the file property
+   */
+  final public String rawFileProperty() {
+    return fileName;
+  }
+
+  /**
+   * Returns the value of the <b>File</b> property.
+   * 
+   * <p>This method may be overridden by derived classes.
+   * 
+   */
   public String getFile() {
     return fileName;
   }
@@ -93,8 +120,24 @@
    */
   public void start() {
     int errors = 0;
-    if (fileName != null) {
-      addInfo("filename set to [" + fileName + "]");
+    if (getFile() != null) {
+      addInfo("File property is set to [" + fileName + "]");
+
+      if (prudent) {
+        if (isAppend() == false) {
+          setAppend(true);
+          addWarn("Setting \"Append\" property to true on account of \"Prudent\" mode");
+        }
+        if (getImmediateFlush() == false) {
+          setImmediateFlush(true);
+          addWarn("Setting \"ImmediateFlush\" to true on account of \"Prudent\" mode");
+        }
+
+        if (bufferedIO == true) {
+          setBufferedIO(false);
+          addWarn("Setting \"BufferedIO\" property to false on account of \"Prudent\" mode");
+        }
+      }
 
       // In case both bufferedIO and immediateFlush are set, the former
       // takes priority because 'immediateFlush' is set to true by default.
@@ -102,22 +145,18 @@
       // directives.
       if (bufferedIO) {
         setImmediateFlush(false);
-        addStatus(new InfoStatus(
-            "Setting immediateFlush to false on account of bufferedIO option",
-            this));
+        addInfo("Setting \"ImmediateFlush\" property to false on account of \"bufferedIO\" property");
       }
+
       try {
-        openFile();
+        openFile(getFile());
       } catch (java.io.IOException e) {
         errors++;
-
-        addStatus(new ErrorStatus("setFile(" + fileName + "," + append
-            + ") call failed.", this, e));
+        addError("openFile(" + fileName + "," + append + ") call failed.", e);
       }
     } else {
       errors++;
-      addStatus(new ErrorStatus("File option not set for appender [" + name
-          + "].", this));
+      addError("\"File\" property not set for appender named [" + name + "].");
     }
     if (errors == 0) {
       super.start();
@@ -145,8 +184,8 @@
    * @throws IOException
    * 
    */
-  public synchronized void openFile() throws IOException {
-    File file = new File(fileName);
+  public synchronized void openFile(String file_name) throws IOException {
+    File file = new File(file_name);
     if (FileUtil.mustCreateParentDirectories(file)) {
       boolean result = FileUtil.createMissingParentDirectories(file);
       if (!result) {
@@ -155,8 +194,8 @@
       }
     }
 
-    FileOutputStream fileOutputStream = new FileOutputStream(fileName, append);
-    if (safeMode) {
+    FileOutputStream fileOutputStream = new FileOutputStream(file_name, append);
+    if (prudent) {
       fileChannel = fileOutputStream.getChannel();
     }
     Writer w = createWriter(fileOutputStream);
@@ -182,46 +221,50 @@
     this.bufferSize = bufferSize;
   }
 
-  public String getFileName() {
-    return fileName;
-  }
-
-  public void setFileName(String fileName) {
-    this.fileName = fileName;
-  }
-
-  public boolean isSafeMode() {
-    return safeMode;
+  /**
+   * @see #setPrudent(boolean)
+   * 
+   * @return true if in prudent mode
+   */
+  public boolean isPrudent() {
+    return prudent;
   }
 
-  public void setSafeMode(boolean safeMode) {
-    this.safeMode = safeMode;
+  /**
+   * When prudent is set to true, file appenders from multiple JVMs can safely
+   * write to the same file.
+   * 
+   * @param prudent
+   */
+  public void setPrudent(boolean prudent) {
+    this.prudent = prudent;
   }
 
   public void setAppend(boolean append) {
     this.append = append;
   }
 
+  final private void safeWrite(String s) throws IOException {
+    FileLock fileLock = null;
+    try {
+      fileLock = fileChannel.lock();
+      long position = fileChannel.position();
+      long size = fileChannel.size();
+      if (size != position) {
+        fileChannel.position(size);
+      }
+      super.writerWrite(s, true);
+    } finally {
+      if (fileLock != null) {
+        fileLock.release();
+      }
+    }
+  }
+
   @Override
   protected void writerWrite(String s, boolean flush) throws IOException {
-    if (safeMode && fileChannel != null) {
-      FileLock fileLock = null;
-      try {
-        fileLock = fileChannel.lock();
-        long position = fileChannel.position();
-        long size = fileChannel.size();
-        if(size != position) {
-          //System.out.println("position size mismatch, pos ="+position+" size="+size);
-          fileChannel.position(size);
-        } else {
-          //System.out.println(position+" size="+size);
-        }
-        super.writerWrite(s, true);
-      } finally {
-        if (fileLock != null) {
-          fileLock.release();
-        }
-      }
+    if (prudent && fileChannel != null) {
+      safeWrite(s);
     } else {
       super.writerWrite(s, flush);
     }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.java	Mon Nov 17 15:45:23 2008
@@ -27,8 +27,9 @@
  * @author Ceki G&uuml;lc&uuml;
  */
 public class FixedWindowRollingPolicy extends RollingPolicyBase {
-  static final String FNP_NOT_SET = "The FileNamePattern option must be set before using FixedWindowRollingPolicy. ";
+  static final String FNP_NOT_SET = "The \"FileNamePattern\" property must be set before using FixedWindowRollingPolicy. ";
   static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
+  static final String PRUDENT_MODE_UNSUPPORTED = "See also http://logback.qos.ch/codes.html#tbr_fnp_prudent_unsupported";
   static final String SEE_PARENT_FN_NOT_SET = "Please refer to http://logback.qos.ch/codes.html#fwrp_parentFileName_not_set";
   int maxIndex;
   int minIndex;
@@ -52,14 +53,20 @@
       fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
       determineCompressionMode();
     } else {
-      addWarn(FNP_NOT_SET);
-      addWarn(SEE_FNP_NOT_SET);
+      addError(FNP_NOT_SET);
+      addError(SEE_FNP_NOT_SET);
       throw new IllegalStateException(FNP_NOT_SET + SEE_FNP_NOT_SET);
     }
 
-    if (getParentFileName() == null) {
-      addWarn("The File name option must be set before using this rolling policy.");
-      addWarn(SEE_PARENT_FN_NOT_SET);
+    if(isParentPrudent()) {
+      addError("Prudent mode is not supported with FixedWindowRollingPolicy.");
+      addError(PRUDENT_MODE_UNSUPPORTED);
+      throw new IllegalStateException("Prudent mode is not supported.");
+    }
+    
+    if (getParentsRawFileProperty() == null) {
+      addError("The File name property must be set before using this rolling policy.");
+      addError(SEE_PARENT_FN_NOT_SET);
       throw new IllegalStateException("The \"File\" option must be set.");
     }
 
@@ -113,18 +120,18 @@
       Compressor compressor;
       switch (compressionMode) {
       case NONE:
-        util.rename(getNewActiveFileName(), fileNamePattern
+        util.rename(getActiveFileName(), fileNamePattern
             .convertInt(minIndex));
         break;
       case GZ:
         compressor = new Compressor(CompressionMode.GZ,
-            getNewActiveFileName(), fileNamePattern.convertInt(minIndex));
+            getActiveFileName(), fileNamePattern.convertInt(minIndex));
         compressor.setContext(this.context);
         compressor.compress();
         break;
       case ZIP:
         compressor = new Compressor(CompressionMode.ZIP,
-            getNewActiveFileName(), fileNamePattern.convertInt(minIndex));
+            getActiveFileName(), fileNamePattern.convertInt(minIndex));
         compressor.setContext(this.context);
         compressor.compress();
         break;
@@ -137,8 +144,8 @@
    * 
    * @see {@link setActiveFileName}.
    */
-  public String getNewActiveFileName() {
-    return getParentFileName();
+  public String getActiveFileName() {
+    return getParentsRawFileProperty();
   }
 
   public int getMaxIndex() {
@@ -156,4 +163,8 @@
   public void setMinIndex(int minIndex) {
     this.minIndex = minIndex;
   }
+
+  public CompressionMode getCompressionMode() {
+    return compressionMode;
+  }
 }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingFileAppender.java	Mon Nov 17 15:45:23 2008
@@ -13,82 +13,97 @@
 import java.io.IOException;
 
 import ch.qos.logback.core.FileAppender;
-
+import ch.qos.logback.core.rolling.helper.CompressionMode;
 
 /**
- * <code>RollingFileAppender</code> extends {@link FileAppender} to backup the log files
- * depending on {@link RollingPolicy} and {@link TriggeringPolicy}.
+ * <code>RollingFileAppender</code> extends {@link FileAppender} to backup the
+ * log files depending on {@link RollingPolicy} and {@link TriggeringPolicy}.
  * <p>
  * 
- * For more information about this appender, please refer to the online manual at
- * http://logback.qos.ch/manual/appenders.html#RollingFileAppender
+ * For more information about this appender, please refer to the online manual
+ * at http://logback.qos.ch/manual/appenders.html#RollingFileAppender
  * 
  * @author Heinz Richter
  * @author Ceki G&uuml;lc&uuml;
- * */
+ */
 public class RollingFileAppender<E> extends FileAppender<E> {
   File activeFileCache;
   TriggeringPolicy<E> triggeringPolicy;
   RollingPolicy rollingPolicy;
 
   /**
-   * The default constructor simply calls its {@link
-   * FileAppender#FileAppender parents constructor}.
-   * */
+   * The default constructor simply calls its {@link FileAppender#FileAppender
+   * parents constructor}.
+   */
   public RollingFileAppender() {
   }
 
   public void start() {
     if (triggeringPolicy == null) {
-      addWarn("No TriggeringPolicy was set for the RollingFileAppender named "+ getName());
+      addWarn("No TriggeringPolicy was set for the RollingFileAppender named "
+          + getName());
       addWarn("For more information, please visit http://logback.qos.ch/codes.html#rfa_no_tp");
       return;
     }
 
-    if (rollingPolicy != null) {  
-      //if no active file name was set, then it's the responsability of the
-      //rollingPolicy to create one.
-      setFile(rollingPolicy.getNewActiveFileName());
-      
-      activeFileCache = new File(getFile());
-      addInfo("Active log file name: "+ getFile());
-      
-      super.start();
-    } else {
-      addWarn("No RollingPolicy was set for the RollingFileAppender named "+ getName());
-      addWarn("For more information, please visit http://logback.qos.ch/codes.html#rfa_no_rp");
+    if (rollingPolicy == null) {
+      addError("No RollingPolicy was set for the RollingFileAppender named "
+          + getName());
+      addError("For more information, please visit http://logback.qos.ch/codes.html#rfa_no_rp");
+      return;
     }
+    
+    if(isPrudent()) {
+      if(rawFileProperty() !=  null) {
+        addWarn("Setting \"File\" property to null on account of prudent mode");
+        setFile(null);    
+      }
+      if(rollingPolicy.getCompressionMode() != CompressionMode.NONE) {
+        addError("Compression is not supported in prudent mode. Aborting");
+        return;
+      }
+    }
+
+    activeFileCache = new File(getFile());
+    addInfo("Active log file name: " + getFile());
+    super.start();
+  }
+
+  @Override
+  public String getFile() {
+    return rollingPolicy.getActiveFileName();
   }
 
   /**
-     Implements the usual roll over behaviour.
-
-     <p>If <code>MaxBackupIndex</code> is positive, then files
-     {<code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code>}
-     are renamed to {<code>File.2</code>, ...,
-     <code>File.MaxBackupIndex</code>}. Moreover, <code>File</code> is
-     renamed <code>File.1</code> and closed. A new <code>File</code> is
-     created to receive further log output.
-
-     <p>If <code>MaxBackupIndex</code> is equal to zero, then the
-     <code>File</code> is truncated with no backup files created.
-
+   * Implements the usual roll over behaviour.
+   * 
+   * <p>If <code>MaxBackupIndex</code> is positive, then files {<code>File.1</code>,
+   * ..., <code>File.MaxBackupIndex -1</code>} are renamed to {<code>File.2</code>,
+   * ..., <code>File.MaxBackupIndex</code>}. Moreover, <code>File</code> is
+   * renamed <code>File.1</code> and closed. A new <code>File</code> is
+   * created to receive further log output.
+   * 
+   * <p>If <code>MaxBackupIndex</code> is equal to zero, then the
+   * <code>File</code> is truncated with no backup files created.
+   * 
    */
   public void rollover() {
-    // Note: synchronization at this point is unnecessary as the doAppend 
+    // Note: synchronization at this point is unnecessary as the doAppend
     // is already synched
-    
+
     //
     // make sure to close the hereto active log file! Renaming under windows
     // does not work for open files.
-    this.closeWriter();    
-    
+    this.closeWriter();
+
     // By default, the newly created file will be created in truncate mode.
     // (See the setFile() call a few lines below.)
-    this.append = false;
-    try { 
+    // FIXME don't change the append mode
+    // this.append = false;
+    
+    try {
       rollingPolicy.rollover();
-    } catch(RolloverFailure rf) {
+    } catch (RolloverFailure rf) {
       addWarn("RolloverFailure occurred. Deferring roll-over.");
       // we failed to roll-over, let us not truncate and risk data loss
       this.append = true;
@@ -97,24 +112,22 @@
     try {
       // This will also close the file. This is OK since multiple
       // close operations are safe.
-      this.openFile();
+      this.openFile(rollingPolicy.getActiveFileName());
     } catch (IOException e) {
-      addError(
-        "setFile(" + fileName + ", false) call failed.", e);
+      addError("setFile(" + fileName + ", false) call failed.", e);
     }
   }
 
   /**
-     This method differentiates RollingFileAppender from its super
-     class.
-  */
+   * This method differentiates RollingFileAppender from its super class.
+   */
   protected void subAppend(E event) {
-    // The roll-over check must precede actual writing. This is the 
-    // only correct behavior for time driven triggers. 
+    // The roll-over check must precede actual writing. This is the
+    // only correct behavior for time driven triggers.
     if (triggeringPolicy.isTriggeringEvent(activeFileCache, event)) {
       rollover();
     }
-      
+
     super.subAppend(event);
   }
 
@@ -128,22 +141,23 @@
 
   /**
    * Sets the rolling policy. In case the 'policy' argument also implements
-   * {@link TriggeringPolicy}, then the triggering policy for this appender
-   * is automatically set to be the policy argument.
+   * {@link TriggeringPolicy}, then the triggering policy for this appender is
+   * automatically set to be the policy argument.
+   * 
    * @param policy
    */
   @SuppressWarnings("unchecked")
   public void setRollingPolicy(RollingPolicy policy) {
     rollingPolicy = policy;
-    if(rollingPolicy instanceof TriggeringPolicy) {
+    if (rollingPolicy instanceof TriggeringPolicy) {
       triggeringPolicy = (TriggeringPolicy<E>) policy;
     }
-    
+
   }
 
   public void setTriggeringPolicy(TriggeringPolicy<E> policy) {
     triggeringPolicy = policy;
-    if(policy instanceof RollingPolicy) {
+    if (policy instanceof RollingPolicy) {
       rollingPolicy = (RollingPolicy) policy;
     }
   }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicy.java	Mon Nov 17 15:45:23 2008
@@ -10,6 +10,7 @@
 package ch.qos.logback.core.rolling;
 
 import ch.qos.logback.core.FileAppender;
+import ch.qos.logback.core.rolling.helper.CompressionMode;
 import ch.qos.logback.core.spi.LifeCycle;
 
 /**
@@ -24,34 +25,39 @@
 
   /**
    * Rolls over log files according to implementation policy.
-   * <p>
-   * <p>
-   * This method is invoked by {@link RollingFileAppender}, usually at the
+   * 
+   * <p>This method is invoked by {@link RollingFileAppender}, usually at the
    * behest of its {@link TriggeringPolicy}.
    * 
    * @throws RolloverFailure
-   *           Thrown if the rollover operation fails for any reason.
+   *                 Thrown if the rollover operation fails for any reason.
    */
   public void rollover() throws RolloverFailure;
 
   /**
-   * Get the new name of the active log file.
-   * With implementations such as {@link TimeBasedRollingPolicy}, 
-   * this method returns a new file name, where the actual output
-   * will be sent.
+   * Get the name of the active log file.
+   * 
+   * <p>With implementations such as {@link TimeBasedRollingPolicy}, this
+   * method returns a new file name, where the actual output will be sent.
    * 
-   * On some implementations, this method might return
-   * the FileAppender's file attribute.
+   * <p>On other implementations, this method might return the FileAppender's
+   * file property.
    */
-  public String getNewActiveFileName();
+  public String getActiveFileName();
 
+  /**
+   * The compression mode for this policy.
+   * 
+   * @return
+   */
+  public CompressionMode getCompressionMode();
   
   /**
-   * This method allows RollingPolicy implementations
-   * to be aware of their containing appender.
+   * This method allows RollingPolicy implementations to be aware of their
+   * containing appender.
    * 
    * @param appender
    */
-  
+
   public void setParent(FileAppender appender);
 }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/RollingPolicyBase.java	Mon Nov 17 15:45:23 2008
@@ -77,11 +77,11 @@
     this.parent = appender;
   }
 
-  public String getParentFileName() {
-    return parent.getFile();
+  public boolean isParentPrudent() {
+    return parent.isPrudent();
   }
   
-  protected void setParentFileName(String newFileName) {
-    parent.setFile(newFileName);
+  public String getParentsRawFileProperty() {
+    return parent.rawFileProperty();
   }
 }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java	Mon Nov 17 15:45:23 2008
@@ -47,7 +47,7 @@
   String elapsedPeriodsFileName;
   FileNamePattern activeFileNamePattern;
   RenameUtil util = new RenameUtil();
-  String lastGeneratedFileName;
+  String latestActiveFileName;
   Future<?> future;
 
   int maxHistory = NO_DELETE_HISTORY;
@@ -117,59 +117,67 @@
     if (lastCheck == null) {
       lastCheck = new Date();
       lastCheck.setTime(getCurrentTime());
-      if (getParentFileName() != null) {
-        File currentFile = new File(getParentFileName());
+      if (getParentsRawFileProperty() != null) {
+        File currentFile = new File(getParentsRawFileProperty());
         if (currentFile.exists() && currentFile.canRead()) {
           lastCheck.setTime(currentFile.lastModified());
         }
       }
     }
     nextCheck = rc.getNextTriggeringMillis(lastCheck);
-    
+
     if (maxHistory != NO_DELETE_HISTORY) {
       tbCleaner = new TimeBasedCleaner(fileNamePattern, rc, maxHistory);
     }
   }
 
   
+  public CompressionMode getCompressionMode() {
+    return compressionMode;
+  }
+
+  
   // allow Test classes to act on the lastCheck field to simulate old
   // log files needing rollover
   void setLastCheck(Date _lastCheck) {
     this.lastCheck = _lastCheck;
   }
 
+  boolean rolloverTargetIsParentFile() {
+    return (getParentsRawFileProperty() != null && getParentsRawFileProperty()
+        .equals(elapsedPeriodsFileName));
+  }
+
   public void rollover() throws RolloverFailure {
 
     // when rollover is called the elapsed period's file has
     // been already closed. This is a working assumption of this method.
-
-    if (getParentFileName() == null && compressionMode != CompressionMode.NONE) {
-      doCompression(false, elapsedPeriodsFileName, elapsedPeriodsFileName);
+    
+    if(compressionMode == CompressionMode.NONE) {
+      if (getParentsRawFileProperty() != null) {
+        util.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
+      }
     } else {
-      if (compressionMode == CompressionMode.NONE) {
-        util.rename(getParentFileName(), elapsedPeriodsFileName);
+      if(getParentsRawFileProperty() == null) {
+        doCompression(false, elapsedPeriodsFileName, elapsedPeriodsFileName);
       } else {
-        doCompression(true, getParentFileName(), elapsedPeriodsFileName);
+        doCompression(true, elapsedPeriodsFileName, elapsedPeriodsFileName);
       }
     }
-
+    
     if (tbCleaner != null) {
       tbCleaner.clean(new Date(getCurrentTime()));
     }
-
-    // let's update the parent active file name
-    setParentFileName(getNewActiveFileName());
-
   }
 
-  void doCompression(boolean rename, String nameOfFile2Compress,
+  void doCompression(boolean renameToTempFile, String nameOfFile2Compress,
       String nameOfCompressedFile) throws RolloverFailure {
     Compressor compressor = null;
 
-    if (rename) {
-      String renameTarget = nameOfFile2Compress + System.nanoTime() + ".tmp";
-      util.rename(getParentFileName(), renameTarget);
-      nameOfFile2Compress = renameTarget;
+    if (renameToTempFile) {
+      String tmpTarget = nameOfFile2Compress + System.nanoTime() + ".tmp";
+      util.rename(getParentsRawFileProperty(), tmpTarget);
+      nameOfFile2Compress = tmpTarget;
     }
 
     switch (compressionMode) {
@@ -199,7 +207,7 @@
    * file equals the file name for the current period as computed by the
    * <b>FileNamePattern</b> option.
    * 
-   * <p> The RollingPolicy must know wether it is responsible for changing the
+   * <p>The RollingPolicy must know whether it is responsible for changing the
    * name of the active file or not. If the active file name is set by the user
    * via the configuration file, then the RollingPolicy must let it like it is.
    * If the user does not specify an active file name, then the RollingPolicy
@@ -212,15 +220,13 @@
    * the change of the file name.
    * 
    */
-  public String getNewActiveFileName() {
-    if (getParentFileName() == null
-        || getParentFileName() == lastGeneratedFileName) {
+  public String getActiveFileName() {
+    if (getParentsRawFileProperty() == null) {
       String newName = activeFileNamePattern.convertDate(lastCheck);
-      addInfo("Generated a new name for RollingFileAppender: " + newName);
-      lastGeneratedFileName = newName;
+      latestActiveFileName = newName;
       return newName;
     } else {
-      return getParentFileName();
+      return getParentsRawFileProperty();
     }
   }
 
@@ -228,7 +234,8 @@
     long time = getCurrentTime();
 
     if (time >= nextCheck) {
-      // We set the elapsedPeriodsFileName before we set the 'lastCheck' variable
+      // We set the elapsedPeriodsFileName before we set the 'lastCheck'
+      // variable
       // The elapsedPeriodsFileName corresponds to the file name of the period
       // that just elapsed.
       elapsedPeriodsFileName = activeFileNamePattern.convertDate(lastCheck);

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java	Mon Nov 17 15:45:23 2008
@@ -37,6 +37,10 @@
    * @throws RolloverFailure
    */
   public void rename(String from, String to) throws RolloverFailure {
+    if(from.equals(to)) {
+      addWarn("From and to file are the same ["+from+"]. Skipping.");
+      return;
+    }
     File fromFile = new File(from);
 
     if (fromFile.exists()) {

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/AbstractAppenderTest.java	Mon Nov 17 15:45:23 2008
@@ -10,7 +10,10 @@
 package ch.qos.logback.core.appender;
 
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
 
 import ch.qos.logback.core.AppenderBase;
 import ch.qos.logback.core.Context;
@@ -19,21 +22,20 @@
 
 
 
-abstract public class AbstractAppenderTest<E> extends TestCase {
+abstract public class AbstractAppenderTest<E>  {
   
-  AbstractAppenderTest(String arg) {
-    super(arg);
-  }
   
   abstract protected AppenderBase<E> getAppender();
   abstract protected AppenderBase<E> getConfiguredAppender();
 
+  @Test
   public void testNewAppender() {
     // new appenders should be inactive
     AppenderBase appender = getAppender();
     assertFalse( appender.isStarted()); 
   }
   
+  @Test
   public void testConfiguredAppender() {
     AppenderBase appender = getConfiguredAppender();
     appender.start();
@@ -44,6 +46,7 @@
     
   }
   
+  @Test
   public void testNoStart() {
     AppenderBase<E> appender = getAppender();
     Context context = new ContextBase();

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java	Mon Nov 17 15:45:23 2008
@@ -9,11 +9,15 @@
  */
 package ch.qos.logback.core.appender;
 
+import static org.junit.Assert.assertEquals;
+
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
 
 import ch.qos.logback.core.AppenderBase;
 import ch.qos.logback.core.ConsoleAppender;
@@ -28,12 +32,9 @@
   TeeOutputStream tee;
   PrintStream original;
 
-  public ConsoleAppenderTest(String arg) {
-    super(arg);
-
-  }
 
-  protected void setUp() throws Exception {
+  @Before
+  public void setUp() throws Exception {
     original = System.out;
     // tee will output bytes on System out but it will also
     // collect them so that the output can be compared against
@@ -47,13 +48,13 @@
     System.setOut(new PrintStream(tee));
   }
 
-  protected void tearDown() throws Exception {
-    super.tearDown();
+  @After
+  public void tearDown() throws Exception {
     System.setOut(original);
   }
 
   @Override
-  protected AppenderBase<Object> getAppender() {
+  public AppenderBase<Object> getAppender() {
     return new ConsoleAppender<Object>();
   } 
 
@@ -64,6 +65,7 @@
     return ca;
   }
 
+  @org.junit.Test
   public void testBasic() {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
     ca.setLayout(new DummyLayout<Object>());
@@ -72,6 +74,7 @@
     assertEquals(DummyLayout.DUMMY, tee.toString());
   }
   
+  @org.junit.Test
   public void testOpen() {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
     DummyLayout<Object> dummyLayout = new DummyLayout<Object>();
@@ -82,6 +85,8 @@
     ca.stop();
     assertEquals("open"+Layout.LINE_SEP+DummyLayout.DUMMY, tee.toString());
   }
+  
+  @Test
   public void testClose() {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
     DummyLayout<Object> dummyLayout = new DummyLayout<Object>();
@@ -95,7 +100,7 @@
 
 
 
-  
+  @Test  
   public void testUTF16BE() throws UnsupportedEncodingException {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
     ca.setLayout(new DummyLayout<Object>());
@@ -107,10 +112,5 @@
     assertEquals(DummyLayout.DUMMY, new String(tee.toByteArray(), encodingName));
   }
 
-  public static Test xxsuite() {
-    TestSuite suite = new TestSuite();
-    //suite.addTest(new ConsoleAppenderTest("testOpen"));
-    suite.addTestSuite(ConsoleAppenderTest.class);
-    return suite;
-  }
+
 }

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java	Mon Nov 17 15:45:23 2008
@@ -9,18 +9,19 @@
  */
 package ch.qos.logback.core.appender;
 
+import static org.junit.Assert.*;
+
 import java.io.StringWriter;
 
+import org.junit.Test;
+
 import ch.qos.logback.core.AppenderBase;
 import ch.qos.logback.core.layout.DummyLayout;
 import ch.qos.logback.core.layout.NopLayout;
 
 
-public class DummyAppenderTest extends AbstractAppenderTest {
+public class DummyAppenderTest {
 
-  public DummyAppenderTest(String arg) {
-    super(arg);
-  }
   
   protected AppenderBase getAppender() {
     return new DummyAppender(new StringWriter());
@@ -33,6 +34,7 @@
     return da;
   }
 
+  @Test
   public void testBasic() {
     StringWriter sw = new StringWriter();
     DummyAppender<Object> da = new DummyAppender<Object>(sw);

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java	Mon Nov 17 15:45:23 2008
@@ -1,92 +1,131 @@
 /**
- * LOGBack: the reliable, fast and flexible logging library for Java.
- *
- * Copyright (C) 1999-2006, QOS.ch
- *
- * This library is free software, you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation.
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2008, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
  */
 package ch.qos.logback.core.appender;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.io.File;
+import java.util.List;
 import java.util.Random;
 
+import org.junit.Test;
+
 import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
 import ch.qos.logback.core.FileAppender;
 import ch.qos.logback.core.layout.DummyLayout;
 import ch.qos.logback.core.layout.NopLayout;
+import ch.qos.logback.core.status.Status;
+import ch.qos.logback.core.status.StatusManager;
 import ch.qos.logback.core.util.Constants;
 import ch.qos.logback.core.util.FileUtil;
+import ch.qos.logback.core.util.StatusPrinter;
 
+public class FileAppenderTest extends AbstractAppenderTest<Object> {
 
-public class FileAppenderTest extends AbstractAppenderTest {
-
-  public FileAppenderTest(String arg0) {
-    super(arg0);
-  }
+  int diff = new Random().nextInt(100);
+  Context context = new ContextBase();
 
-  protected void setUp() throws Exception {
-    super.setUp();
+  protected AppenderBase<Object> getAppender() {
+    return new FileAppender<Object>();
   }
 
-  protected void tearDown() throws Exception {
-    super.tearDown();
-  }
-
-  protected AppenderBase getAppender() {
-    return new FileAppender();
-  }
-
-  protected AppenderBase getConfiguredAppender() {
+  protected AppenderBase<Object> getConfiguredAppender() {
     FileAppender<Object> appender = new FileAppender<Object>();
     appender.setLayout(new NopLayout<Object>());
     appender.setFile("temp.log");
     appender.setName("temp.log");
-    appender.setContext(new ContextBase());
+    appender.setContext(context);
     appender.start();
     return appender;
   }
-  
-  public void test() {
-    String filename = Constants.OUTPUT_DIR_PREFIX+"temp.log";
-    
+
+  @Test
+  public void smoke() {
+    String filename = Constants.OUTPUT_DIR_PREFIX + "temp.log";
+
     FileAppender<Object> appender = new FileAppender<Object>();
     appender.setLayout(new DummyLayout<Object>());
     appender.setAppend(false);
     appender.setFile(filename);
     appender.setName("temp.log");
-    appender.setContext(new ContextBase());
+    appender.setContext(context);
     appender.start();
     appender.doAppend(new Object());
     appender.stop();
-    
+
     File file = new File(filename);
     assertTrue(file.exists());
-    assertTrue("failed to delete "+file.getAbsolutePath(), file.delete());
+    assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
   }
-  
+
+  @Test
   public void testCreateParentFolders() {
-    int diff =  new Random().nextInt(100);
-    String filename = Constants.OUTPUT_DIR_PREFIX+"/fat"+diff+"/testing.txt";    
+    String filename = Constants.OUTPUT_DIR_PREFIX + "/fat" + diff
+        + "/testing.txt";
     File file = new File(filename);
     FileAppender<Object> appender = new FileAppender<Object>();
     appender.setLayout(new DummyLayout<Object>());
     appender.setAppend(false);
     appender.setFile(filename);
     appender.setName("testCreateParentFolders");
-    appender.setContext(new ContextBase());
+    appender.setContext(context);
     appender.start();
     appender.doAppend(new Object());
     appender.stop();
     assertFalse(FileUtil.mustCreateParentDirectories(file));
     assertTrue(file.exists());
-   
+
     // cleanup
-    assertTrue("failed to delete "+file.getAbsolutePath(), file.delete());
+    assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
     File parent = file.getParentFile();
-    assertTrue("failed to delete "+parent.getAbsolutePath(), parent.delete());
+    assertTrue("failed to delete " + parent.getAbsolutePath(), parent.delete());
   }
 
+  @Test
+  public void testPrudentModeLogicalImplications() {
+    String filename = Constants.OUTPUT_DIR_PREFIX + diff + "testing.txt";
+    File file = new File(filename);
+    FileAppender<Object> appender = new FileAppender<Object>();
+    appender.setLayout(new DummyLayout<Object>());
+    appender.setFile(filename);
+    appender.setName("testPrudentMode");
+    appender.setContext(context);
+
+    appender.setAppend(false);
+    appender.setImmediateFlush(false);
+    appender.setBufferedIO(true);
+    appender.setPrudent(true);
+    appender.start();
+
+    assertTrue(appender.getImmediateFlush());
+    assertTrue(appender.isAppend());
+    assertFalse(appender.isBufferedIO());
+
+    StatusManager sm = context.getStatusManager();
+    assertEquals(Status.WARN, sm.getLevel());
+    List<Status> statusList = sm.getCopyOfStatusList();
+    assertTrue("Expecting status list size to be larger than 3, but was "
+        + statusList.size(), statusList.size() > 3);
+    String msg1 = statusList.get(1).getMessage();
+
+    assertTrue("Got message [" + msg1 + "]", msg1
+        .startsWith("Setting \"Append\" property"));
+    StatusPrinter.print(context);
+
+    appender.doAppend(new Object());
+    appender.stop();
+    assertTrue(file.exists());
+    assertTrue("failed to delete " + file.getAbsolutePath(), file.delete());
+  }
 }

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/appender/PackageTest.java	Mon Nov 17 15:45:23 2008
@@ -1,7 +1,7 @@
 /**
- * Logback: the generic, reliable, fast and flexible logging framework for Java.
+ * Logback: the generic, reliable, fast and flexible logging framework.
  * 
- * Copyright (C) 2000-2006, QOS.ch
+ * Copyright (C) 2000-2008, QOS.ch
  * 
  * This library is free software, you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
@@ -10,6 +10,7 @@
 
 package ch.qos.logback.core.appender;
 
+import junit.framework.JUnit4TestAdapter;
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -18,9 +19,9 @@
 
   public static Test suite() {
     TestSuite suite = new TestSuite();
-    suite.addTestSuite(DummyAppenderTest.class);
-    suite.addTestSuite(ConsoleAppenderTest.class);
-    suite.addTestSuite(FileAppenderTest.class);
+    suite.addTest(new JUnit4TestAdapter(DummyAppenderTest.class));
+    suite.addTest(new JUnit4TestAdapter(ConsoleAppenderTest.class));
+    suite.addTest(new JUnit4TestAdapter(FileAppenderTest.class));
     return suite;
   }
 }

Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java	Mon Nov 17 15:45:23 2008
@@ -0,0 +1,100 @@
+package ch.qos.logback.core.rolling;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.core.AppenderBase;
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.appender.AbstractAppenderTest;
+import ch.qos.logback.core.layout.DummyLayout;
+import ch.qos.logback.core.status.Status;
+import ch.qos.logback.core.status.StatusManager;
+
+public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
+
+  RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
+  Context context = new ContextBase();
+
+  TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
+
+  @Before
+  public void setUp() throws Exception {
+    rfa.setLayout(new DummyLayout<Object>());
+    rfa.setName("test");
+    rfa.setRollingPolicy(tbrp);
+    
+    tbrp.setContext(context);
+    tbrp.setParent(rfa);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  
+  @Override
+  protected AppenderBase<Object> getAppender() {
+    return rfa;
+  }
+
+  @Override
+  protected AppenderBase<Object> getConfiguredAppender() {
+    rfa.setContext(context);
+
+    tbrp.setFileNamePattern("toto-%d.log");
+    tbrp.start();
+    
+    rfa.start();
+    return rfa;
+  }
+
+
+  @Test
+  public void testPrudentModeLogicalImplications() {
+    tbrp.setFileNamePattern("toto-%d.log");
+    tbrp.start();
+    
+    rfa.setContext(context);
+    // prudent mode will force "file" property to be null
+    rfa.setFile("some non null value");
+    rfa.setAppend(false);
+    rfa.setImmediateFlush(false);
+    rfa.setBufferedIO(true);
+    rfa.setPrudent(true);
+    rfa.start();
+
+    assertTrue(rfa.getImmediateFlush());
+    assertTrue(rfa.isAppend());
+    assertFalse(rfa.isBufferedIO());
+    assertNull(rfa.rawFileProperty());
+    assertTrue(rfa.isStarted());
+  }
+
+  
+  @Test
+  public void testPrudentModeLogicalImplicationsOnCompression() {
+    tbrp.setFileNamePattern("toto-%d.log.zip");
+    tbrp.start();
+
+    rfa.setContext(context);
+    rfa.setAppend(false);
+    rfa.setImmediateFlush(false);
+    rfa.setBufferedIO(true);
+    rfa.setPrudent(true);
+    rfa.start();
+
+    StatusManager sm = context.getStatusManager();
+    assertFalse(rfa.isStarted());
+    assertEquals(Status.ERROR, sm.getLevel());
+  }
+  
+  
+}

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java	Mon Nov 17 15:45:23 2008
@@ -29,6 +29,7 @@
 import ch.qos.logback.core.layout.EchoLayout;
 import ch.qos.logback.core.util.Compare;
 import ch.qos.logback.core.util.Constants;
+import ch.qos.logback.core.util.StatusPrinter;
 
 /**
  * A rather exhaustive set of tests. Tests include leaving the file option
@@ -76,7 +77,7 @@
     cal.set(Calendar.MILLISECOND, 333);
     currentTime = cal.getTimeInMillis();
     recomputeRolloverThreshold(currentTime);
-    System.out.println("currentTime=" + sdf.format(new Date(currentTime)));
+    System.out.println("at setUp() currentTime=" + sdf.format(new Date(currentTime)));
 
     // Delete .log files
     deleteStaleLogFile("test4.log");
@@ -112,8 +113,8 @@
     if (lastCheck != 0) {
       tbrp.setLastCheck(new Date(lastCheck));
     }
-    tbrp.start();
     rfa.setRollingPolicy(tbrp);
+    tbrp.start();
     rfa.start();
   }
 
@@ -140,7 +141,8 @@
       tbrp1.setCurrentTime(currentTime);
     }
 
-    System.out.println(expectedFilenameList);
+    StatusPrinter.print(context);
+    //System.out.println(expectedFilenameList);
 
     int i = 0;
     for (String fn : expectedFilenameList) {

Added: logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-PrudentTimeBasedRolling.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-PrudentTimeBasedRolling.xml	Mon Nov 17 15:45:23 2008
@@ -0,0 +1,20 @@
+<configuration>
+   <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+   
+   <!-- Support multiple-JVMs writing to the same log file -->
+   <Prudent>true</Prudent>
+   <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+     <FileNamePattern>logFile.%d{yyyy-MM-dd}.log</FileNamePattern>
+     <MaxHistory>30</MaxHistory> 
+   </rollingPolicy>
+
+   <layout class="ch.qos.logback.classic.PatternLayout">
+     <Pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</Pattern>
+   </layout>
+ </appender> 
+
+ <root>
+   <level value="debug" />
+   <appender-ref ref="FILE" />
+ </root>
+</configuration>
\ No newline at end of file

Modified: logback/trunk/logback-site/src/site/pages/codes.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/codes.html	(original)
+++ logback/trunk/logback-site/src/site/pages/codes.html	Mon Nov 17 15:45:23 2008
@@ -81,6 +81,20 @@
   </p>
 			
   <hr />
+  <p>
+    <a name="tbr_fnp_prudent_unsupported"
+    href="#tbr_fnp_prudent_unsupported">Prudent mode is not supported
+    with <code>FixedWindowRollingPolicy</code>.</a>
+  </p>
+
+  <p>Given that <code>FixedWindowRollingPolicy</code> performs
+  multiple file rename operations suring roll over, and that these
+  operations cannot be guaranteed to be safe in a multi-JVM context,
+  prudent mode is not allowed in conjuction with a
+  <code>FixedWindowRollingPolicy</code>.
+  </p>
+
+  <hr/>
 
   <p>
     <a name="socket_no_host" href="#socket_no_host">No remote host or

Modified: logback/trunk/logback-site/src/site/pages/css/common.css
==============================================================================
--- logback/trunk/logback-site/src/site/pages/css/common.css	(original)
+++ logback/trunk/logback-site/src/site/pages/css/common.css	Mon Nov 17 15:45:23 2008
@@ -129,6 +129,11 @@
 	background-color: #ddd;
 }
 
+/* apply to tr elements of tables which are both bodytable and dark */
+table[class="bodyTable properties"] tr {
+	vertical-align: top;
+}
+
 table.bodyTable tr.a {
 	background-color: #ddd;
 }

Modified: logback/trunk/logback-site/src/site/pages/manual/appenders.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/appenders.html	(original)
+++ logback/trunk/logback-site/src/site/pages/manual/appenders.html	Mon Nov 17 15:45:23 2008
@@ -166,16 +166,16 @@
 	to it.  <code>Appender</code> objects implement the
 	<code>LifeCycle</code> interface, which implies that they implement
 	<code>start()</code>, <code>stop()</code> and
-	<code>isStarted()</code> methods.  After setting all the options of
+	<code>isStarted()</code> methods.  After setting all the properties of
 	an appender, Joran, logback's configuration framework, calls the
 	<code>start()</code> method to signal the appender to activate its
-	options.  Depending on its kind, an appender may fail to start if
-	certain options are missing or because of interferences between
-	various options.  For example, given that file creation depends on
+	properties.  Depending on its kind, an appender may fail to start if
+	certain properties are missing or because of interferences between
+	various properties.  For example, given that file creation depends on
 	truncation mode, <code>FileAppender</code> cannot act on the value
 	of its <code>File</code> option until the value of the Append option
 	is also known with certainty. The explicit activation step ensures
-	that an appender acts on its options <em>after</em> their values
+	that an appender acts on its properties <em>after</em> their values
 	become known.
 	</p>
 	
@@ -219,8 +219,10 @@
   </p>
 
 
-	<a name="WriterAppender"></a>
-	<h3>WriterAppender</h3>
+	
+	<h3>
+    <a name="WriterAppender" href="#WriterAppender">WriterAppender</a>
+  </h3>
 	
 	<p><a
 	href="../xref/ch/qos/logback/core/WriterAppender.html"><code>WriterAppender</code></a>
@@ -232,12 +234,12 @@
 	<code>Writer</code> object in a configuration script.  Simply put,
 	you cannot configure a <code>WriterAppender</code> from a script.
 	However, this does not mean that <code>WriterAppender</code> lacks
-	configurable options.  These options are described next.
+	configurable properties.  These properties are described next.
 	</p>
 	
   <table class="bodyTable">
     <tr class="a">
-      <th>Option Name</th>
+      <th>Property Name</th>
       <th>Type</th>
       <th>Description</th>
     </tr>
@@ -287,8 +289,9 @@
 	messages will be lost as illustrated by the next example.
 	</p>
 	
-	<em>Example 4.1: Exiting an application without flushing (<a href="../xref/chapter4/ExitWoes1.html">logback-examples/src/main/java/chapter4/ExitWoes1.java</a>)</em>
-<div class="source"><pre>package chapter4;
+	<em>Example 4.<span class="autoEx"/>: Exiting an application without flushing (<a href="../xref/chapter4/ExitWoes1.html">logback-examples/src/main/java/chapter4/ExitWoes1.java</a>)</em>
+
+  <p class="source">package chapter4;
 
 import java.io.FileOutputStream;
 import java.io.OutputStream;
@@ -322,7 +325,7 @@
 
     logger.debug("Hello world.");
   }
-}</pre></div>
+}</p>
     
 	<p>This example creates a <code>WriterAppender</code> that uses an
 	<code>OutputStreamWriter</code> wrapping a
@@ -351,36 +354,38 @@
 	
 	<img src="images/chapter4/fileAppenderUML.png" alt="A UML diagram showing FileAppender"/>
 	
-	<a name="ConsoleAppender"></a>
-	<h3>ConsoleAppender</h3>
-	
-	<p>The <a href="../xref/ch/qos/logback/core/ConsoleAppender.html">
-	<code>ConsoleAppender</code></a>, as the name indicates, appends on
-	the console, or more precisely on <em>System.out</em> or
-	<em>System.err</em>, the former being the default
-	target. <code>ConsoleAppender</code> formats events with a layout
-	specified by the user. Layouts will be discussed in the next
-	chapter. Both <em>System.out</em> and <em>System.err</em> are
-	<code>java.io.PrintStream</code> objects.  Consequently, they are
-	wrapped inside an <code>OutputStreamWriter</code> which buffers I/O
-	operations but not character conversions.
+
+	<h3>	
+    <a name="ConsoleAppender" href="#ConsoleAppender">ConsoleAppender</a>
+  </h3>
+	
+  <p>The <a href="../xref/ch/qos/logback/core/ConsoleAppender.html">
+  <code>ConsoleAppender</code></a>, as the name indicates, appends on
+  the console, or more precisely on <em>System.out</em> or
+  <em>System.err</em>, the former being the default
+  target. <code>ConsoleAppender</code> formats events with a layout
+  specified by the user. Layouts will be discussed in the next
+  chapter. Both <em>System.out</em> and <em>System.err</em> are
+  <code>java.io.PrintStream</code> objects.  Consequently, they are
+  wrapped inside an <code>OutputStreamWriter</code> which buffers I/O
+  operations but not character conversions.
 	</p>
 	
 	<table class="bodyTable">
 			<tr class="a">
-			<th>Option Name</th>
+			<th>Property Name</th>
 			<th>Type</th>
 			<th>Description</th>
 		</tr>
 		<tr class="b">
 			<td><b><span class="option">Encoding</span></b></td>
 			<td><code>String</code></td>
-			<td>See <code>WriterAppender</code> options.</td>
+			<td>See <code>WriterAppender</code> properties.</td>
 		</tr>
 		<tr class="a">
 			<td><b><span class="option">ImmediateFlush</span></b></td>
 			<td><code>boolean</code></td>
-			<td>See <code>WriterAppender</code> options.</td>
+			<td>See <code>WriterAppender</code> properties.</td>
 		</tr>
 		<tr class="b">
 			<td><b><span class="option">Target</span></b></td>
@@ -396,8 +401,8 @@
 	<code>ConsoleAppender</code>.
 	</p>
 
-<em>Example 4.2: ConsoleAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-Console.xml)</em>
-<div class="source"><pre>&lt;configuration>
+  <em>Example 4.<span class="autoEx"/>: ConsoleAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-Console.xml)</em>
+  <p class="source">&lt;configuration>
 
   <b>&lt;appender name="STDOUT"
     class="ch.qos.logback.core.ConsoleAppender">
@@ -410,130 +415,167 @@
     &lt;level value="debug" />
     &lt;appender-ref ref="STDOUT" />
   &lt;/root>
-&lt;/configuration></pre></div>
-
-	<p>After you have set your current path to the
-	<em>logback-examples</em> directory, you can give the above
-	configuration file a whirl by issuing the following command:
-	</p>
+&lt;/configuration></p>
 
-<div class="source"><pre>java <a
-href="../xref/chapter4/ConfigurationTester.html">chapter4.ConfigurationTester</a> src/main/java/chapter4/conf/logback-Console.xml</pre></div>
-	
-	<a name="FileAppender"></a>
-	<h3>FileAppender</h3>
-	
-	<p>The <a
-	href="../xref/ch/qos/logback/core/FileAppender.html"><code>FileAppender</code></a>,
-	a subclass of <code>WriterAppender</code>, appends log events into a
-	file. The target fileis specified by the <span
-	class="option">File</span> option.  If the file already exists, it
-	is either appended to, or truncated depending on the value of the
-	<span class="option">Append</span> option.
-	<code>FileAppender</code> uses a <code>FileOutputStream</code> which
-	is wrapped by an <code>OutputStreamWriter</code>.  Note that
-	<code>OutputStreamWriter</code> buffers I/O operations but not
-	character conversions. To optimize character conversions one can set
-	the <span class="option">BufferedIO</span> option to true which
-	effectively wraps the <code>OutputStreamWriter</code> with a
-	<code>BufferedWriter</code>. Options for <code>FileAppender</code>
-	are summarized below.
-	</p>
-	
-	<table class="bodyTable">
-			<tr class="a">
-			<th>Option Name</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">Append</span></b></td>
-			<td><code>boolean</code></td>
-      <td>If true, events are appended at the end of an existing file.
-      Otherwise, if <span class="option">Append</span> is false, any
-      existing file is truncated. The <span
-      class="option">Append</span> option is set to true by
-      default.</td>
-		</tr>
-		<tr class="a">
-			<td><b><span class="option">Encoding</span></b></td>
-			<td><code>String</code></td>
-			<td>See <code>WriterAppender</code> options.</td>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">BufferedIO</span></b></td>
-			<td><code>boolean</code></td>
-			<td>The <span class="option">BufferedIO</span> option is set to
-			false by default.  If set to true, the underlying
-			<code>OutputStreamWriter</code> is wrapped by a
-			<code>BufferedWriter</code> object.  Setting <span
-			class="option">BufferedIO</span> to true automatically sets the
-			<span class="option">ImmediateFlush</span> option to false.  The
-			name <span class="option">BufferedIO</span> is slightly
-			misleading because buffered IO is already supported by
-			<code>OutputStreamWriter</code>.  Setting <span
-			class="option">BufferedIO</span> to true has the effect of
-			buffering I/O as well as character to raw byte conversions,
-			saving a few CPU cycles in the process.
-			</td>
-		</tr>
-		<tr class="a">
-			<td><b><span class="option">BufferSize</span></b></td>
-			<td><code>int</code></td>
-			<td>Size of <code>BufferedWriter</code> buffer. The default value is 8192.</td>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">File</span></b></td>
-			<td><code>String</code></td>
-			<td>The name of the file to write to. If the file does not
-			exist, it is created. On the MS Windows platform users
-			frequently forget to escape back slashes.  For example, the
-			value <em>c:\temp\test.log</em> is not likely to be interpreted
-			properly as <em>'\t'</em> is an escape sequence interpreted as a
-			single tab character <em>(\u0009)</em>.  Correct values can be
-			specified as <em>c:/temp/test.log</em> or alternatively as
-			<em>c:\\temp\\test.log</em>.  The <span
-			class="option">File</span> option has no default value.
-
-      <p>If the parent directory of the file does now exist, the
-      FileAppender will automatically create it, including any
-      necessary but nonexistent parent directories.
-      </p>
-			</td>
-		</tr>
-		<tr class="a">
-			<td><b><span class="option">ImmediateFlush</span></b></td>
-			<td><code>boolean</code></td>
-			<td>See <code>WriterAppender</code> options.</td>
-		</tr>
-	</table>
-	
-	<p>By default, <code>FileAppender</code> performs a flushes each
-	event, ensuring that events are immediately written to disk.
-	Setting the <span class="option">ImmediateFlush</span> option to
-	false can drastically reduce I/O activity by letting
-	<code>OutputStreamWriter</code> buffer bytes before writing them on
-	disk. For short messages, we have observed 2 or 3 fold increases in
-	logging throughput, i.e. the number of logs output per unit of
-	time. For longer messages, the throughput gains are somewhat less
-	dramatic, and range between 1.4 and 2 fold. Enabling the <span
-	class="option">BufferedIO</span> option, that is buffering character
-	to byte conversions, increases performance by an additional 10% to
-	40% compared to only disk I/O buffering (<span
-	class="option">ImmediateFlush</span>=false).  Performance varies
-	somewhat depending on the host machine as well as JDK version.
-	Throughput measurements are based on the <code>chapter4.IO</code>
-	application.  Please refer to <a href="../xref/chapter4/IO.html">
-	<em>logback-examples/src/main/java/chapter4/IO.java</em></a> for
-	actual source code.
-	</p>
+   <p>After you have set your current path to the
+   <em>logback-examples</em> directory, you can give the above
+   configuration file a whirl by issuing the following command:
+	 </p>
+
+   <p class="source">java <a
+   href="../xref/chapter4/ConfigurationTester.html">chapter4.ConfigurationTester</a> src/main/java/chapter4/conf/logback-Console.xml</p>
+	
+	
+   <h3>
+     <a name="FileAppender" href="#FileAppender">FileAppender</a>
+   </h3>
+	
+   <p>The <a
+   href="../xref/ch/qos/logback/core/FileAppender.html"><code>FileAppender</code></a>,
+   a subclass of <code>WriterAppender</code>, appends log events into
+   a file. The target fileis specified by the <span
+   class="option">File</span> option.  If the file already exists, it
+   is either appended to, or truncated depending on the value of the
+   <span class="option">Append</span> option.
+   <code>FileAppender</code> uses a <code>FileOutputStream</code>
+   which is wrapped by an <code>OutputStreamWriter</code>.  Note that
+   <code>OutputStreamWriter</code> buffers I/O operations but not
+   character conversions. To optimize character conversions one can
+   set the <span class="option">BufferedIO</span> option to true which
+   effectively wraps the <code>OutputStreamWriter</code> with a
+   <code>BufferedWriter</code>. Properties for <code>FileAppender</code>
+   are summarized below.
+   </p>
+	
+   <table class="bodyTable properties">
+     <tr>
+       <th>Property Name</th>
+       <th>Type</th>
+       <th>Description</th>
+     </tr>
+     <tr class="alt">
+       <td><b><span class="option">Append</span></b></td>
+       <td><code>boolean</code></td>
+       <td>If true, events are appended at the end of an existing
+       file.  Otherwise, if <span class="option">Append</span> is
+       false, any existing file is truncated. The <span
+       class="option">Append</span> option is set to true by
+       default.
+       </td>
+     </tr>
+     <tr >
+       <td><b><span class="option">Encoding</span></b></td>
+       <td><code>String</code></td>
+       <td>See <code>WriterAppender</code> properties.</td>
+     </tr>
+     <tr class="alt">
+       <td><b><span class="option">BufferedIO</span></b></td>
+       <td><code>boolean</code></td>
+       <td>The <span class="option">BufferedIO</span> option is set to
+       false by default.  If set to true, the underlying
+       <code>OutputStreamWriter</code> is wrapped by a
+       <code>BufferedWriter</code> object.  Setting <span
+       class="option">BufferedIO</span> to true automatically sets the
+       <span class="option">ImmediateFlush</span> option to false.
+       The name <span class="option">BufferedIO</span> is slightly
+       misleading because buffered IO is already supported by
+       <code>OutputStreamWriter</code>.  Setting <span
+       class="option">BufferedIO</span> to true has the effect of
+       buffering I/O as well as character to raw byte conversions,
+       saving a few CPU cycles in the process.
+			</td>
+     </tr>
+     <tr >
+       <td><b><span class="option">BufferSize</span></b></td>
+       <td><code>int</code></td>
+       <td>Size of <code>BufferedWriter</code> buffer. The default value is 8192.</td>
+     </tr>
+     <tr class="alt">
+       <td><b><span class="option">File</span></b></td>
+       <td><code>String</code></td>
+       <td>The name of the file to write to. If the file does not
+       exist, it is created. On the MS Windows platform users
+       frequently forget to escape back slashes.  For example, the
+       value <em>c:\temp\test.log</em> is not likely to be interpreted
+       properly as <em>'\t'</em> is an escape sequence interpreted as
+       a single tab character <em>(\u0009)</em>.  Correct values can
+       be specified as <em>c:/temp/test.log</em> or alternatively as
+       <em>c:\\temp\\test.log</em>.  The <span
+       class="option">File</span> option has no default value.
+
+       <p>If the parent directory of the file does now exist, the
+       FileAppender will automatically create it, including any
+       necessary but nonexistent parent directories.
+       </p>
+       </td>
+     </tr>
+     <tr >
+       <td><b><span class="option">ImmediateFlush</span></b></td>
+       <td><code>boolean</code></td>
+       <td>See <code>WriterAppender</code> properties.</td>
+     </tr>
+
+     <tr class="alt">
+       <td><b><span class="option bold"><a name="prudent"
+       href="#prudent">Prudent</a></span></b></td>
+       <td><code>boolean</code></td>
+
+       <td>
+         <p>In prudent mode, <code>FileAppeder</code> will safely
+         write to the specified file, even in the presence of other
+         <code>FileAppender</code> instances running in different
+         JVMs, potentially running on different hosts. The default
+         value for prudent mode is <code>false</code>.
+         </p>
+
+         <p>Prudent mode implies that <span
+         class="option">Append</span> and <span
+         class="option">ImmediateFlush</span> properties are
+         autmatically set to true and the <span
+         class="option">BufferedIO</span> set to false.
+         </p>
+
+         <p>Prudent mode will approximately triple (x3) the cost of
+         writing a logging event. On an "average" PC writing to a file
+         located on a local hard disk, when prudent mode is off, it
+         takes about 10 microseconds to write a single logging
+         event. When prudent mode is on, it takes approximately 30
+         microseconds to output a single logging event. This
+         translates to logging throughput of 100'00 events per second
+         when prudent mode is off and 30'000 events per second in
+         prudent mode.
+         </p>
+       </td>
+       
+     </tr>
+   </table>
 	
-	<p>Below is an example of a cconfiguration file for
-	<code>FileAppender</code>:
-	</p>
+ 	 <p>By default, <code>FileAppender</code> performs a flushes each
+ 	 event, ensuring that events are immediately written to disk.
+ 	 Setting the <span class="option">ImmediateFlush</span> option to
+ 	 false can drastically reduce I/O activity by letting
+ 	 <code>OutputStreamWriter</code> buffer bytes before writing them on
+ 	 disk. For short messages, we have observed 2 or 3 fold increases in
+ 	 logging throughput, i.e. the number of logs output per unit of
+ 	 time. For longer messages, the throughput gains are somewhat less
+ 	 dramatic, and range between 1.4 and 2 fold. Enabling the <span
+ 	 class="option">BufferedIO</span> option, that is buffering
+ 	 character to byte conversions, increases performance by an
+ 	 additional 10% to 40% compared to only disk I/O buffering (<span
+ 	 class="option">ImmediateFlush</span>=false).  Performance varies
+ 	 somewhat depending on the host machine as well as JDK version.
+ 	 Throughput measurements are based on the <code>chapter4.IO</code>
+ 	 application.  Please refer to <a href="../xref/chapter4/IO.html">
+ 	 <em>logback-examples/src/main/java/chapter4/IO.java</em></a> for
+ 	 actual source code.
+ 	 </p>
+	
+   <p>Below is an example of a cconfiguration file for
+   <code>FileAppender</code>:
+	 </p>
 
-<em>Example 4.3: FileAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-fileAppender.xml)</em>
-<div class="source"><pre>&lt;configuration>
+   <em>Example 4.<span class="autoEx"/>: FileAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-fileAppender.xml)</em>
+   <p class="source">&lt;configuration>
 
   <b>&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
     &lt;File>testFile.log&lt;/File>
@@ -548,116 +590,134 @@
     &lt;level value="debug" />
     &lt;appender-ref ref="FILE" />
   &lt;/root>
-&lt;/configuration></pre></div>
+&lt;/configuration></p>
 
-	<p>After changing the current directory to
-	<em>logback-examples</em>, run this example by lauching the
-	following command:
-	</p>
-	
-<div class="source"><pre>java chapter4.ConfigurationTester src/main/java/chapter4/conf/logback-fileAppender.xml</pre></div>
-	
-	
-	
-	<h3>
-  <a name="RollingFileAppender" 
-     href="#RollingFileAppender">RollingFileAppender</a></h3>
-	
-	<p><a
-	href="../xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>
-	extends <code>FileAppender</code> with the capability to roll log
-	files.  For example, <code>RollingFileAppender</code> can log to a
-	file named <em>log.txt</em> file and, once a certain condition is
-	met, change its logging target to another file.
-	</p>
-
-	<p>There are two important logback componenents that interact with
-	<code>RollingFileAppender</code>. First, a
-	<code>RollingPolicy</code> instance attached to the
-	<code>RollingFileAppender</code> is responsible for undertaking the
-	action for perfoming a rollover. Second, a
-	<code>TriggeringPolicy</code> instance attached to a
-	<code>RollingFileAppender</code> will determine if and exactly when
-	rollover happens Thus, <code>RollingPolicy</code> is responsible for
-	the <em>what</em> and <code>TriggeringPolicy</code> is responsible
-	for the <em>when</em>.
-	</p>
-	
-	<p>To be of any use, a <code>RollingFileAppender</code> must have
-	both a <code>RollingPolicy</code> and a
-	<code>TriggeringPolicy</code> set up. However, if its
-	<code>RollingPolicy</code> also implements the
-	<code>TriggeringPolicy</code> interface, then only the former needs
-	to be set up.
-	</p>
-	
-	<p>Here are the available options for <code>RollingFileAppender</code>:</p>
-	
-	<table class="bodyTable">
-			<tr class="a">
-			<th>Option Name</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">Append</span></b></td>
-			<td><code>boolean</code></td>
-			<td>See <code>FileAppender</code> options.</td>
-		</tr>	
-		<tr class="a">
-			<td><b><span class="option">BufferedIO</span></b></td>
-			<td><code>boolean</code></td>
-			<td>See <code>FileAppender</code> options.</td>
-		</tr>		
-		<tr class="b">
-			<td><b><span class="option">BufferSize</span></b></td>
-			<td><code>int</code></td>
-			<td>See <code>FileAppender</code> options.</td>
-		</tr>	
-		<tr class="a">
-			<td><b><span class="option">Encoding</span></b></td>
-			<td><code>String</code></td>
-			<td>See <code>WriterAppender</code> options.</td>
-		</tr>	
-		<tr class="b">
-			<td><b><span class="option">File</span></b></td>
-			<td><code>String</code></td>
-			<td>See <code>FileAppender</code> options.</td>
-		</tr>	
-		<tr class="a">
-			<td><b><span class="option">ImmediateFlush</span></b></td>
-			<td><code>boolean</code></td>
-			<td>See <code>WriterAppender</code> options.</td>
-		</tr>	
-		<tr class="b">
-			<td><b><span class="option">RollingPolicy</span></b></td>
-			<td><code>RollingPolicy</code></td>
-			<td>This option is the component that will dictate
-			<code>RollingFileAppender</code>'s behaviour when rollover
-			occurs. See more information below.
-			</td>
-		</tr>	
-		<tr class="a">
-			<td><b><span class="option">TriggeringPolicy</span></b></td>
-			<td><code>TriggeringPolicy</code></td>
-			<td>
-				This option is the component that will tell 
-				<code>RollingFileAppender</code> when to activate the rollover
-				procedure. See more information below.
-			</td>
-		</tr>	
-	</table>
-	
-	<h3>Rolling policies</h3>
-	
-	<p><a
-	href="../xref/ch/qos/logback/core/rolling/RollingPolicy.html"><code>RollingPolicy</code></a>
-	is responsible for the rollover procedure. It manages file renaming
-	and in occasion file deleting.</p>
-	
-	<p>The <code>RollingPolicy</code> interface is presented below:</p>
-	
-<div class="source"><pre>package ch.qos.logback.core.rolling;
+   <p>After changing the current directory to
+   <em>logback-examples</em>, run this example by lauching the
+   following command:
+   </p>
+	
+   <p class="source">java chapter4.ConfigurationTester src/main/java/chapter4/conf/logback-fileAppender.xml</p>
+	
+	
+	
+   <h3>
+     <a name="RollingFileAppender" 
+   href="#RollingFileAppender">RollingFileAppender</a></h3>
+   
+   <p><a
+	 href="../xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>
+	 extends <code>FileAppender</code> with the capability to roll log
+	 files.  For example, <code>RollingFileAppender</code> can log to a
+	 file named <em>log.txt</em> file and, once a certain condition is
+	 met, change its logging target to another file.
+   </p>
+     
+   <p>There are two important logback componenents that interact with
+   <code>RollingFileAppender</code>. First, a
+   <code>RollingPolicy</code> instance attached to the
+   <code>RollingFileAppender</code> is responsible for undertaking the
+   action for perfoming a rollover. Second, a
+   <code>TriggeringPolicy</code> instance attached to a
+   <code>RollingFileAppender</code> will determine if and exactly when
+   rollover happens Thus, <code>RollingPolicy</code> is responsible
+   for the <em>what</em> and <code>TriggeringPolicy</code> is
+   responsible for the <em>when</em>.
+   </p>
+	
+   <p>To be of any use, a <code>RollingFileAppender</code> must have
+   both a <code>RollingPolicy</code> and a
+   <code>TriggeringPolicy</code> set up. However, if its
+   <code>RollingPolicy</code> also implements the
+   <code>TriggeringPolicy</code> interface, then only the former needs
+   to be set up.
+   </p>
+	
+   <p>Here are the available properties for <code>RollingFileAppender</code>:</p>
+	
+   <table class="bodyTable">
+     <tr class="a">
+       <th>Property Name</th>
+       <th>Type</th>
+       <th>Description</th>
+     </tr>
+     <tr class="b">
+       <td><b><span class="option">Append</span></b></td>
+       <td><code>boolean</code></td>
+       <td>See <code>FileAppender</code> properties.</td>
+     </tr>	
+     <tr class="a">
+       <td><b><span class="option">BufferedIO</span></b></td>
+       <td><code>boolean</code></td>
+       <td>See <code>FileAppender</code> properties.</td>
+     </tr>		
+     <tr class="b">
+       <td><b><span class="option">BufferSize</span></b></td>
+       <td><code>int</code></td>
+       <td>See <code>FileAppender</code> properties.</td>
+     </tr>	
+     <tr class="a">
+       <td><b><span class="option">Encoding</span></b></td>
+       <td><code>String</code></td>
+       <td>See <code>WriterAppender</code> properties.</td>
+     </tr>	
+     <tr class="b">
+       <td><b><span class="option">File</span></b></td>
+       <td><code>String</code></td>
+       <td>See <code>FileAppender</code> properties.</td>
+     </tr>	
+     <tr class="a">
+       <td><b><span class="option">ImmediateFlush</span></b></td>
+       <td><code>boolean</code></td>
+       <td>See <code>WriterAppender</code> properties.</td>
+     </tr>	
+     <tr class="b">
+       <td><b><span class="option">RollingPolicy</span></b></td>
+       <td><code>RollingPolicy</code></td>
+       <td>This option is the component that will dictate
+       <code>RollingFileAppender</code>'s behaviour when rollover
+       occurs. See more information below.
+       </td>
+     </tr>	
+     <tr class="a">
+       <td><b><span class="option">TriggeringPolicy</span></b></td>
+       <td><code>TriggeringPolicy</code></td>
+       <td>
+         This option is the component that will tell 
+         <code>RollingFileAppender</code> when to activate the rollover
+         procedure. See more information below.
+       </td>
+     </tr>	
+     <tr class="b">
+       <td><span class="option"><b>Prudent</b></span></td>
+       <td><code>boolean</code></td>
+       <td>Prudent mode is supported by
+       <code>RollingFileAppender</code> in conjunction with <a
+       href="#TimeBasedRollingPolicy"><code>TimeBasedRollingPolicy</code></a>
+       with two restrictions. In prudent mode, file compression is not
+       supported nor allowed. Moreover, the <span
+       class="option">File</span> property of
+       <code>FileAppender</code> cannot be set.
+
+       <p><a
+       href="#FixedWindowRollingPolicy"><code>FixedWindowRollingPolicy</code></a>
+       is not supported in prudent mode.</p>
+
+       <p>See also <code>FileAppender</code> properties.</p>
+       </td>
+     </tr>
+   </table>
+	
+   <h3>Rolling policies</h3>
+	
+   <p><a
+   href="../xref/ch/qos/logback/core/rolling/RollingPolicy.html"><code>RollingPolicy</code></a>
+   is responsible for the rollover procedure. It manages file renaming
+   and in occasion file deleting.</p>
+	
+   <p>The <code>RollingPolicy</code> interface is presented below:</p>
+   
+   <p class="source">package ch.qos.logback.core.rolling;  
 
 import ch.qos.logback.core.FileAppender;
 import ch.qos.logback.core.spi.LifeCycle;
@@ -667,113 +727,112 @@
   <b>public void rollover() throws RolloverFailure;</b>
   public String getNewActiveFileName();
   public void setParent(FileAppender appender);
-}</pre></div>
-
-	<p>The <code>rollover</code> method proceeds to the file change,
-	renaming or deletion.  The <code>getNewActiveFileName()</code>
-	method is called to compute a new file name, with respect to the
-	configuration elements that were injected into the
-	<code>RollingPolicy</code>.  Lastly, a <code>RollingPolicy</code> is
-	given a reference to its parent via the <code>setParent</code>
-	method.
-	</p>
-
-	<h4>	
-    <a name="FixedWindowRollingPolicy" 
-       href="#FixedWindowRollingPolicy">FixedWindowRollingPolicy</a>
-  </h4>
-
-	<p>When rolling over, <a
-	href="../xref/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.html">
-	<code>FixedWindowRollingPolicy</code></a> renames files according to
-	a fixed window algorithm as described below.
-	</p>
-
-	<p>The <span class="option">FileNamePattern</span> option represents
-	the file name pattern for the archived (rolled over) log files.
-	This option is required and must include an integer token
-	<em>%i</em> somewhere within the pattern.
-  </p>
-	
-	<p>Here are the available options for
-	<code>FixedWindowRollingPolicy</code>
-	</p>
-	
-	<table class="bodyTable">
-			<tr class="a">
-			<th>Option Name</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">MinIndex</span></b></td>
-			<td><code>int</code></td>
-			<td>
-				<p>This option represents the lower bound for the window's
-				index.
-				</p>
-			</td>
-		</tr>
-    <tr class="a">
-      <td><b><span class="option">MaxIndex</span></b></td>
-      <td><code>int</code></td>
-			<td>
-        <p>This option represents the upper bound for the window's
-        index.
-				</p>
-			</td>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">FileNamePattern</span></b></td>
-			<td><code>String</code></td>
-			<td>
-				<p>This option represents the pattern that will be followed by
-				the <code>FixedWindowRollingPolicy</code> when renaming the
-				log files. If must contain the string <em>%i</em>, which will
-				indicate the position where the value of the current window
-				index will be inserted.
-				</p>
-				<p>For example, using <em>MyLogFile%i.log</em>, associated
-				with minimum and maximum values of <em>1</em> and <em>3</em>
-				will produce archive files named <em>MyLogFile1.log</em>,
-				<em>MyLogFile2.log</em> and <em>MyLogFile3.log</em>.
-				</p>
-				<p>Note that file compression is also specified via the <span
-				class="option">FileNamePattern</span> option. For example, the
-				file name pattern <em>MyLogFile%i.log.zip</em> will indicate
-				to the <code>FixedWindowRollingPolicy</code> that the archived
-				file must be compressed using the <em>zip</em> format;
-				<em>gz</em> format is also supported.
-				</p>
-			</td>
-		</tr>	
-		
-	</table>
+}</p>
 
-	<p>Given that the fixed window rolling policy requires as many file
-	renaming operations as the window size, large window sizes are
-	strongly discouraged. The current implementation will automatically
-	reduce the window size to 12, when larger values are specified by
-	the user.
-	</p>
-
-	<p>Let us go over a more concrete example of the fixed windows
-	rollover policy. Suppose that the <span
-	class="option">MinIndex</span> is set to <em>1</em>, <span
-	class="option">MaxIndex</span> set to <em>3</em>, that <span
-	class="option">FileNamePattern</span> option is set to
-	<em>foo%i.log</em>, and that <span
-	class="option">FileNamePattern</span> option is set to
-	<em>foo.log</em>.
-	</p>
-	
-	<table class="bodyTable">
-		<tr class="a">
-			<th>Number of rollovers</th>
-			<th>Active output target</th>
-			<th>Archived log files</th>
-			<th>Description</th>
-		</tr>
+   <p>The <code>rollover</code> method proceeds to the file change,
+   renaming or deletion.  The <code>getNewActiveFileName()</code>
+   method is called to compute a new file name, with respect to the
+   configuration elements that were injected into the
+   <code>RollingPolicy</code>.  Lastly, a <code>RollingPolicy</code>
+   is given a reference to its parent via the <code>setParent</code>
+   method.
+   </p>
+
+   <h4>	
+     <a name="FixedWindowRollingPolicy" 
+     href="#FixedWindowRollingPolicy">FixedWindowRollingPolicy</a>
+   </h4>
+
+   <p>When rolling over, <a
+   href="../xref/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.html">
+   <code>FixedWindowRollingPolicy</code></a> renames files according
+   to a fixed window algorithm as described below.
+   </p>
+
+   <p>The <span class="option">FileNamePattern</span> option
+   represents the file name pattern for the archived (rolled over) log
+   files.  This option is required and must include an integer token
+   <em>%i</em> somewhere within the pattern.
+   </p>
+	
+   <p>Here are the available properties for
+   <code>FixedWindowRollingPolicy</code>
+   </p>
+	
+   <table class="bodyTable">
+     <tr class="a">
+       <th>Property Name</th>
+       <th>Type</th>
+       <th>Description</th>
+     </tr>
+     <tr class="b">
+       <td><b><span class="option">MinIndex</span></b></td>
+       <td><code>int</code></td>
+       <td>
+         <p>This option represents the lower bound for the window's
+         index.
+         </p>
+       </td>
+     </tr>
+     <tr class="a">
+       <td><b><span class="option">MaxIndex</span></b></td>
+       <td><code>int</code></td>
+       <td>
+         <p>This option represents the upper bound for the window's
+         index.
+         </p>
+       </td>
+     </tr>
+     <tr class="b">
+       <td><b><span class="option">FileNamePattern</span></b></td>
+       <td><code>String</code></td>
+       <td>
+         <p>This option represents the pattern that will be followed
+         by the <code>FixedWindowRollingPolicy</code> when renaming
+         the log files. If must contain the string <em>%i</em>, which
+         will indicate the position where the value of the current
+         window index will be inserted.
+         </p>
+         <p>For example, using <em>MyLogFile%i.log</em>, associated
+         with minimum and maximum values of <em>1</em> and <em>3</em>
+         will produce archive files named <em>MyLogFile1.log</em>,
+         <em>MyLogFile2.log</em> and <em>MyLogFile3.log</em>.
+         </p>
+         <p>Note that file compression is also specified via the <span
+         class="option">FileNamePattern</span> option. For example, the
+         file name pattern <em>MyLogFile%i.log.zip</em> will indicate
+         to the <code>FixedWindowRollingPolicy</code> that the archived
+         file must be compressed using the <em>zip</em> format;
+         <em>gz</em> format is also supported.
+         </p>
+       </td>
+     </tr>			
+   </table>
+   
+   <p>Given that the fixed window rolling policy requires as many file
+   renaming operations as the window size, large window sizes are
+   strongly discouraged. The current implementation will automatically
+   reduce the window size to 12, when larger values are specified by
+   the user.
+   </p>
+
+   <p>Let us go over a more concrete example of the fixed windows
+   rollover policy. Suppose that the <span
+   class="option">MinIndex</span> is set to <em>1</em>, <span
+   class="option">MaxIndex</span> set to <em>3</em>, that <span
+   class="option">FileNamePattern</span> option is set to
+   <em>foo%i.log</em>, and that <span
+   class="option">FileNamePattern</span> option is set to
+   <em>foo.log</em>.
+   </p>
+	
+   <table class="bodyTable">
+     <tr class="a">
+       <th>Number of rollovers</th>
+       <th>Active output target</th>
+       <th>Archived log files</th>
+       <th>Description</th>
+     </tr>
 		<tr class="b">
 			<td>0</td>
 			<td>foo.log</td>
@@ -781,61 +840,62 @@
 			<td>No rollover has happened yet, logback logs into the initial
 			file.
 			</td>
-		</tr>		
-		<tr class="a">
-			<td>1</td>
-			<td>foo.log</td>
-			<td>foo1.log</td>
-			<td>First rollover. <em>foo.log</em> is renamed as
-			<em>foo1.log</em>. A new <em>foo.log</em> file is created and
-			becomes the active output target.
-			</td>
-		</tr>
-		<tr class="b">
-			<td>2</td>
-			<td>foo.log</td>
-			<td>foo1.log, foo2.log</td>
-			<td>Second rollover. <em>foo1.log</em> is renamed as
-			<em>foo2.log</em>.  <em>foo.log</em> is renamed as
-			<em>foo1.log</em>. A new <em>foo.log</em> file is created and
-			becomes the active output target.
-			</td>
-		</tr>
-		<tr class="a">
-			<td>3</td>
-			<td>foo.log</td>
-			<td>foo1.log, foo2.log, foo3.log</td>
-			<td>Third rollover.  <em>foo2.log</em> is renamed as
-			<em>foo3.log</em>. <em>foo1.log</em> is renamed as
-			<em>foo2.log</em>.  <em>foo.log</em> is renamed as
-			<em>foo1.log</em>. A new <em>foo.log</em> file is created and
-			becomes the active output target.
-			</td>
-		</tr>
-		<tr class="b">
-			<td>4</td>
-			<td>foo.log</td>
-			<td>foo1.log, foo2.log, foo3.log</td>
-			<td>In this and subsequent rounds, the rollover begins by
-			deleting <em>foo3.log</em>. Otherfiles are renamed by
-			incrementing their index as shown in previous steps. In this and
-			subsequent rollovers, there will be three archive logs and one
-			active log file.
-			</td>
-		</tr>
-	</table>
-	
-	<p>The configuration file below gives an example of configuring
-	<code>RollingFileAppender</code> and
-	<code>FixedWindowRollingPolicy</code>. Note that the <span
-	class="option">File</span> option is mandatory even if it contains
-	some of the same information as conveyed with the <span
-	class="option">FileNamePattern</span> option.
-	</p>
+     </tr>		
+     <tr class="a">
+       <td>1</td>
+       <td>foo.log</td>
+       <td>foo1.log</td>
+       <td>First rollover. <em>foo.log</em> is renamed as
+       <em>foo1.log</em>. A new <em>foo.log</em> file is created and
+       becomes the active output target.
+       </td>
+     </tr>
+     <tr class="b">
+       <td>2</td>
+       <td>foo.log</td>
+       <td>foo1.log, foo2.log</td>
+       <td>Second rollover. <em>foo1.log</em> is renamed as
+       <em>foo2.log</em>.  <em>foo.log</em> is renamed as
+       <em>foo1.log</em>. A new <em>foo.log</em> file is created and
+       becomes the active output target.
+       </td>
+     </tr>
+     <tr class="a">
+       <td>3</td>
+       <td>foo.log</td>
+       <td>foo1.log, foo2.log, foo3.log</td>
+       <td>Third rollover.  <em>foo2.log</em> is renamed as
+       <em>foo3.log</em>. <em>foo1.log</em> is renamed as
+       <em>foo2.log</em>.  <em>foo.log</em> is renamed as
+       <em>foo1.log</em>. A new <em>foo.log</em> file is created and
+       becomes the active output target.
+       </td>
+     </tr>
+     <tr class="b">
+       <td>4</td>
+       <td>foo.log</td>
+       <td>foo1.log, foo2.log, foo3.log</td>
+       <td>In this and subsequent rounds, the rollover begins by
+       deleting <em>foo3.log</em>. Otherfiles are renamed by
+       incrementing their index as shown in previous steps. In this and
+       subsequent rollovers, there will be three archive logs and one
+       active log file.
+       </td>
+     </tr>
+   </table>
+	
+   <p>The configuration file below gives an example of configuring
+   <code>RollingFileAppender</code> and
+   <code>FixedWindowRollingPolicy</code>. Note that the <span
+   class="option">File</span> option is mandatory even if it contains
+   some of the same information as conveyed with the <span
+   class="option">FileNamePattern</span> option.
+   </p>
 	
-<em>Example 4.4: Sample configuration of a <code>RollingFileAppender</code> using a 
-<code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-RollingFixedWindow.xml)</em>
-<div class="source"><pre>&lt;configuration>
+   <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a 
+   <code>FixedWindowRollingPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-RollingFixedWindow.xml)</em>
+
+   <p class="source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     <b>&lt;File>test.log&lt;/File></b>
 
@@ -857,124 +917,125 @@
     &lt;level value="debug" />
     &lt;appender-ref ref="FILE" />
   &lt;/root>
-&lt;/configuration></pre></div>
-	
-  <h4>
-    <a name="TimeBasedRollingPolicy" href="#TimeBasedRollingPolicy">TimeBasedRollingPolicy</a>
-  </h4>
-
-	<p>
-		<a href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
-		<code>TimeBasedRollingPolicy</code></a> is possibly the most
-		popular rolling polciy. It defines a rollover policy based on
-		time, say by day or by month.
-	</p>
-
-	<p><code>TimeBasedRollingPolicy</code>'s admits two properties, the
-	mandatory <span class="option">FileNamePattern</span> property and
-	the optinal <span class="option">MaxHistory</span> property.
-	</p>
-	
-	<p><span class="option">FileNamePattern</span> option defines the
-	name of the rolled (archived) log files. Its value should consist of
-	the name of the file, plus a suitably placed <em>%d</em> conversion
-	specifier.  The <em>%d</em> conversion specifier may contain a
-	date-and-time pattern as specified by the
-	<code>java.text.SimpleDateFormat</code> class.  If the date-and-time
-	pattern is omitted, then the default pattern <em>yyyy-MM-dd</em> is
-	assumed. The following examples should clarify the point.
-	</p>
-
-	<table class="bodyTable">
-		<tr class="a">
-			<th>
-				<span class="option">FileNamePattern</span>
-			</th>
-			<th>Roll-over schedule</th>
-			<th>Example</th>
-		</tr>
-		<tr class="b">
-      <td class="small">
-				<em>/wombat/folder/foo.%d</em>
-			</td>
-			<td>Daily rollover (at midnight). Due to the omission of the
-			optional time and date pattern for the <em>%d</em> token
-			specifier, the default pattern of <em>yyyy-MM-dd</em> is
-			assumed, which corresponds to daily rollover.
-			</td>
-			<td>During November 23rd, 2006, logging output will go to the
-			file <em>/wombat/foo.2006-11-23</em>.  At midnight and for the
-			rest of the 24th, logging output will be directed to
-			<em>/wombat/foo.2006-11-24</em>.
-			</td>
-		</tr>
-		<tr class="a">
-			<td class="small">
-				<em>/wombat/foo.%d{yyyy-MM}.log</em>
-			</td>
-			<td>Rollover at the beginning of each month.</td>
-			<td>During the month of October 2006, logging output will go to
-			<em>/wombat/foo.2006-10.log</em>.  After midnight of October
-			31st and for the rest of November, logging output will be
-			directed to <em>/wombat/foo.2006-11.log</em>.
-			</td>
-		</tr>
-		<tr class="b">
-			<td class="small">
-				<em>/wombat/foo.%d{yyyy-ww}.log</em>
-			</td>
-
-      <td>Rollover at the first day of each week. Note that the first
-      day of the week depends on the locale.</td>
-
-			<td>During the 23rd week of 2006, the file
-			<em>/wombat/foo.2006-23.log</em> will contain the actual logging
-			output.  Logging for the 24th week of 2006 will be output to
-			<em>/wombat/foo.2006-24.log</em> until it is rolled over at the
-			beginning of the next week.
-			</td>
-		</tr>	
-		<tr class="a">
-			<td class="small">
-				<em>/wombat/foo.  &nbsp;&nbsp;/<br/>%d{yyyy-MM-dd_HH}.log</em>
-			</td>
-			<td>Rollover at the top of each hour.</td>
-			<td>Between 11.00,001 and 11.59,999, on November 3rd, 2006, the
-			logging will be output to
-			<em>/wombat/foo.2006-11-03_11.log</em>.  After that, and until
-			12.59,999, the logging will be output to
-			<em>/wombat/foo.2006-11-03_12.log</em>.
-			</td>
-		</tr>
-		<tr class="b">
-			<td class="small">
-				<em>/wombat/foo. &nbsp;&nbsp; /<br/>%d{yyyy-MM-dd_HH-mm}.log</em>
-			</td>
-			<td>Rollover at the beggining of every minute.</td>
-			<td>Between 11.32,001 and 11.32,999, on November 3rd, 2006, the
-			logging will be output to
-			<em>/wombat/foo.2006-11-03_11-32.log</em>.  After that, and
-			until 12.33,999, the logging will be output to
-			<em>/wombat/foo.2006-11_12-33.log</em>.
-			</td>
-		</tr>
-	</table>
+&lt;/configuration></p>
 	
-	<p>Any characters in the pattern outside the ranges
-	<em>['a'..'z']</em> and <em>['A'..'Z']</em> will be treated as
-	quoted text. For instance, characters like <em>'.'</em>, <em>'
-	'</em>, <em>'#'</em> and <em>'@'</em> will appear in the resulting
-	time text even when they are not enclosed within single
-	quotes. Nevertheless, we recommend against using the colon
-	<em>":"</em> character anywhere within the <span
-	class="option">FileNamePattern</span> option.  The text before the
-	colon is interpreted as the protocol specification of a URL, which
-	is most probably not what you intend. The slash <em>"/"</em>
-	character, a common date field separator, must also be avoided. It
-	is taken as a file separator causing the rollover operation to fail
-	because the target file cannot be created. Although less common, the
-	backslash character <em>"\"</em> is equally troublesome.
-	</p>
+   <h4>
+     <a name="TimeBasedRollingPolicy" href="#TimeBasedRollingPolicy">TimeBasedRollingPolicy</a>
+   </h4>
+
+   <p><a
+   href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
+   <code>TimeBasedRollingPolicy</code></a> is possibly the most
+   popular rolling polciy. It defines a rollover policy based on time,
+   say by day or by month.
+   </p>
+
+   <p><code>TimeBasedRollingPolicy</code>'s admits two properties, the
+   mandatory <span class="option">FileNamePattern</span> property and
+   the optinal <span class="option">MaxHistory</span> property.
+   </p>
+	
+   <p><span class="option">FileNamePattern</span> option defines the
+   name of the rolled (archived) log files. Its value should consist
+   of the name of the file, plus a suitably placed <em>%d</em>
+   conversion specifier.  The <em>%d</em> conversion specifier may
+   contain a date-and-time pattern as specified by the
+   <code>java.text.SimpleDateFormat</code> class.  If the
+   date-and-time pattern is omitted, then the default pattern
+   <em>yyyy-MM-dd</em> is assumed. The following examples should
+   clarify the point.
+   </p>
+   
+   <table class="bodyTable">
+     <tr class="a">
+       <th>
+         <span class="option">FileNamePattern</span>
+       </th>
+       <th>Roll-over schedule</th>
+       <th>Example</th>
+     </tr>
+     <tr class="b">
+       <td class="small">
+         <em>/wombat/folder/foo.%d</em>
+       </td>
+       <td>Daily rollover (at midnight). Due to the omission of the
+       optional time and date pattern for the <em>%d</em> token
+       specifier, the default pattern of <em>yyyy-MM-dd</em> is
+       assumed, which corresponds to daily rollover.
+       </td>
+       <td>During November 23rd, 2006, logging output will go to the
+       file <em>/wombat/foo.2006-11-23</em>.  At midnight and for the
+       rest of the 24th, logging output will be directed to
+       <em>/wombat/foo.2006-11-24</em>.
+       </td>
+     </tr>
+     <tr class="a">
+       <td class="small">
+         <em>/wombat/foo.%d{yyyy-MM}.log</em>
+       </td>
+       <td>Rollover at the beginning of each month.</td>
+       <td>During the month of October 2006, logging output will go to
+       <em>/wombat/foo.2006-10.log</em>.  After midnight of October
+       31st and for the rest of November, logging output will be
+       directed to <em>/wombat/foo.2006-11.log</em>.
+       </td>
+     </tr>
+     <tr class="b">
+       <td class="small">
+         <em>/wombat/foo.%d{yyyy-ww}.log</em>
+       </td>
+       
+       <td>Rollover at the first day of each week. Note that the first
+       day of the week depends on the locale.</td>
+       
+       <td>During the 23rd week of 2006, the file
+       <em>/wombat/foo.2006-23.log</em> will contain the actual logging
+       output.  Logging for the 24th week of 2006 will be output to
+       <em>/wombat/foo.2006-24.log</em> until it is rolled over at the
+       beginning of the next week.
+       </td>
+     </tr>	
+     <tr class="a">
+       <td class="small">
+         <em>/wombat/foo.  &nbsp;&nbsp;/<br/>%d{yyyy-MM-dd_HH}.log</em>
+       </td>
+       <td>Rollover at the top of each hour.</td>
+       <td>Between 11.00,001 and 11.59,999, on November 3rd, 2006, the
+       logging will be output to
+       <em>/wombat/foo.2006-11-03_11.log</em>.  After that, and until
+       12.59,999, the logging will be output to
+       <em>/wombat/foo.2006-11-03_12.log</em>.
+       </td>
+     </tr>
+     <tr class="b">
+       <td class="small">
+         <em>/wombat/foo. &nbsp;&nbsp; /<br/>%d{yyyy-MM-dd_HH-mm}.log</em>
+       </td>
+       <td>Rollover at the beggining of every minute.</td>
+       <td>Between 11.32,001 and 11.32,999, on November 3rd, 2006, the
+       logging will be output to
+       <em>/wombat/foo.2006-11-03_11-32.log</em>.  After that, and
+       until 12.33,999, the logging will be output to
+       <em>/wombat/foo.2006-11_12-33.log</em>.
+       </td>
+     </tr>
+   </table>
+   
+   <p>Any characters in the pattern outside the ranges
+   <em>['a'..'z']</em> and <em>['A'..'Z']</em> will be treated as
+   quoted text. For instance, characters like <em>'.'</em>, <em>'
+   '</em>, <em>'#'</em> and <em>'@'</em> will appear in the resulting
+   time text even when they are not enclosed within single
+   quotes. Nevertheless, we recommend against using the colon
+   <em>":"</em> character anywhere within the <span
+   class="option">FileNamePattern</span> option.  The text before the
+   colon is interpreted as the protocol specification of a URL, which
+   is most probably not what you intend. The slash <em>"/"</em>
+   character, a common date field separator, must also be avoided. It
+   is taken as a file separator causing the rollover operation to fail
+   because the target file cannot be created. Although less common,
+   the backslash character <em>"\"</em> is equally troublesome.
+   </p>
 
 	<p>Just like <code>FixedWindowRollingPolicy</code>,
 	<code>TimeBasedRollingPolicy</code> supports automatic file
@@ -1056,9 +1117,9 @@
   <code>TimeBasedRollingPolicy</code>.
 	</p>
 	
-<em>Example 4.5: Sample configuration of a <code>RollingFileAppender</code> using a 
-<code>TimeBasedRollingPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-RollingTimeBased.xml)</em>
-<div class="source"><pre>&lt;configuration>
+  <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a 
+  <code>TimeBasedRollingPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-RollingTimeBased.xml)</em>
+  <p class="source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     &lt;File>logFile.log&lt;/File>
     <b>&lt;rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
@@ -1076,7 +1137,37 @@
     &lt;level value="debug" />
     &lt;appender-ref ref="FILE" />
   &lt;/root>
-&lt;/configuration></pre></div>
+&lt;/configuration></p>
+
+    <p>The next configuration sample illustrates the use
+    <code>RollingFileAppender</code> associated with
+    <code>TimeBasedRollingPolicy</code> in <span class="option">Prudent</span>
+    mode.
+    </p>
+
+  <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a 
+  <code>TimeBasedRollingPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-PrudentTimeBasedRolling.xml)</em>
+  <p class="source">&lt;configuration>
+  &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <b>&lt;!-- Support multiple-JVM writing to the same log file --></b>
+    <b>&lt;Prudent>true&lt;/Prudent></b>
+    &lt;rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      &lt;FileNamePattern>logFile.%d{yyyy-MM-dd}.log&lt;/FileNamePattern>
+      &lt;MaxHistory>30&lt;/MaxHistory> 
+    &lt;/rollingPolicy>
+
+    &lt;layout class="ch.qos.logback.classic.PatternLayout">
+      &lt;Pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/Pattern>
+    &lt;/layout>
+  &lt;/appender> 
+
+  &lt;root>
+    &lt;level value="debug" />
+    &lt;appender-ref ref="FILE" />
+  &lt;/root>
+&lt;/configuration></p>
+
+    
 
 		<a name="TriggeringPolicy"></a>
 		<h3>Triggering policies</h3>
@@ -1089,7 +1180,7 @@
 		<p>The <code>TriggeringPolicy</code> interface contains only one
 		method.</p>
 	
-<div class="source"><pre>package ch.qos.logback.core.rolling;
+    <p class="source">package ch.qos.logback.core.rolling;
 
 import java.io.File;
 import ch.qos.logback.core.spi.LifeCycle;
@@ -1097,13 +1188,12 @@
 public interface TriggeringPolicy&lt;E&gt; extends LifeCycle {
 
   <b>public boolean isTriggeringEvent(final File activeFile, final &lt;E&gt; event);</b>
-}</pre></div>
+}</p>
 
-		<p>
-			The <code>isTriggeringEvent()</code> method takes as parameters
-			the active file, and the logging event currently being
-			processed. The concrete implementation determines whether the
-			rollover should occur or not, based on the said parameters.
+		<p>The <code>isTriggeringEvent()</code> method takes as parameters
+		the active file, and the logging event currently being
+		processed. The concrete implementation determines whether the
+		rollover should occur or not, based on the said parameters.
 		</p>
 
 		<a name="SizeBasedTriggeringPolicy"></a>
@@ -1136,9 +1226,9 @@
 		<code>SizeBasedTriggeringPolicy</code>.
 		</p>
 
-<em>Example 4.6: Sample configuration of a <code>RollingFileAppender</code> using a 
-<code>SizeBasedTriggeringPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-RollingSizeBased.xml)</em>
-<div class="source"><pre>&lt;configuration>
+    <em>Example 4.<span class="autoEx"/>: Sample configuration of a <code>RollingFileAppender</code> using a 
+    <code>SizeBasedTriggeringPolicy</code> (logback-examples/src/main/java/chapter4/conf/logback-RollingSizeBased.xml)</em>
+    <p class="source">&lt;configuration>
   &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
     &lt;File>testFile.log&lt;/File>
     &lt;rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
@@ -1159,7 +1249,7 @@
     &lt;level value="debug" />
     &lt;appender-ref ref="FILE" />
   &lt;/root>
-&lt;/configuration></pre></div>
+&lt;/configuration></p>
 
 	
     <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx -->
@@ -1173,43 +1263,45 @@
 
     </p>
 
-		<a name="SocketAppender"></a>
-		<h3>SocketAppender</h3>
-		
-		<p>
-			The appenders covered this far were only able to log on local resources. 
-			In contrast, the <a href="../xref/ch/qos/logback/classic/net/SocketAppender.html">
-			<code>SocketAppender</code></a> is designed to log to a 
-			remote entity by transmitting serialized <code>LoggingEvent</code> objects over the wire. 
-			Remote logging is non-intrusive as far as the logging event is concerned. 
-			On the receiving end after de-serialization, the event can be logged as 
-			if it were generated locally. Multiple <code>SocketAppender</code> instances 
-			running of different machines can direct their logging output 
-			to a central log server whose format is fixed. 
-			<code>SocketAppender</code> does not admit an 
-			associated layout because it sends serialized events to a remote server. 
-			<code>SocketAppender</code> operates above the 
-			<em>Transmission Control Protocol (TCP)</em> 
-			layer which provides a reliable, sequenced, flow-controlled end-to-end octet stream. 
-			Consequently, if the remote server is reachable, then log events 
-			will eventually arrive there. Otherwise, if the remote server is down or 
-			unreachable, the logging events will simply be dropped. If and when the server 
-			comes back up, then event transmission will be resumed transparently. 
-			This transparent reconnection is performed by a connector thread which 
-			periodically attempts to connect to the server.
-		</p>
+		<h3> 
+      <a name="SocketAppender" href="#SocketAppender">SocketAppender</a>
+    </h3>
 		
-		<p>
-			Logging events are automatically buffered by the native TCP implementation. 
-			This means that if the link to server is slow but still faster than the 
-			rate of event production by the client, the client will not be affected by 
-			the slow network connection. However, if the network connection is slower 
-			then the rate of event production, then the client can only progress at the 
-			network rate. In particular, in the extreme case where the network link 
-			to the server is down, the client will be eventually blocked. 
-			Alternatively, if the network link is up, but the server is down, 
-			the client will not be blocked, although the log events will be 
-			lost due to server unavailability.
+		<p>The appenders covered this far were only able to log on local
+		resources.  In contrast, the <a
+		href="../xref/ch/qos/logback/classic/net/SocketAppender.html">
+		<code>SocketAppender</code></a> is designed to log to a remote
+		entity by transmitting serialized <code>LoggingEvent</code>
+		objects over the wire.  Remote logging is non-intrusive as far as
+		the logging event is concerned.  On the receiving end after
+		de-serialization, the event can be logged as if it were generated
+		locally. Multiple <code>SocketAppender</code> instances running of
+		different machines can direct their logging output to a central
+		log server whose format is fixed.  <code>SocketAppender</code>
+		does not admit an associated layout because it sends serialized
+		events to a remote server.  <code>SocketAppender</code> operates
+		above the <em>Transmission Control Protocol (TCP)</em> layer which
+		provides a reliable, sequenced, flow-controlled end-to-end octet
+		stream.  Consequently, if the remote server is reachable, then log
+		events will eventually arrive there. Otherwise, if the remote
+		server is down or unreachable, the logging events will simply be
+		dropped. If and when the server comes back up, then event
+		transmission will be resumed transparently.  This transparent
+		reconnection is performed by a connector thread which periodically
+		attempts to connect to the server.
+		</p>
+		
+		<p>Logging events are automatically buffered by the native TCP
+		implementation.  This means that if the link to server is slow but
+		still faster than the rate of event production by the client, the
+		client will not be affected by the slow network
+		connection. However, if the network connection is slower then the
+		rate of event production, then the client can only progress at the
+		network rate. In particular, in the extreme case where the network
+		link to the server is down, the client will be eventually blocked.
+		Alternatively, if the network link is up, but the server is down,
+		the client will not be blocked, although the log events will be
+		lost due to server unavailability.
 		</p>
 		
 		<p>Even if a <code>SocketAppender</code> is no longer attached to
@@ -1234,108 +1326,108 @@
 		
 		<p>The remote server is identified by the <span
 		class="option">RemoteHost</span> and <span
-		class="option">Port</span> options.  <code>SocketAppender</code>
-		options are listed in the following table.
+		class="option">Port</span> properties.
+		<code>SocketAppender</code> properties are listed in the following
+		table.
 		</p>
 
     <table class="bodyTable">
       <tr class="a">
-			<th>Option Name</th>
+			<th>Property Name</th>
 			<th>Type</th>
 			<th>Description</th>
-		</tr>
-		<tr class="b">
-			<td><b><span class="option">IncludeCallerData</span></b></td>
-			<td><code>boolean</code></td>
-			<td>
-				<p>
-					The <span class="option">IncludeCallerData</span> option takes a boolean value. 
-					If true, the caller data will be available to the remote host. 
-					By default no caller data is sent to the server.
-				</p>
-			</td>
-		</tr>
-		<tr class="a">
-			<td><b><span class="option">Port</span></b></td>
-			<td><code>int</code></td>
-			<td>
-				<p>
-					The port number of the remote server.
-				</p>
-			</td>
-		</tr>	
-		<tr class="b">
-			<td><b><span class="option">ReconnectionDelay</span></b></td>
-			<td><code>int</code></td>
-			<td>
-					The <span class="option">ReconnectionDelay</span> option takes a 
-					positive integer representing the number of milliseconds to wait between 
-					each failed connection attempt to the server. 
-					The default value of this option is 30'000 which corresponds to 30 seconds. 
-					Setting this option to zero turns off reconnection capability. 
-					Note that in case of successful connection to the server, there will be no 
-					connector thread present.
-			</td>
-		</tr>
-		<tr class="a">
-			<td><b><span class="option">RemoteHost</span></b></td>
-			<td><code>String</code></td>
-			<td>
-					The host name of the server.
-			</td>
-		</tr>		
-	</table>
-	
-	<p>
-		The standard logback distribution includes a simple log server application named
-		<code>ch.qos.logback.classic.net.SimpleSocketServer</code> that can service multiple 
-		<code>SocketAppender</code> clients. It waits for logging events from 
-		<code>SocketAppender</code> clients. After reception by 
-		<code>SimpleSocketServer</code>, the events are logged according to local server policy. 
-		The <code>SimpleSocketServer</code> application takes two parameters: 
-		port and configFile; where port is the port to listen on and configFile is 
-		configuration script in XML format. 
-	</p>
-	
-	<p>
-		Assuming you are in the <em>logback-examples/</em> directory, 
-		start <code>SimpleSocketServer</code> with the following command:
-	</p>
+      </tr>
+      <tr class="b">
+        <td><b><span class="option">IncludeCallerData</span></b></td>
+        <td><code>boolean</code></td>
+        <td>
+          <p>
+            The <span class="option">IncludeCallerData</span> option takes a boolean value. 
+            If true, the caller data will be available to the remote host. 
+            By default no caller data is sent to the server.
+          </p>
+        </td>
+      </tr>
+      <tr class="a">
+        <td><b><span class="option">Port</span></b></td>
+        <td><code>int</code></td>
+        <td>
+          <p>
+            The port number of the remote server.
+          </p>
+        </td>
+      </tr>	
+      <tr class="b">
+        <td><b><span class="option">ReconnectionDelay</span></b></td>
+        <td><code>int</code></td>
+        <td>
+          The <span class="option">ReconnectionDelay</span> option takes a 
+          positive integer representing the number of milliseconds to wait between 
+          each failed connection attempt to the server. 
+          The default value of this option is 30'000 which corresponds to 30 seconds. 
+          Setting this option to zero turns off reconnection capability. 
+          Note that in case of successful connection to the server, there will be no 
+          connector thread present.
+        </td>
+      </tr>
+      <tr class="a">
+        <td><b><span class="option">RemoteHost</span></b></td>
+        <td><code>String</code></td>
+        <td>
+          The host name of the server.
+        </td>
+      </tr>		
+    </table>
+    
+    <p>The standard logback distribution includes a simple log server
+    application named
+    <code>ch.qos.logback.classic.net.SimpleSocketServer</code> that
+    can service multiple <code>SocketAppender</code> clients. It waits
+    for logging events from <code>SocketAppender</code> clients. After
+    reception by <code>SimpleSocketServer</code>, the events are
+    logged according to local server policy.  The
+    <code>SimpleSocketServer</code> application takes two parameters:
+    port and configFile; where port is the port to listen on and
+    configFile is configuration script in XML format.
+    </p>
 	
-<div class="source"><pre>java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
-  src/main/java/chapter4/socket/server1.xml
-</pre></div>
+    <p>
+      Assuming you are in the <em>logback-examples/</em> directory, 
+      start <code>SimpleSocketServer</code> with the following command:
+    </p>
+    
+    <p class="source">java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
+  src/main/java/chapter4/socket/server1.xml</p>
 
-	<p>
-		where 6000 is the port number to listen on and <em>server1.xml</em> is a 
-		configuration script that adds a <code>ConsoleAppender</code> and a 
-		<code>RollingFileAppender</code> to the root logger. 
-		After you have started <code>SimpleSocketServer</code>, you can send it 
-		log events from multiple clients using <code>SocketAppender</code>.  
-		The examples associated with this manual include two such clients: 
-		<code>chapter4.SocketClient1</code> and <code>chapter4.SocketClient2</code> 
-		Both clients wait for the user to type a line of text on the console. 
-		The text is encapsulated in a logging event of level debug and then sent 
-		to the remote server. The two clients differ in the configuration of the 
-		<code>SocketAppender</code>. <code>SocketClient1</code> configures the appender 
-		programmatically while <code>SocketClient2</code> requires a configuration file. 
-	</p>
+    <p>where 6000 is the port number to listen on and
+    <em>server1.xml</em> is a configuration script that adds a
+    <code>ConsoleAppender</code> and a
+    <code>RollingFileAppender</code> to the root logger.  After you
+    have started <code>SimpleSocketServer</code>, you can send it log
+    events from multiple clients using <code>SocketAppender</code>.
+    The examples associated with this manual include two such clients:
+    <code>chapter4.SocketClient1</code> and
+    <code>chapter4.SocketClient2</code> Both clients wait for the user
+    to type a line of text on the console.  The text is encapsulated
+    in a logging event of level debug and then sent to the remote
+    server. The two clients differ in the configuration of the
+    <code>SocketAppender</code>. <code>SocketClient1</code> configures
+    the appender programmatically while <code>SocketClient2</code>
+    requires a configuration file.
+    </p>
 	
-	<p>
-		Assuming <code>SimpleSocketServer</code> is running on the local host, 
-		you connect to it with the following command:
-	</p>
+    <p>Assuming <code>SimpleSocketServer</code> is running on the
+    local host, you connect to it with the following command:
+    </p>
 	
-<div class="source"><pre>java chapter4.socket.SocketClient1 localhost 6000</pre></div>
+    <p class="source">java chapter4.socket.SocketClient1 localhost 6000</p>
 
-		<p>
-			Each line that you type should appear on the console of the
-			<code>SimpleSocketServer</code>
-			launched in the previous step. If you stop and restart the
-			<code>SimpleSocketServer</code>
-			the client will transparently reconnect to the new server
-			instance, although the events generated while disconnected
-			will be simply (and irrevocably) lost.
+		<p>Each line that you type should appear on the console of the
+		<code>SimpleSocketServer</code> launched in the previous step. If
+		you stop and restart the <code>SimpleSocketServer</code> the
+		client will transparently reconnect to the new server instance,
+		although the events generated while disconnected will be simply
+		(and irrevocably) lost.
 		</p>
 
 		<p>
@@ -1348,7 +1440,7 @@
 			and attaches it to the root logger.
 		</p>
 
-		<em>Example 4.7: SocketAppender configuration (logback-examples/src/main/java/chapter4/socket/client1.xml)</em>
+		<em>Example 4.<span class="autoEx"/>: SocketAppender configuration (logback-examples/src/main/java/chapter4/socket/client1.xml)</em>
 <div class="source"><pre>&lt;configuration>
 	  
   &lt;appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
@@ -1369,44 +1461,42 @@
 		<p>
 			Note that in the above configuration scripts the values for the 
 			<span class="option">RemoteHost</span>, <span class="option">Port</span> and
-			<span class="option">IncludeCallerData</span> options
+			<span class="option">IncludeCallerData</span> properties
 			are not given directly but as substituted variable keys. The values for the variables 
 			can be specified as system properties: 
 		</p>
 	
-<div class="source"><pre>java -Dhost=localhost -Dport=6000 -DincludeCallerData=false \
-  chapter4.socket.SocketClient2 src/main/java/chapter4/socket/client1.xml
-</pre></div>
+    <p class="source">java -Dhost=localhost -Dport=6000 -DincludeCallerData=false \
+  chapter4.socket.SocketClient2 src/main/java/chapter4/socket/client1.xml</p>
 
-		<p>
-			This command should give similar results to the previous
+		<p>This command should give similar results to the previous
 			<code>SocketClient1</code>
 			example.
 		</p>
 		
-		<p>
-			Allow us to repeat for emphasis that serialization of logging events is not 
-			intrusive. A de-serialized event carries the same information as any other 
-			logging event. It can be manipulated as if it were generated locally; 
-			except that serialized logging events by default do not include caller 
-			data. Here is an example to illustrate the point. First, start 
-			<code>SimpleSocketServer</code> with the following command:
-		</p>
-
-<div class="source"><pre>  java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
-  src/main/java/chapter4/socket/server2.xml
-</pre></div>
-
-		<p>
-			The configuration file <em>server2.xml</em> creates a <code>ConsoleAppender</code> 
-			whose layout outputs the callers file name and line number along with other 
-			information. If you run <code>SocketClient2</code> with the configuration file 
-			<em>client1.xml</em> as previously, you will notice that the output on the 
-			server side will contain two question marks between parentheses instead of 
-			the file name and the line number of the caller:
+		<p>Allow us to repeat for emphasis that serialization of logging
+		events is not intrusive. A de-serialized event carries the same
+		information as any other logging event. It can be manipulated as
+		if it were generated locally; except that serialized logging
+		events by default do not include caller data. Here is an example
+		to illustrate the point. First, start
+		<code>SimpleSocketServer</code> with the following command:
+		</p>
+
+    <p class="source"> java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
+  src/main/java/chapter4/socket/server2.xml</p>
+
+   <p>The configuration file <em>server2.xml</em> creates a
+   <code>ConsoleAppender</code> whose layout outputs the callers file
+   name and line number along with other information. If you run
+   <code>SocketClient2</code> with the configuration file
+   <em>client1.xml</em> as previously, you will notice that the output
+   on the server side will contain two question marks between
+   parentheses instead of the file name and the line number of the
+   caller:
 		</p>
 
-<div class="source"><pre>2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?] chapter4.socket.SocketClient2 - Hi</pre></div>
+    <p class="source">2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?] chapter4.socket.SocketClient2 - Hi</p>
 
 		<p>
 			The outcome can be easily changed by instructing the <code>SocketAppender</code> 
@@ -1467,12 +1557,12 @@
 		</p>
 		
 		<p>
-			Here are <code>JMSAppenderBase</code>'s options:
+			Here are <code>JMSAppenderBase</code>'s properties:
 		</p>
 		
 	<table class="bodyTable">
 			<tr class="a">
-			<th>Option Name</th>
+			<th>Property Name</th>
 			<th>Type</th>
 			<th>Description</th>
 		</tr>
@@ -1769,13 +1859,13 @@
 		</p>
 		
 		<p>
-			Some options are proper to <code>JMSTopicAppender</code>. They are 
+			Some properties are proper to <code>JMSTopicAppender</code>. They are 
 			listed below.
 		</p>
 		
 		<table class="bodyTable">
 			<tr class="a">
-			<th>Option Name</th>
+			<th>Property Name</th>
 			<th>Type</th>
 			<th>Description</th>
 		</tr>
@@ -1803,7 +1893,7 @@
 			<code>JMSTopicAppender</code> is rather straightforward to configure:
 		</p>
 
-		<em>Example 4.8: JMSTopicAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-JMSTopic.xml)</em>
+		<em>Example 4.<span class="autoEx"/>: JMSTopicAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-JMSTopic.xml)</em>
 <div class="source"><pre>&lt;configuration>
 
   &lt;appender name="Topic"
@@ -1838,13 +1928,13 @@
 		</p>
 		
 		<p>
-			Some options are proper to <code>JMSQueueAppender</code>. They are 
+			Some properties are proper to <code>JMSQueueAppender</code>. They are 
 			listed below.
 		</p>
 		
 		<table class="bodyTable">
 			<tr class="a">
-			<th>Option Name</th>
+			<th>Property Name</th>
 			<th>Type</th>
 			<th>Description</th>
 		</tr>
@@ -1872,7 +1962,7 @@
 			A typical <code>JMSQueueAppender</code> configuration file looks very
 			similar to that of a <code>JMSTopicAppender</code>.
 		</p>
-		<em>Example 4.9: JMSQueueAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-JMSQueue.xml)</em>
+		<em>Example 4.<span class="autoEx"/>: JMSQueueAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-JMSQueue.xml)</em>
 <div class="source"><pre>&lt;configuration>
 
   &lt;appender name="Queue"
@@ -1904,13 +1994,13 @@
 		higher.
 		</p>
 		
-		<p>The various options for <code>SMTPAppender</code> are
+		<p>The various properties for <code>SMTPAppender</code> are
 		summarized in the following table.
 		</p>
 		
 		<table class="bodyTable">
       <tr class="a">
-        <th>Option Name</th>
+        <th>Property Name</th>
         <th>Type</th>
         <th>Description</th>
       </tr>
@@ -2076,7 +2166,7 @@
 		<code>Email</code> application:
 		</p>	
 		
-<em>Example 4.10: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapter4/mail/mail1.xml)</em>		
+<em>Example 4.<span class="autoEx"/>: A sample <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapter4/mail/mail1.xml)</em>		
 <div class="source"><pre>&lt;configuration>
 	  
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2099,7 +2189,7 @@
 		<p>Before trying out <code>chapter4.mail.Email</code> application
 		with the above configuration file, you must set the <span
 		class="option">SMTPHost</span>, <span class="option">To</span> and
-		<span class="option">From</span> options to values appropriate for
+		<span class="option">From</span> properties to values appropriate for
 		your environment. Once you have set the correct values in the
 		configuration file, execute the following command:
 		</p>
@@ -2117,7 +2207,7 @@
 		<p>In the next exampleconfiguration file <em>mail2.xml</em>, the
 		values for the <span class="option">SMTPHost</span>, <span
 		class="option">To</span> and <span class="option">From</span>
-		options are determined by variable substitution. Here is the
+		properties are determined by variable substitution. Here is the
 		relevant part of <em>mail2.xml</em>.
 		</p>		
 
@@ -2192,7 +2282,7 @@
 		triggers an email message.
 		</p>
 
-<em>Example 4.11: A <code>EventEvaluator</code> implementation
+<em>Example 4.<span class="autoEx"/>: A <code>EventEvaluator</code> implementation
 that evaluates to <code>true</code> every 1024th event (<a href="../xref/chapter4/mail/CounterBasedEvaluator.html">logback-examples/src/main/java/chapter4/mail/CounterBasedEvaluator.java</a>)</em>
 <div class="source"><pre>package chapter4.mail;
 
@@ -2243,7 +2333,7 @@
 			as its event evaluator.
 		</p>
 
-<em>Example 4.12: <code>SMTPAppender</code> with custom 
+<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> with custom 
 <code>Evaluator</code> and buffer size (logback-examples/src/main/java/chapter4/mail/mail3.xml)</em>
 
 <div class="source"><pre>&lt;configuration>
@@ -2272,7 +2362,7 @@
     <p>The next example shows you how to configure SMTPAppender for
     gmail with SSL. </p>
     
-<em>Example 4.13: <code>SMTPAppender</code> to GMAIL using SSL (logback-examples/src/main/java/chapter4/mail/gmailSSL.xml)</em>
+<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> to GMAIL using SSL (logback-examples/src/main/java/chapter4/mail/gmailSSL.xml)</em>
 
 <div class="source"><pre>&lt;configuration>
   &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
@@ -2589,7 +2679,7 @@
 			The following configuration file is what one would need.
 		</p>
 		
-<em>Example 4.13: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapter4/db/append-toMySQL-with-driverManager.xml)</em>
+<em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapter4/db/append-toMySQL-with-driverManager.xml)</em>
 <div class="source"><pre>&lt;configuration>
 
   <b>&lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
@@ -2668,7 +2758,7 @@
 			<code>javax.sql.DataSource</code>.
 		</p>
 	
-<em>Example 4.14: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapter4/db/append-with-datasource.xml)</em>	
+<em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration (logback-examples/src/main/java/chapter4/db/append-with-datasource.xml)</em>	
 <div class="source"><pre>&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
@@ -2780,7 +2870,7 @@
 			configuration file, logging events are sent to a MySQL database,
 			without any pooling.
 		</p>
-<em>Example 4.15: <code>DBAppender</code> configuration without pooling (logback-examples/src/main/java/chapter4/db/append-toMySQL-with-datasource.xml)</em>	
+<em>Example 4.<span class="autoEx"/> <code>DBAppender</code> configuration without pooling (logback-examples/src/main/java/chapter4/db/append-toMySQL-with-datasource.xml)</em>	
 <div class="source"><pre>&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
@@ -2816,8 +2906,8 @@
 			in the classpath.
 		</p>
 
-<em>Example 4.16: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapter4/db/append-toMySQL-with-datasource-and-pooling.xml)</em>			
-<div class="source"><pre>&lt;configuration>
+    <em>Example 4.<span class="autoEx"/>: <code>DBAppender</code> configuration with pooling (logback-examples/src/main/java/chapter4/db/append-toMySQL-with-datasource-and-pooling.xml)</em>			
+    <p class="source">&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
     &lt;connectionSource
@@ -2836,7 +2926,7 @@
     &lt;level value="debug" />
     &lt;appender-ref ref="DB" />
   &lt;/root>
-&lt;/configuration></pre></div>
+&lt;/configuration></p>
 
 		<p>
 			With this new configuration, sending 500 logging requests to
@@ -2859,11 +2949,11 @@
 			<a href="../xref/ch/qos/logback/classic/net/SyslogAppender.html"><code>SyslogAppender</code></a>.
 		</p>
 		
-		<p>Here are the options upi can pass to a SyslogAppender.</p>
+		<p>Here are the properties upi can pass to a SyslogAppender.</p>
 
 		<table class="bodyTable">
 			<tr class="a">
-				<th>Option Name</th>
+				<th>Property Name</th>
 				<th>Type</th>
 				<th>Description</th>
 			</tr>
@@ -2955,7 +3045,7 @@
 			Here is a sample configuration using a <code>SyslogAppender</code>.
 		</p>
 		
-<em>Example 4.17: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapter4/conf/logback-syslog.xml)</em>				
+<em>Example 4.<span class="autoEx"/>: <code>SyslogAppender</code> configuration (logback-examples/src/main/java/chapter4/conf/logback-syslog.xml)</em>				
 <div class="source"><pre>&lt;configuration>
 
   &lt;appender name="SYSLOG"
@@ -3000,7 +3090,7 @@
 			if it were generated locally.
 		</p>
 		<p>
-			The options of access' <code>SocketAppender</code> are the same as those available
+			The properties of access' <code>SocketAppender</code> are the same as those available
 			for classic's <code>SocketAppender</code>.
 		</p>
 
@@ -3020,7 +3110,7 @@
 		<p>
 			Here is a sample configuration of a <code>SMTPAppender</code> in the access environnement.
 		</p>
-<em>Example 4.18: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapter4/conf/access/logback-smtp.xml)</em>					
+<em>Example 4.<span class="autoEx"/>: <code>SMTPAppender</code> configuration (logback-examples/src/main/java/chapter4/conf/access/logback-smtp.xml)</em>					
 <div class="source"><pre>&lt;appender name="SMTP"
   class="ch.qos.logback.access.net.SMTPAppender">
   &lt;layout class="ch.qos.logback.access.html.HTMLLayout">
@@ -3158,14 +3248,14 @@
 			</table>
 
 		<p>
-			All options of classic's <code>DBAppender</code> are available
+			All properties of classic's <code>DBAppender</code> are available
 			in access' <code>DBAppender</code>. The latter offers one more option,
 			described below.
 		</p>
 		
 		<table class="bodyTable">
 			<tr class="a">
-				<th>Option Name</th>
+				<th>Property Name</th>
 				<th>Type</th>
 				<th>Description</th>
 			</tr>
@@ -3188,7 +3278,8 @@
 		<p>
 			Here is a sample configuration that uses <code>DBAppender</code>.
 		</p>
-<em>Example 4.19: DBAppender configuration (logback-examples/src/main/java/chapter4/conf/access/logback-DB.xml)</em>		
+
+    <em>Example 4.<span class="autoEx"/>: DBAppender configuration (logback-examples/src/main/java/chapter4/conf/access/logback-DB.xml)</em>		
 <div class="source"><pre>&lt;configuration>
 
   &lt;appender name="DB" class="ch.qos.logback.access.db.DBAppender">
@@ -3221,8 +3312,8 @@
     thus a few more methods are needed.
     </p>
     
-<em>Example 4.20: <code>CountingConsoleAppender</code> (logback-examples/src/main/java/chapter4/CountingConsoleAppender.java)</em>					    
-<div class="source"><pre>package chapter4;
+    <em>Example 4.<span class="autoExec"/>: <code>CountingConsoleAppender</code> (logback-examples/src/main/java/chapter4/CountingConsoleAppender.java)</em>					    
+    <p class="source">package chapter4;
 
 import ch.qos.logback.core.AppenderBase;
 import ch.qos.logback.core.Layout;
@@ -3276,36 +3367,33 @@
   public void setLayout(Layout&lt;LoggingEvent> layout) {
     this.layout = layout;
   }
-}</pre></div>
+}</p>
 
-		<p>
-			The <code>start()</code> method checks for the presence of a <code>Layout</code>.
-			In case none is found, the appender is not started.
+		<p>The <code>start()</code> method checks for the presence of a
+		<code>Layout</code>.  In case none is found, the appender is not
+		started.
 		</p>
 		
-		<p>
-			This custom appender illustrates a two points:
+		<p>This custom appender illustrates a two points:
 		</p>
 		
 		<ul>
-			<li>
-				All options that follow the setter/getter JavaBeans conventions 
-				are handled transparently. The <code>start()</code> method, that is 
-				called automatically, has the responsability to check that the given
-				options are coherent.
+			<li>All properties that follow the setter/getter JavaBeans
+			conventions are handled transparently. The <code>start()</code>
+			method, that is called automatically, has the responsability to
+			check that the given properties are coherent.
 			</li>
-			<li>
-				The <code>AppenderBase.doAppend()</code> method invokes the append() 
-				method of its derived classes where actual output operations occur. 
-				It is in this method that appenders format events by invoking their layouts.
+			<li>The <code>AppenderBase.doAppend()</code> method invokes the
+			append() method of its derived classes where actual output
+			operations occur.  It is in this method that appenders format
+			events by invoking their layouts.
 			</li>
 		</ul>
 		
-		<p>
-			The <code>CountingConsoleAppender</code> can be configured like
-			any appender.  See sample file
-			<em>logback-examples/src/main/java/chapter4/countingConsole.xml</em>
-			for an example.
+		<p>The <code>CountingConsoleAppender</code> can be configured like
+		any appender.  See sample file
+		<em>logback-examples/src/main/java/chapter4/countingConsole.xml</em>
+		for an example.
 		</p>
   
 

Modified: logback/trunk/logback-site/src/site/pages/manual/joran.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/joran.html	(original)
+++ logback/trunk/logback-site/src/site/pages/manual/joran.html	Mon Nov 17 15:45:23 2008
@@ -12,11 +12,9 @@
   </head>
   <body>
     <script type="text/javascript">prefix='../'</script>
-    <script src="../templates/header.js" type="text/javascript">
-    </script>
+    <script src="../templates/header.js" type="text/javascript"></script>
     <div id="left">
-      <script src="../templates/left.js" type="text/javascript">
-      </script>
+      <script src="../templates/left.js" type="text/javascript"></script>
     </div>
     <div id="right">
       <script src="menu.js" type="text/javascript"></script>
@@ -35,8 +33,7 @@
     </div>
 
 
-    <script src="../templates/creative.js" type="text/javascript">
-    </script>
+    <script src="../templates/creative.js" type="text/javascript"></script>
 
 
     <p>Joran stands for a cold north-west wind which, every now and
@@ -126,7 +123,7 @@
     <code>BasicConfigurator</code> usage <a
     href="../xref/chapter3/MyApp1.html">(logback-examples/src/main/java/chapter3/MyApp1.java)</a></em>
 
-<div class="source"><pre>package chapter3;
+    <p class="source">package chapter3;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -141,7 +138,7 @@
     foo.doIt();
     logger.info("Exiting application.");
   }
-}</pre></div>
+}</p>
 
   <p>This class defines a static logger variable. It then
   instantiates a Foo object. The Foo class is listed below:
@@ -151,7 +148,7 @@
   <a href="../xref/chapter3/Foo.html">(logback-examples/src/main/java/chapter3/Foo.java)</a>
   </em>
 
-<div class="source"><pre>package chapter3;
+  <p class="source">package chapter3;
   
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -162,7 +159,7 @@
   public void doIt() {
     logger.debug("Did it again!");
   }
-}</pre></div>
+}</p>
 
 
     <p>In order to run the examples in this chapter, you need to make

Modified: logback/trunk/logback-site/src/site/pages/manual/layouts.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/layouts.html	(original)
+++ logback/trunk/logback-site/src/site/pages/manual/layouts.html	Mon Nov 17 15:45:23 2008
@@ -380,7 +380,7 @@
 		listed on the left column, they should be considered as aliases.
 		</p>
 
-		<table class="bodyTable" border="0">
+		<table class="bodyTable properties" border="0">
       <tr>
         <th>Conversion Word</th>
         <th>Effect</th>
@@ -967,7 +967,7 @@
 				<td align="center">20</td>
 				<td align="center">none</td>
 				<td>
-					Left pad with spaces if the category name is less
+					Left pad with spaces if the logger name is less
 					than 20 characters long.
 				</td>
 			</tr>

Modified: logback/trunk/logback-site/src/site/pages/news.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/news.html	(original)
+++ logback/trunk/logback-site/src/site/pages/news.html	Mon Nov 17 15:45:23 2008
@@ -38,6 +38,15 @@
     files at initialization if their timestamp warrants it.
     </p>
 
+    <p>Added support for file appending in <a
+    href="manual/appenders.html#prudent">prudent mode</a>. Thus,
+    multiple <code>FileAppender</code> instances running on multiple
+    JVMs can safely write to the same log file. With certain
+    limitations, prudent mode extends to
+    <code>RollingFileAppender</code>.
+    </p>
+
+
     <p>Fixed <a
     href="http://jira.qos.ch/browse/LBCLASSIC-83">LBCLASSIC-83</a>.
     It is now possible to set the level of a logger to null, even if


More information about the logback-dev mailing list