[logback-dev] svn commit: r858 - in logback/trunk: logback-examples logback-examples/src/main/java/chapter4 logback-site/src/site/xdocTemplates/manual logback-skin/src/main/resources/css

noreply.seb at qos.ch noreply.seb at qos.ch
Thu Nov 2 20:36:44 CET 2006


Author: seb
Date: Thu Nov  2 20:36:44 2006
New Revision: 858

Added:
   logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
   logback/trunk/logback-examples/src/main/java/chapter4/IO.java
   logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
Modified:
   logback/trunk/logback-examples/   (props changed)
   logback/trunk/logback-examples/pom.xml
   logback/trunk/logback-skin/src/main/resources/css/site.css

Log:
on going work, documenting appenders (chapter4)
modified css to display appender options

Modified: logback/trunk/logback-examples/pom.xml
==============================================================================
--- logback/trunk/logback-examples/pom.xml	(original)
+++ logback/trunk/logback-examples/pom.xml	Thu Nov  2 20:36:44 2006
@@ -31,18 +31,28 @@
 	</licenses>
 
 	<dependencies>
+	
 		<dependency>
 			<groupId>ch.qos.logback</groupId>
 			<artifactId>logback-core</artifactId>
 		</dependency>
+
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-core</artifactId>
+			<classifier>tests</classifier>
+		</dependency>
+			
 		<dependency>
 			<groupId>ch.qos.logback</groupId>
 			<artifactId>logback-classic</artifactId>
 		</dependency>
+		
 		<dependency>
 			<groupId>ch.qos.logback</groupId>
 			<artifactId>logback-access</artifactId>
 		</dependency>
+		
 	</dependencies>
 
 	<build>

Added: logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/ExitWoes.java	Thu Nov  2 20:36:44 2006
@@ -0,0 +1,41 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+package chapter4;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.WriterAppender;
+import ch.qos.logback.core.layout.EchoLayout;
+
+
+
+public class ExitWoes {
+
+  public static void main(String[] args) throws Exception {
+    LoggerContext lc = new LoggerContext();
+    WriterAppender writerAppender = new WriterAppender();
+    writerAppender.setContext(lc);
+    writerAppender.setLayout(new EchoLayout());
+
+    OutputStream os = new FileOutputStream("exitWoes1.log");
+    writerAppender.setWriter(new OutputStreamWriter(os));
+    writerAppender.setImmediateFlush(false);
+    writerAppender.start();
+
+    Logger logger = lc.getLogger(ExitWoes.class);
+
+    logger.debug("Hello world.");
+  }
+}

Added: logback/trunk/logback-examples/src/main/java/chapter4/IO.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-examples/src/main/java/chapter4/IO.java	Thu Nov  2 20:36:44 2006
@@ -0,0 +1,176 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * 
+ * Copyright (C) 1999-2006, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
+
+package chapter4;
+
+import org.slf4j.Logger;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.core.FileAppender;
+import ch.qos.logback.core.layout.EchoLayout;
+
+
+
+public class IO extends Thread {
+  static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
+  static String msgShort = "Hello";
+  static boolean scarceCPU;
+  static int numThreads;
+  static long l;
+  static boolean longMessage;
+  long len;
+  boolean buffered;
+  boolean immediateFlush;
+  Logger logger;
+  LoggerContext context;
+  double throughput;
+
+  public IO(boolean _buffered, boolean _immediateFlush, long _len) {
+    this.len = _len;
+    this.buffered = _buffered;
+    this.immediateFlush = _immediateFlush;
+    context = new LoggerContext();
+    logger = context.getLogger("logger-" + getName());
+
+    // A FileAppender is created according to the buffering and
+    // immediate flush setting of this IO instance.
+    FileAppender fa = new FileAppender();
+
+    if (longMessage) {
+      PatternLayout pa = new PatternLayout();
+      pa.setPattern("%r %5p %c [%t] - %m%n");
+      fa.setLayout(pa);
+    } else {
+      fa.setLayout(new EchoLayout());
+    }
+
+    fa.setFile(getName() + ".log");
+    fa.setAppend(false);
+    fa.setImmediateFlush(immediateFlush);
+    fa.setBufferedIO(buffered);
+    fa.setContext(context);
+    fa.start();
+    
+  }
+
+  public static void main(String[] argv) throws Exception {
+    if (argv.length != 4) {
+      usage("Wrong number of arguments.");
+    }
+
+    l = Integer.parseInt(argv[0]);
+    numThreads = Integer.parseInt(argv[1]);
+    scarceCPU = "true".equalsIgnoreCase(argv[2]);
+    longMessage = "long".equalsIgnoreCase(argv[3]);
+
+    // ----------------------------------------------------
+    // first test with unbuffered IO and immediate flushing
+    perfCase(false, true, l);
+
+    // ----------------------------------------------------
+    // Second test with unbuffered IO and no immediate flushing
+    perfCase(false, false, l);
+
+    // ----------------------------------------------------
+    // Third test with buffered IO and no immediate flushing
+    perfCase(true, false, l);
+
+    // There is no fourth test as buffered IO and immediate flushing
+    // do not make sense.
+  }
+
+  static void usage(String msg) {
+    System.err.println(msg);
+    System.err.println("Usage: java " + IO.class.getName() +
+      " runLength numThreads scarceCPU (short|long)\n" +
+      "   runLength (integer) the number of logs to generate perthread\n" +
+      "   numThreads (integer) the number of threads.\n" +
+      "   scarceCPU (boolean) if true an additional CPU intensive thread is created\n" +
+      "   (short|long) length of log messages.");
+    System.exit(1);
+  }
+
+  static void perfCase(boolean buffered, boolean immediateFlush, long len)
+    throws Exception {
+    IO[] threads = new IO[numThreads];
+    Counter counterThread = null;
+
+    if (scarceCPU) {
+      counterThread = new Counter();
+      counterThread.start();
+    }
+
+    // First create the threads 
+    for (int i = 0; i < numThreads; i++) {
+      threads[i] = new IO(buffered, immediateFlush, len);
+    }
+
+    // then start them
+    for (int i = 0; i < numThreads; i++) {
+      threads[i].start();
+    }
+
+    // wait for them to stop, compute the average throughputs
+    double sum = 0;
+
+    for (int i = 0; i < numThreads; i++) {
+      threads[i].join();
+      sum += threads[i].throughput;
+    }
+
+    if (scarceCPU) {
+      // setting the interrupted field will cause counterThread to stop
+      counterThread.interrupted = true;
+      counterThread.join();
+    }
+
+    System.out.println("On average throughput of " + (sum / numThreads) +
+      " logs per millisecond.");
+    System.out.println("------------------------------------------------");
+  }
+
+  public void run() {
+    String msg = msgShort;
+
+    if (longMessage) {
+      msg = msgLong;
+    }
+
+    long before = System.currentTimeMillis();
+
+    for (int i = 0; i < len; i++) {
+      logger.debug(msg);
+    }
+
+    throughput = (len * 1.0) / (System.currentTimeMillis() - before);
+    System.out.println(getName() + ", buffered: " + buffered +
+      ", immediateFlush: " + immediateFlush + ", throughput: " + throughput +
+      " logs per millisecond.");
+  }
+}
+
+
+class Counter extends Thread {
+  public boolean interrupted = false;
+  public double counter = 0;
+
+  public void run() {
+    long before = System.currentTimeMillis();
+
+    while (!interrupted) {
+      counter += 0.001;
+    }
+
+    double tput = (counter * 1.0) / (System.currentTimeMillis() - before);
+    System.out.println("Counter thread " + getName() +
+      " incremented counter by " + tput + " per millisecond.");
+  }
+}

Added: logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml
==============================================================================
--- (empty file)
+++ logback/trunk/logback-site/src/site/xdocTemplates/manual/appenders.xml	Thu Nov  2 20:36:44 2006
@@ -0,0 +1,471 @@
+<document>
+	<!-- 
+		
+		Warning: do not use any auto-format function on this file.
+		Since "source" divs use pre as white-space, it affects the
+		look of the code parts in this document.
+		
+	-->
+
+
+	<body>
+		<h2>Chapter 4: Appenders</h2>
+		<div class="author">
+			Authors: Ceki G&#252;lc&#252;, S&#233;bastien Pennec
+		</div>
+
+
+		<table>
+			<tr>
+				<td valign="top" align="top">
+						<a rel="license"
+							href="http://creativecommons.org/licenses/by-nc-sa/2.5/">
+							<img alt="Creative Commons License"
+								style="border-width: 0"
+								src="http://creativecommons.org/images/public/somerights20.png" />
+						</a>
+				</td>
+				<td>
+					<p>Copyright &#169; 2000-2006, QOS.ch</p>
+
+					<p>
+						<!--Creative Commons License-->
+						This work is licensed under a
+						<a rel="license"
+							href="http://creativecommons.org/licenses/by-nc-sa/2.5/">
+							Creative Commons
+							Attribution-NonCommercial-ShareAlike 2.5
+							License
+						</a>
+						.
+						<!--/Creative Commons License-->
+					</p>
+				</td>
+			</tr>
+		</table>
+
+		<h2>What is an Appender</h2>
+
+		<p>
+			Logback delegates the task of writing a logging event to appenders. 
+			Appenders must imple-ment the <code>ch.qos.logback.core.Appender</code> interface. 
+			The salient methods of this interface are summarized below:
+		</p>
+		<div class="source"><pre>package ch.qos.logback.core;
+  
+import ch.qos.logback.core.spi.ContextAware;
+import ch.qos.logback.core.spi.FilterAttachable;
+import ch.qos.logback.core.spi.LifeCycle;
+  
+
+public interface Appender extends LifeCycle, ContextAware, FilterAttachable {
+
+  public String getName();
+  <b>void doAppend(Object event);</b>
+  public void setLayout(Layout layout);
+  public Layout getLayout();
+  public void setName(String name);
+  
+}</pre></div>
+
+	<p>
+		Most of the methods in the Appender interface are made of setter 
+		and getter methods. A notable exception is the <code>doAppend()</code> 
+		method taking an Object instance as its only parameter. 
+		This method is perhaps the most important in the logback framework. 
+		It is responsible for outputting the logging events in a suitable format 
+		to the appropriate output device. Appenders are named entities. 
+		This ensures that they can be referenced by name, a quality confirmed 
+		to be especially significant in configuration scripts. 
+		An appender can contain multiple filters, thus the <code>Appender</code>
+		interface extending the <code>FilterAttachable</code> interface.
+		Filters are discussed in detail in a subsequent chapter.
+	</p>
+	
+	<p>
+		Appenders are ultimately responsible for outputting logging events. 
+		However, they may delegate the actual formatting of the event to a 
+		<code>Layout</code> object. 
+		Each layout is associated with one and only one appender, referred to 
+		as the containing appender. Some appenders have a built-in or fixed 
+		event format, such that they do not require a layout. For example, the 
+		<code>SocketAppender</code> simply serialize logging events before 
+		transmitting them over the wire.
+	</p>
+	
+	<h2>AppenderBase</h2>
+	
+	<p>
+		The <code>ch.qos.logback.core.AppenderSkeleton</code> class is an abstract 
+		class implementing the <code>Appender</code> interface. 
+		It provides basic functionality shared by all appenders, 
+		such as methods for getting or setting their name, their started status, 
+		their layout and their filters. 
+		It is the super-class of all appenders shipped with logback. 
+		Although an abstract class, AppenderBase actually implements the 
+		<code>doAppend()</code> method in the <code>Append</code> interface. 
+		Perhaps the clearest way to discuss AppenderBase class is by 
+		presenting a bit of its actual source code.
+		<code>AppenderBase</code>'s complete source code is also 
+		<a href="../xref/ch/qos/logback/core/AppenderBase.html">
+		available for viewing</a>.  
+	</p>
+	
+<div class="source"><pre>public synchronized void doAppend(Object eventObject) {
+
+  // prevent re-entry.
+  if (guard) {
+    return;
+  }
+
+  try {
+    guard = true;
+
+    if (!this.started) {
+      if (statusRepeatCount++ &lt; ALLOWED_REPEATS) {
+        addStatus(new WarnStatus(
+            "Attempted to append to non started appender [" + name + "].",this));
+      }
+      return;
+    }
+
+    if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
+      return;
+    }
+    
+    // ok, we now invoke derived class' implementation of append
+    this.append(eventObject);
+
+  } finally {
+    guard = false;
+  }
+}</pre></div>
+	
+	<p>
+		This implementation of the <code>doAppend()</code> method is synchronized. 
+		It follows that logging to the same appender from different 
+		threads is safe. While a thread, say <em>T</em>, is executing the <code>doAppend()</code> 
+		method, subsequent calls by other threads are queued until <em>T</em> 
+		leaves the <code>doAppend()</code> method, ensuring 
+		<em>T</em>'s exclusive access to the appender. 
+	</p>
+	
+	<p>
+		EXPLAIN GUARD
+	</p>
+	
+	<p>
+		The first statement of the <code>doAppend()</code> method, once the <code>try</code> block
+		is reached is to check whether the <code>started</code> field is true. 
+		If it is not, <code>doAppend()</code> will send a warning message and return. 
+		In other words, once stopped, it is impossible to write to a closed appender. 
+		<code>Appender</code> object 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 an appender,
+		Joran, logback's configuration framework, calls this method to signal the appender
+		to bind or activate its options.
+		Indeed, depending on the appender, certain options cannot be activated because 
+		of interferences with other options, or appenders can even not start at all if
+		some options are missing. 
+		For example, since 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 for certain.
+		Sub-classes of <code>AppenderBase</code> are required to set the boolean variable 
+		<code>started</code> to false when their <code>stop()</code> method is invoked.
+	</p>
+	
+	<p>
+		If a warning message is sent due to incorrect calls to the <code>doAppend()</code>
+		method, logback's powerful <code>Status</code> error reporting system is used. In case
+		several incorrect calls on <code>doAppend()</code> are issued, <code>AppenderBase</code>
+		does not send an unlimited number of warnings. Once a certain limit is reached, the
+		<code>AppenderBase</code> instance stops its warnings.
+	</p>
+	
+	<p>
+		The next <code>if</code> statement checks the result
+		of the attached <code>Filter</code> objects. 
+		Depending on the decision made by the filters 
+		in the filter chain, events can be denied or alternatively accepted. 
+		In the absence of a decision by the filter chain, events are accepted by default.
+	</p>
+	
+	<p>
+		Lastly, the <code>doAppend()</code> method invoke the derived classes' implementation
+		of the <code>append()</code> method, which does the actual work of appending the
+		event to the appropriate device.
+	</p>
+	
+	<p>DO WE ADD A UML DIAGRAM?? YES!!</p>
+	
+	<p>In appenders, the term option or property is reserved for named attributes 
+	that are dynamically inferred using JavaBeans introspection. </p>
+	
+	<h2>Logback Core</h2>
+	
+	<h3>WriterAppender</h3>
+	
+	<p>
+		<code>WriterAppender</code> appends events to a <code>java.io.Writer</code>. 
+		This class provides basic services that other appenders build upon. 
+		Users do not usually instantiate <code>WriterAppender</code> objects directly. 
+		Since <code>java.io.Writer</code> type cannot be mapped to a string, there is no 
+		way to specify the target <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.
+	</p>
+	
+	<table>
+		<tr>
+			<th>Option Name</th>
+			<th>Type</th>
+			<th>Description</th>
+		</tr>
+		<tr>
+			<td><b><span class="option">Encoding</span></b></td>
+			<td><code>String</code></td>
+			<td>
+				The encoding specifies the method of conversion between 16-bit Unicode 
+				characters into raw 8-bit bytes. This appender will use the local platform's 
+				default encoding unless you specify otherwise using the 
+				<span class="option">Encoding</span> option. 
+				According to the <code>java.lang</code> package documentation, acceptable values 
+				are dependent on the VM implementation although all implementations are 
+				required to support at least the following encodings: 
+				<em>US-ASCII</em>, <em>ISO-8859-1</em>, <em>UTF-8</em>, <em>UTF-16BE</em>,
+				<em>UTF-16LE</em> and <em>UTF-16</em>. 
+				By default, the <span class="option">Encoding</span> option is null such 
+				that the platform's default encoding is used.
+			</td>
+		</tr>
+		<tr>
+			<td><b><span class="option">ImmediateFlush</span></b></td>
+			<td><code>boolean</code></td>
+			<td>
+				If set to true, each write of a logging event is followed by a flush operation 
+				on the underlying <code>Writer</code> object. Conversely, if the option is set to false, 
+				each write will not be followed by a flush. 
+				In general, skipping the flush operation improves logging throughput by roughly 15%. 
+				The downside is that if the application exits abruptly, the unwritten characters 
+				buffered inside the <code>Writer</code> might be lost. 
+				This can be particularly troublesome as those unwritten characters may contain 
+				crucial information needed in identifying the reasons behind a crash. 
+				By default, the <span class="option">ImmediateFlush</span> option is set to true.
+			</td>
+		</tr>
+	</table>
+	
+	<p>
+		In general, if you disable immediate flushing, then make sure to flush 
+		any output streams when your application exits. Otherwise, log messages 
+		will be lost as illustrated by the next example. 
+	</p>
+	
+	<em>Example 4.1: Exiting an application without flushing (logback-examples/src/main/java/chapter4/
+	<a href="../xref/chapter4/ExitWoes.html">ExitWoes.java</a>)</em>
+<div class="source"><pre>package chapter4;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.WriterAppender;
+import ch.qos.logback.core.layout.DummyLayout;
+
+public class ExitWoes {
+
+  public static void main(String[] args) throws Exception {
+    LoggerContext lc = new LoggerContext();
+    WriterAppender writerAppender = new WriterAppender();
+    writerAppender.setContext(lc);
+    writerAppender.setLayout(new DummyLayout());
+
+    OutputStream os = new FileOutputStream("exitWoes1.log");
+    writerAppender.setWriter(new OutputStreamWriter(os));
+    writerAppender.setImmediateFlush(false);
+    writerAppender.start();
+
+    Logger logger = LoggerFactory.getLogger(ExitWoes1.class);
+
+    logger.debug("Hello world.");
+  }
+}</pre></div>
+
+	<p>
+		This example creates a <code>WriterAppender</code> that uses an 
+		<code>OutputStreamWriter</code> 
+		wrapping a <code>FileOutputStream</code> as its underlying <code>Writer</code> object, 
+		with immediate flushing disabled. It then proceeds to log a single debug message. 
+		According to <code>OutputStreamWriter</code> javadocs, each invocation of a 
+		<code>write()</code>
+		method causes the encoding converter to be invoked on the given character(s). 
+		The resulting bytes are accumulated in a buffer before being written 
+		to the underlying output stream. As astonishing as this may seem, 
+		running <code>ExitWoes1</code> will not produce any output in the file 
+		<em>exitWoes1.log</em>
+		because the Java VM does not flush output streams when it exits. 
+		Calling the <code>shutdown()</code> method of a <b>XXXXXX</b> ensures that all 
+		appenders in the hierarchy are closed and their buffers are flushed. 
+		For most applications this is as simple as including the following statement 
+		before exiting the application.
+	</p>
+	<p>WHAT TO DO IN LB ???</p>
+
+	<p>
+		The <code>WriterAppender</code> is the super class of four other appenders, 
+		namely <code>ConsoleAppender</code>, <code>FileAppender</code> which in turn is 
+		the super class of <code>RollingFileAppender</code>. 
+	</p>
+	<p><b>include UML??</b>
+		Figure 4 2 illustrates the class diagram for WriterAppender and its subclasses
+	</p>
+	
+	<h3>ConsoleAppender</h3>
+	
+	<p>
+		The <code>ConsoleAppender</code>, 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. 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>
+			<tr>
+			<th>Option Name</th>
+			<th>Type</th>
+			<th>Description</th>
+		</tr>
+		<tr>
+			<td><b><span class="option">Encoding</span></b></td>
+			<td><code>String</code></td>
+			<td>See <code>WriterAppender</code> options.</td>
+		</tr>
+		<tr>
+			<td><b><span class="option">ImmediateFlush</span></b></td>
+			<td><code>boolean</code></td>
+			<td>See <code>WriterAppender</code> options.</td>
+		</tr>
+		<tr>
+			<td><b><span class="option">Target</span></b></td>
+			<td><code>String</code></td>
+			<td>
+				One of the String values <em>System.out</em> or 
+				<em>System.err</em>. The default target is <em>System.out</em>.
+			</td>
+		</tr>
+	</table>
+	
+	<h3>FileAppendery</h3>
+	
+	<p>
+		The <code>FileAppender</code>, a subclass of <code>WriterAppender</code>, 
+		appends log events into a file. The file to write to is 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. 
+		It 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>
+			<tr>
+			<th>Option Name</th>
+			<th>Type</th>
+			<th>Description</th>
+		</tr>
+		<tr>
+			<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> options.</td>
+		</tr>
+		<tr>
+			<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>
+			<td><b><span class="option">File</span></b></td>
+			<td><code>int</code></td>
+			<td>
+				The name of the file to write to. If the file does not exist, it is created. <br />
+				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.
+			</td>
+		</tr>
+	</table>
+	
+	<p>
+		By default, <code>FileAppender</code> performs a flush operation for 
+		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 the file <em>logback-examples/src/main/java/chapter4/IO.java</em> 
+		for actual source code. 
+		<a href="../xref/chapter4/IO.html">Online viewing</a> 
+		of this file is also available. 
+	</p>
+	
+	<h2>Logback Classic</h2>
+	
+	<h2>Logback Access</h2>
+	
+	
+	
+	
+	
+	
+	
+	
+
+	</body>
+</document>

Modified: logback/trunk/logback-skin/src/main/resources/css/site.css
==============================================================================
--- logback/trunk/logback-skin/src/main/resources/css/site.css	(original)
+++ logback/trunk/logback-skin/src/main/resources/css/site.css	Thu Nov  2 20:36:44 2006
@@ -360,4 +360,9 @@
 .greenBold {
 	color: green;	
   font-weight: bold;	
+}
+
+.option {
+  border: 1px solid black;
+  font-family: Arial, sans-serif;	
 }
\ No newline at end of file



More information about the logback-dev mailing list