<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 implement the 
			<a href="../xref/ch/qos/logback/core/Appender.html"><code>ch.qos.logback.core.Appender</code></a> 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>
	
	<a name="AppenderBase"/>
	<h2>AppenderBase</h2>
	
	<p>
		The <a href="../xref/ch/qos/logback/core/AppenderBase.html">
		<code>ch.qos.logback.core.AppenderBase</code></a> 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, <code>AppenderBase</code> actually implements the 
		<code>doAppend()</code> method in the <code>Append</code> interface. 
		Perhaps the clearest way to discuss <code>AppenderBase</code> class is by 
		presenting a bit of its actual source code.
	</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>
		The first thing the <code>doAppend()</code> method does is to set the 
		<code>guard</code> variable to <code>true</code>. This ensures that the method will not
		call itself and create an infinite loop. Just imagine that a component, called somewhere 
		beyond the <code>append()</code>
		method, wants to log something. Its call could be directed to the very same appender
		that just called it, which would then call it again.
	</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> 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 an appender,
		Joran, logback's configuration framework, calls the <code>start()</code> 
		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.
	</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 resulting from 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>
	
	<!-- ADD UML DIAGRAM -->
	
	<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>
	
	<p>
		Core is logback's central module. It offers functionnalities that are available
		to any other module based on logback core. The <code>Appender</code> classes
		contained in the core module are can be used by any module without any customization.
	</p>
	
	<a name="WriterAppender" />
	<h3>WriterAppender</h3>
	
	<p>
		<a href="../xref/ch/qos/logback/core/WriterAppender.html"><code>WriterAppender</code></a> 
		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 
				<code>null</code> 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 (<a href="../xref/chapter4/ExitWoes1.html">logback-examples/src/main/java/chapter4/ExitWoes1.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.EchoLayout;

public class ExitWoes1 {

  public static void main(String[] args) throws Exception {
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    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 = 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>shutdownAndReset()</code> method of a <code>LoggerContext</code> 
		ensures that all 
		appenders in the hierarchy are closed and their buffers are flushed. The
		<code>ExitWoes2</code> class uses this statement and outputs a logging
		request.
	</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>
	
	<!-- ADD UML DIAGRAM -->
	
	<a name="ConsoleAppender" />
	<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. 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>
	
	<p>
		Here is a sample configuration that uses <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>

  <b>&lt;appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    &lt;layout class="ch.qos.logback.classic.PatternLayout">
      &lt;Pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n&lt;/Pattern>
    &lt;/layout>
  &lt;/appender></b>

  &lt;root>
    &lt;level value="debug" />
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre></div>

	<p>
		To run this example, as well as others in this
		chapter, please run the script provided in the <em>logback-examples</em> directory. 
		Then, use the <code>ConfigurationTester</code> by
		issuing the following command, once in the <em>logback-examples</em> directory:
	</p>
	
<div class="source"><pre>java chapter4.ConfigurationTester src/main/java/chapter4/conf/logback-Console.xml</pre></div>
	
	<a name="FileAppender" />
	<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 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>
		<tr>
			<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 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 <a href="../xref/chapter4/IO.html">
		<em>logback-examples/src/main/java/chapter4/IO.java</em></a>
		for actual source code. 
	</p>
	
	<p>
		Configuring <code>FileAppender</code> can be done the following way:
	</p>

<em>Example 4.3: FileAppender configuration (logback-examples/src/main/java/chapter4/conf/logback-fileAppender.xml)</em>
<div class="source"><pre>&lt;configuration>

  <b>&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender">
    &lt;File>testFile.log&lt;/File>
    &lt;Append>true&lt;/Append>
    &lt;Encoding>UTF-8&lt;/Encoding>
    &lt;BufferedIO>false&lt;/BufferedIO>
    &lt;ImmediateFlush>true&lt;/ImmediateFlush>
		
    &lt;layout class="ch.qos.logback.classic.PatternLayout">
      &lt;Pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n&lt;/Pattern>
    &lt;/layout>
  &lt;/appender></b>
	
  &lt;root>
    &lt;level value="debug" />
    &lt;appender-ref ref="FILE" />
  &lt;/root>
&lt;/configuration></pre></div>

	<p>
		To run this example, use the provided <code>ConfigurationTester</code> by
		issuing the following command, once in the <em>logback-examples/target/classes</em>:
	</p>
	
<div class="source"><pre>java chapter4.ConfigurationTester src/main/java/chapter4/conf/logback-fileAppender.xml</pre></div>
	
	
	<a name="RollingFileAppender" />
	<h3>RollingFileAppender</h3>
	
	<p>
		<a href="../xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>
		extends <code>FileAppender</code> by 
		allowing rolling from a log file to another. For example,
		<code>RollingFileAppender</code> can log to a <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, <code>RollingPolicy</code>
		implementations define the procedure that will be followed when
		the rollover happens. The second componenent is
		<code>TriggeringPolicy</code> implementations that are used
		to check wether the rollover must happen or not at a given time.
	</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>
			<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>See <code>FileAppender</code> options.</td>
		</tr>	
		<tr>
			<td><b><span class="option">BufferedIO</span></b></td>
			<td><code>boolean</code></td>
			<td>See <code>FileAppender</code> options.</td>
		</tr>		
		<tr>
			<td><b><span class="option">BufferSize</span></b></td>
			<td><code>int</code></td>
			<td>See <code>FileAppender</code> options.</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">File</span></b></td>
			<td><code>String</code></td>
			<td>See <code>FileAppender</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">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>
			<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> 
	implementations are responsible for the
	rollover procedure. They manage 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;

import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.spi.LifeCycle;

public interface RollingPolicy extends LifeCycle {

  <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 in the <code>RollingPolicy</code>.
		Lastly, a <code>RollingPolicy</code> knows about its parent.
	</p>
	
	<a name="FixedWindowRollingPolicy" />
	<h4>FixedWindowRollingPolicy</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">File</span> option, which is configured in the 
		<code>FileAppender</code> element, is required. It represents the name of the file
		to write to. The <span class="option">FileNamePattern</span>
		option represents the file name pattern for the archived (rolled over) log files. 
		The <span class="option">FileNamePattern</span> option, which is also required, must include 
		an integer token, that is the string <em>%i</em>
		somewhere within the pattern.
	</p>
	
	<p>
		Here are the available options for <code>FixedWindowRollingPolicy</code>
	</p>
	
	<table>
			<tr>
			<th>Option Name</th>
			<th>Type</th>
			<th>Description</th>
		</tr>
		<tr>
			<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 to insert the file's index.
				</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 
					files named <em>MyLogFile1.log</em>, <em>MyLogFile2.log</em> and
					<em>MyLogFile3.log</em>.
				</p>
				<p>
					File compression is also specified in the 
					<span class="option">FileNamePattern</span> option. 
					<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. The <em>gz</em>
					format is also supported.
				</p>
			</td>
		</tr>	
		<tr>
			<td><b><span class="option">MaxIndex</span></b></td>
			<td><code>int</code></td>
			<td>
				<p>
					This option represents the maximum border of the window algorithm.
				</p>
			</td>
		</tr>
		<tr>
			<td><b><span class="option">MinIndex</span></b></td>
			<td><code>int</code></td>
			<td>
				<p>
					This option represents the minimum border of the window algorithm.
				</p>
			</td>
		</tr>
	</table>

	<p>
		Given that this rollover algorithm requires as many file
		renaming operations as the window size, large window sizes are
		discouraged. The current implementation will automatically
		reduce the window size to 12 when larger values are specified by
		the user.
	</p>

	<p>
		Here is an example of file handling by <code>FixedWindowRollingPolicy</code>.
		We suppose that the <span class="option">MinIndex</span> is set to <em>1</em> and
		<span class="option">MaxIndex</span> is set to <em>3</em>. The
		<span class="option">FileNamePattern</span> option is set to <em>foo%i.log</em>, and
		the <span class="option">FileNamePattern</span> 
		option is set to <em>foo.log</em>.
	</p>
	
	<table>
		<tr>
			<th>
				Steps
			</th>
			<th>
				Active file name
			</th>
			<th>
				Archived file names
			</th>
			<th>Description</th>
		</tr>
		<tr>
			<td>
				0
			</td>
			<td>
				foo.log
			</td>
			<td>
				-
			</td>
			<td>
				No rollover has happened yet, logback logs 
				into the initial file.
			</td>
		</tr>		
		<tr>
			<td>
				1
			</td>
			<td>
				foo.log
			</td>
			<td>
				foo1.log
			</td>
			<td>
				First rollover. <em>foo.log</em> is renamed into <em>foo1.log</em> and
				a new <em>foo.log</em> file is created and used for the output.
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				foo.log
			</td>
			<td>
				foo2.log, foo1.log
			</td>
			<td>
				Second rollover. <em>foo.log</em> is renamed into <em>foo1.log</em> and
				the old <em>foo1.log</em> is renamed into <em>foo2.log</em>.
				Again, a new <em>foo.log</em> file is created and used for the output.
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				foo.log
			</td>
			<td>
				foo3.log, foo2.log, foo1.log
			</td>
			<td>
				Third rollover. <em>foo.log</em> is renamed into <em>foo1.log</em> and
				the old <em>foo1.log</em> is renamed into <em>foo2.log</em>. As well, the
				old <em>foo2.log</em> is renamed into <em>foo3.log</em>.
				A new <em>foo.log</em> file is created and used for the output.
			</td>
		</tr>
		<tr>
			<td>
				4
			</td>
			<td>
				foo.log
			</td>
			<td>
				foo3.log, foo2.log, foo1.log
			</td>
			<td>
				From the fourth rollover, the old <em>foo3.log</em> file is deleted. The files
				are all renamed with an increment to their index, and a new <em>foo.log</em>
				file is created and used for the output.
				From this moment on, there will always be 4 log files available, each being present
				for the time of 3 rollovers and being deleted afterwards.
			</td>
		</tr>
	</table>
	
	<p>
		Here is a sample configuration to use <code>RollingFileAppender</code>
		and <code>FixedWindowRollingPolicy</code>.
	</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>
  &lt;appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    &lt;File>testFile.log&lt;/File>
    <b>&lt;rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      &lt;FileNamePattern>testFile.%i.log.zip&lt;/FileNamePattern>
      &lt;MinIndex>1&lt;/MinIndex>
      &lt;MaxIndex>3&lt;/MaxIndex>
    &lt;/rollingPolicy></b>

    &lt;triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      &lt;MaxFileSize>5MB&lt;/MaxFileSize>
    &lt;/triggeringPolicy>
    &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></pre></div>
	
	<a name="TimeBasedRollingPolicy" />
	<h4>TimeBasedRollingPolicy</h4>
	<p>
		<a href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
		<code>TimeBasedRollingPolicy</code></a> is both easy to configure and quite powerful.
		It allows the rollover to be made based on time conditions. It is possible to specify
		that the rollover must occur each day, or month, for example.
	</p>
	<p>
		<code>TimeBasedRollingPolicy</code>'s only option is the
		<span class="option">FileNamePattern</span>.
	</p>
	
	<p>
		In order to use
		<code>TimeBasedRollingPolicy</code>, the
		<span class="option">FileNamePattern</span> option must be set. It basically 
		specifies the name of the rolled log files. The value
		<span class="option">FileNamePattern</span> 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
		of <em>yyyy-MM-dd</em> is assumed. The following examples should
		clarify the point.
	</p>
	<table>
		<tr>
			<th>
				<span class="option">FileNamePattern</span>
			</th>
			<th>Roll-over schedule</th>
			<th>Example</th>
		</tr>
		<tr>
			<td>
				<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>
			<td>
				<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>
			<td>
				<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>
			<td>
				<em>/wombat/foo.%d{yyyy-MM-dd-a}.log</em>
			</td>
			<td>Rollover at midnight and midday of each day.</td>
			<td>
				During the first 12 hours of November 3rd, 2006, the logging
				will be output to <em>/wombat/foo.2006-11-03-AM.log</em>.
				After noon, and until  midnight, the logging will be output to
				<em>/wombat/foo.2006-11-03-PM.log</em>.
			</td>
		</tr>
		<tr>
			<td>
				<em>/wombat/foo.%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>
			<td>
				<em>/wombat/foo.%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 would 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 compression. 
		This feature is enabled if the value of the <span class="option">FileNamePattern</span> option 
		ends with <em>.gz</em> or <em>.zip</em>.
	</p>
	<table>
	  <tr>
	    <th><span class="option">FileNamePattern</span></th>
	    <th>Rollover schedule</th>
	    <th>Example</th>
	  </tr>
	  <tr>
	    <td><em>/wombat/foo.%d.gz</em></td>
	    <td>Daily rollover (at midnight) with automatic GZIP compression of the 
	     arcived files.</td>
	    <td>During November 23rd, 2004, logging output will go to 
	      the file <em>/wombat/foo.2004-11-23</em>. However, at midnight that
	      file will be compressed to become <em>/wombat/foo.2004-11-23.gz</em>.
	      For the 24th of November, logging output will be directed to 
	      <em>/wombat/folder/foo.2004-11-24</em> until its rolled over at the
	      beginning of the next day.
	    </td>
	  </tr>
	</table>
	
	<p>
		As we have seen, the <span class="option">FileNamePattern</span> serves two purposes. First,
		by studying the pattern, logback computes the requested rollover periodicity. Second,
		it computes each files' name based on the pattern. It is entirely possible for two different
		file name patterns to specify the same periodicity.
		The date patterns <em>yyyy-MM</em> and <em>yyyy@MM</em> both specify monthly 
		rollover periodicity, although the rolled files will carry different names.
	</p>
	
	<p>
		Given the use of the <span class="option">FileNamePattern</span>, we see that the
		<code>TimeBasedRollingPolicy</code> is responsible for the rollover as well as for
		the triggering of said rollover. Therefore, <code>TimeBasedTriggeringPolicy</code>
		implements both <code>RollingPolicy</code> and <code>TriggeringPolicy</code>
		interfaces. A <code>RollingFileAppender</code> that uses
		<code>TimeBasedRollingPolicy</code> can be started and used correctly even
		if its configuration does not contain any reference to a <code>TriggeringPolicy</code>.
	</p>
	
	<p>
		With <code>TimeBasedRollingPolicy</code>, it is possible to
		decouple the location of the active log file and the archived log files
	</p>
	<p>
		The <span class="option">File</span> option defines the log file 
		for the current period whereas <em>archived files</em> are those files 
		which have been rolled over in previous periods.
	</p>
	<p>
		By setting the <span class="option">File</span> option you can 
		decouple the location of the active log file and the location 
		of the archived log files. The actual logging will be done in the
		file specified by the <span class="option">File</span> option. This way,
		the active file name will never change. By not setting the
		<span class="option">File</span> option, logback uses the 
		<span class="option">FileNamePattern</span> to name the active file,
		whose name will change each time a rollover occurs.
	</p>
	
	<p>
		For various efficiency reasons, rollovers are not time-driven 
		but depend on the arrival of logging events. For example, on 8th of March 2002, 
		assuming the <span class="option">FileNamePattern</span> is set to  
		<em>yyyy-MM-dd</em> (daily rollover), the arrival of the first 
		event after midnight will trigger rollover. If there are no logging events 
		during, say 23 minutes and 47 seconds after midnight, 
		then rollover will occur at 00:23'47 AM on March 9th and not at 0:00 AM. 
		Thus, depending on the arrival rate of events, rollovers might be triggered 
		with some latency.  However, regardless of the delay, the rollover algorithm 
		is known to be correct, in the sense that all logging events generated 
		during a certain period will be output in the correct file delimiting that period.
	</p>
	
	<p>Here is a sample configuration of a <code>RollingFileAppender</code> which
	uses a <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>
  &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">
      &lt;FileNamePattern>logFile.%d{yyyy-MM-dd}.log&lt;/FileNamePattern>
    &lt;/rollingPolicy></b>

    &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></pre></div>

		<a name="TriggeringPolicy"/>
		<h3>Triggering policies</h3>
		
		<p><a href="../xref/ch/qos/logback/core/rolling/TriggeringPolicy.html"><code>TriggeringPolicy</code></a>
		implementations are responsible for instructing
		the <code>RollingFileAppender</code> to rollover.</p>
		
		<p>The <code>TriggeringPolicy</code> interface is pretty simple.</p>
	
<div class="source"><pre>package ch.qos.logback.core.rolling;

import java.io.File;
import ch.qos.logback.core.spi.LifeCycle;

public interface TriggeringPolicy extends LifeCycle {

  <b>public boolean isTriggeringEvent(final File activeFile, final Object event);</b>
}</pre></div>

		<p>
			The
			<code>isTriggeringEvent()</code>
			method takes the active file, and the currently processed
			logging event. It's implementation decides, based on these
			parameters, whether the rollover must occur or not, by
			returning a boolean value.
		</p>

		<a name="SizeBasedTriggeringPolicy" />
		<h4>SizeBasedTriggeringPolicy</h4>

		<p>
			<a href="../xref/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.html">
			<code>SizeBasedTriggeringPolicy</code></a>
			looks at size of the file being currently written to. If it
			grows larger than the specified size, the
			<code>FileAppender</code> using the
			<code>SizeBasedTriggeringPolicy</code>
			will proceed to the rollover of the current file and log to
			a new one.
		</p>

		<p>
			This <code>TriggeringPolicy</code>
			only accepts one parameter, that is the
			<span class="option">MaxFileSize</span>
			option. This option's default value is 10 MB.
		</p>

		<p>
			The <span class="option">MaxFileSize</span>
			option can be specified in a simple and easy way, by
			specifying the unit that should be used. One can enter any 
			numeric value, with three possible units, namely <em>KB</em>, 
			<em>MB</em> and <em>GB</em>. Consequently, values like
			<em>5MB</em>, <em>500KB</em> or <em>2GB</em> are all valid.
		</p>
		<p>
			Here is a sample configuration with a <code>RollingFileAppender</code>
			using a <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>
  &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">
      &lt;FileNamePattern>testFile.%i.log.zip&lt;/FileNamePattern>
      &lt;MinIndex>1&lt;/MinIndex>
      &lt;MaxIndex>3&lt;/MaxIndex>
    &lt;/rollingPolicy>

    <b>&lt;triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      &lt;MaxFileSize>5MB&lt;/MaxFileSize>
    &lt;/triggeringPolicy></b>
    &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></pre></div>

		<p>
			<code>TriggeringPolicy</code> implementations do not only serve with
			<code>RollingFileAppender</code> objects. They can also be used to tell
			<code>SMTPAppender</code>, which will be covered soon, when to send an email
			containing the last logging events.
		</p>
		
		<p>
			In that case, the <code>isTriggeringEvent()</code> method takes <em>null</em>
			as its first parameter (of type <code>File</code>) and takes the logging event
			as its second parameter. It is based on that last element that the decision is
			made to send the email or not. By default, a <code>TriggeringPolicy</code> is
			included with <code>SMTPAppender</code> that triggers the mail each time an event
			with a <code>Level</code> of <em>ERROR</em> or more is issued.
		</p>

		<a name="Classic"/>
		<h2>Logback Classic</h2>
		
		
		<p>While logging event are declared as <code>Object</code> in logback core, 
		they are instances of the <code>LoggingEvent</code> class in logback classic.</p>

		<a name="SocketAppender" />
		<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>
		
		<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 any logger, 
			it will not be garbage collected in the presence of a connector thread. 
			A connector thread exists only if the connection to the server is down. 
			To avoid this garbage collection problem, you should close the <code>SocketAppender</code> 
			explicitly. Long lived applications which create/destroy many 
			<code>SocketAppender</code> instances should be aware of this 
			garbage collection problem. Most other applications can safely ignore it. 
			If the JVM hosting the <code>SocketAppender</code> exits before the 
			<code>SocketAppender</code> is closed, either explicitly or subsequent 
			to garbage collection, then there might be untransmitted data in the 
			pipe which may be lost. This is a common problem on Windows based systems.  
			To avoid lost data, it is usually sufficient to <code>close()</code> the 
			<code>SocketAppender</code> either explicitly or by calling the 
			<code>LoggerContext</code>'s <code>shutdownAndReset()</code> method before exiting the application.
		</p>
		
		<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.
		</p>

	<table>
			<tr>
			<th>Option Name</th>
			<th>Type</th>
			<th>Description</th>
		</tr>
		<tr>
			<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>
			<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>
			<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>
			<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>
	
<div class="source"><pre>java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
  src/main/java/chapter4/socket/server1.xml
</pre></div>

	<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>
	
<div class="source"><pre>java chapter4.socket.SocketClient1 localhost 6000</pre></div>

		<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>
			Unlike
			<code>SocketClient1</code>, the sample application
			<code>SocketClient2</code> does not configure logback by itself. 
			It requires a configuration file in XML format. 
			The configuration file <em>client1.xml</em>
			shown below creates a <code>SocketAppender</code>
			and attaches it to the root logger.
		</p>

		<em>Example 4.7: 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">
    &lt;RemoteHost>${host}&lt;/RemoteHost>
    &lt;Port>${port}&lt;/Port>
    &lt;ReconnectionDelay>10000&lt;/ReconnectionDelay>
    &lt;IncludeCallerData>${includeCallerData}&lt;/IncludeCallerData>
  &lt;/appender>

  &lt;root>
    &lt;level value ="debug"/>
    &lt;appender-ref ref="SOCKET" />
  &lt;/root>  

&lt;/configuration></pre></div>
	
	
		<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
			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>
			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>

<div class="source"><pre>2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?] chapter4.socket.SocketClient2 - Hi</pre></div>

		<p>
			The outcome can be easily changed by instructing the <code>SocketAppender</code> 
			to include caller data by setting the <span class="option">IncludeCallerData</span> 
			option to true. Using the following command will do the trick:
		</p>

<div class="source"><pre>java -Dhost=localhost -Dport=6000 -DincludeCallerData=true \
  chapter4.socket.SocketClient2 src/main/java/chapter4/socket/client1.xml
</pre></div>

		<p>
			As deserialized events can be handled in the same way as locally 
			generated events, they even can be sent to a second server for further treatment. 
			As an exercise, you may wish to setup two servers where the first server 
			tunnels the events it receives from its clients to a second server.
		</p>
		
		<a name="SMTPAppender"/>
		<h3>SMTPAppender</h3>
		
		<p>
			The <a href="../xref/ch/qos/logback/classic/net/SMTPAppender.html"><code>SMTPAppender</code></a> 
			accumulates logging events in a fixed-size buffer and sends them in an email when a 
			user specified event occurs.  
		  By default, the email is sent as the reception of an event 
			of level <em>ERROR</em> or higher.
		</p>
		
		<p>
			The various options for <code>SMTPAppender</code> are summarized in the following table.
		</p>
		
		<table>
			<tr>
			<th>Option Name</th>
			<th>Type</th>
			<th>Description</th>
		</tr>
		<tr>
			<td><b><span class="option">SMTPHost</span></b></td>
			<td><code>String</code></td>
			<td>
				The host name of the SMTP server. This parameter is mandatory.
			</td>
		</tr>
		<tr>
			<td><b><span class="option">To</span></b></td>
			<td><code>String</code></td>
			<td>
				The email address of the recipient. Multiple recipients can
				be specified by separating each recipient with a comma.
			</td>
		</tr>
		<tr>
			<td><b><span class="option">From</span></b></td>
			<td><code>String</code></td>
			<td>
				The stated originator of the email messages sent by 
				<code>SMTPAppender</code>.
			</td>
		</tr>
		<tr>
			<td><b><span class="option">Subject</span></b></td>
			<td><code>String</code></td>
			<td>
				<p>
					The subject of the email. The String can contain a <code>Pattern</code>
					that <code>PatternLayout</code> uses. In that case, the subject
					is created just before the transmission of the email, with information
					about the last logging event that was issued.
				</p>
				<p>
					For example, setting <em>Log: %logger - %msg</em> as the
					<span class="option">Subject</span> option will send an email with
					the logger name and message string of the event that triggered the 
					email transmission.
				</p>
				<p>
					By default, <code>SMTPAppender</code> will form a subject with
					logger name and the message of the last logging event.
				</p>
			</td>
		</tr>
		<tr>
			<td><b><span class="option">BufferSize</span></b></td>
			<td><code>String</code></td>
			<td>
				The <span class="option">BufferSize</span> option takes a positive 
				integer representing the maximum number of logging events to collect in a 
				cyclic buffer. When the <span class="option">BufferSize</span> is reached, 
				oldest events are deleted as new events are added to the buffer. 
				The default size of the cyclic buffer is 512.
			</td>
		</tr>
		<tr>
			<td><b><span class="option">Evaluator</span></b></td>
			<td><code>String</code></td>
			<td>
				<p>This option is declared by creating a new <code>&lt;EventEvaluator/></code>
				element. The name of the class that the user wishes to use as the
				<code>SMTPAppender</code>'s <code>Evaluator</code> can be given
				by adding an attribute to the newly created element.
				</p>
				<p>
				More details about the use of event evaluators with <code>SMTPAppender</code>
				follow further down this document.
				</p>
				<p>In the absence of this option, 
				<code>SMTPAppender</code> is assigned a default event evaluator which triggers 
				email transmission as a response to any event of level <em>ERROR</em> or higher.  
				</p>
			</td>
		</tr>
		</table>		
		
		<p>
			The SMTPAppender keeps only the last <span class="option">BufferSize</span> logging events 
			in its cyclic buffer, throwing away older events when its buffer becomes full. 
			The number of logging events  delivered in any e-mail sent by <code>SMTPAppender</code> 
			is upper-bounded by <span class="option">BufferSize</span>. This keeps memory 
			requirements bounded while still delivering a reasonable amount of application context. 
		</p>
		
		<p>
			The <code>SMTPAppender</code> relies on the JavaMail API. 
			It has been tested with JavaMail API version 1.4. 
			The JavaMail API requires the JavaBeans Activation Framework package. 
			You can download the <a href="http://java.sun.com/products/javamail/">JavaMail API</a>  
			and the <a href="http://java.sun.com/beans/glasgow/jaf.html">Java-Beans Activation Framework</a>
			from their respective websites. 
			Make sure to place these two jar files in the classpath before 
			trying the following examples.
		</p>
		
		<p>
			A sample application called <code>chapter4.mail.EMail</code> takes two parameters. 
			The first parameter is an integer corresponding to the number of logging events 
			to generate. The second parameter is the logback configuration file in XML format. 
			The last logging event generated by chapter4.mail.Email application is always an 
			<em>ERROR</em> event which triggers the transmission of an email message.
		</p>

		<p>
			Here is a sample configuration file you can supply to chapter4.mail.Email:
		</p>	
		
<em>Example 4.8: 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">
    &lt;SMTPHost>ADDRESS-OF-YOUR-SMTP-HOST&lt;/SMTPHost>
    &lt;To>DESTINATION-EMAIL&lt;/To>
    &lt;From>SENDER-EMAIL&lt;/From>
    &lt;layout class="ch.qos.logback.classic.PatternLayout">
      &lt;Pattern>%date %-5level %logger{35} - %message%n&lt;/Pattern>
    &lt;/layout>	    
  &lt;/appender>

  &lt;root>
    &lt;level value ="debug"/>
    &lt;appender-ref ref="EMAIL" />
  &lt;/root>  
&lt;/configuration></pre></div>

		<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 your environment. Once you have set the proper values, 
			change directory to <em>logback-examples</em> and execute the following command:
		</p>
		
<div class="source"><pre>java chapter4.mail.EMail 300 src/main/java/chapter4/mail/mail.xml</pre></div>

		<p>
			The chosen recipient should see an email message containing 300 logging events 
			formatted by <code>PatternLayout</code>.
		</p>
		
		<p>
			In another configuration 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 relevant part of <em>mail2.xml</em>.
		</p>		

<div class="source"><pre>
  &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    &lt;SMTPHost>${smtpHost}&lt;/SMTPHost>
    &lt;To>${to}&lt;/To>
    &lt;From>${from}&lt;/From>
    &lt;layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  &lt;/appender>
</pre></div>
		
		<p>
			You can supply the various values on the command line:
		</p>
		
<div class="source"><pre>java -Dfrom=source@xyz.com -Dto=recipient@xyz.com 
  -DsmtpHost=some_smtp_host src/main/java/chapter4.mail.EMail 10000 chapter4/mail/mail2.xml
</pre></div>

		<p>
			Be sure to replace with the correct values appropriate for your environment.
		</p>
		
		<p>
			Given that the default size of the cyclic buffer is 512, 
			the recipient should see an email message containing 512 events conveniently 
			formatted in an HTML table. Note that this run of the <code>chapter4.mail.Email</code> 
			application generated 10'000 events of which only the last 512 were included in the email. 
		</p>
		
		<p>
			By default, the <code>SMTPAppender</code> will initiate the transmission of an email 
			message as a response to an event of level <em>ERROR</em> or higher. 
			However, it is possible to override this default behavior by providing a custom 
			implementation of the <code>EventEvaluator</code> interface. 
		</p>
		
		<p>
			The <code>SMTPAppender</code> submits each incoming event to its evaluator 
			by calling <code>evaluate()</code> method in order to check whether 
			the event should trigger an email or just be placed in the cyclic buffer. 
			When the evaluator gives a positive answer to its evaluation, an email is sent.
			The <code>SMTPAppender</code> contains one and only one evaluator object. 
			This object may possess its own state. For illustrative purposes, 
			the <code>CounterBasedEvaluator</code> class listed next, implements an
			event evaluator whereby every 1024th event triggers an email message.
		</p>

<em>Example 4.9: 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;

import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.spi.ContextAwareBase;

public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator {

  static int LIMIT = 1024;
  int counter = 0;
  String name;

  <b>public boolean evaluate(Object event) throws NullPointerException,
      EvaluationException {
    counter++;

    if (counter == LIMIT) {
      counter = 0;

      return true;
    } else {
      return false;
    }
  }</b>

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}</pre></div>

		<p>
			Note that this implementation extends <code>ContextAwareBase</code> and
			implements <code>EventEvaluator</code>. This allows the user to concentrate
			on the core functions of her <code>EventEvaluator</code> and let the base class
			provide the common functionnality.
		</p>

		<p>
			Setting the <span class="option">EventEvaluator</span> option of 
			<code>SMTPAppender</code> instructs it to use a custom evaluator. 
			The next configuration file attaches a <code>SMTPAppender</code> to the root logger. 
			This appender has a buffer size of 2048 and uses a <code>CounterBasedEvaluator</code> instance 
			as its event evaluator.
		</p>

<em>Example 4.10: <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>
  &lt;appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <b>&lt;Evaluator class="chapter4.mail.CounterBasedEvaluator" /></b>
    &lt;BufferSize>1050&lt;/BufferSize>
    &lt;SMTPHost>${smtpHost}&lt;/SMTPHost>
    &lt;To>${to}&lt;/To>
    &lt;From>${from}&lt;/From>
    &lt;layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  &lt;/appender>

  &lt;root>
    &lt;level value ="debug"/>
    &lt;appender-ref ref="EMAIL" />
  &lt;/root>  
&lt;/configuration></pre></div>



		<a name="DBAppender"/>
		<h3>DBAppender</h3>
		
		<p>
			The <a href="../xref/ch/qos/logback/classic/db/DBAppender.html"><code>DBAppender</code></a> 
			inserts loggin events into three database tables in a format
			independent of the Java programming language. 
		</p>
		<p>
			These three tables are <em>logging_event</em>, <em>logging_event_property</em> and
			<em>logging_event_exception</em>. They all must exist before <code>DBAppender</code>
			can be used. Logback ships with SQL scripts that will create the tables. 
			They can be found in the found in the 
			<em>logback-classic/src/main/java/ch/qos/logback/classic/db/dialect</em> directory. There
			is a specific script for each of the most popular database systems. 
			If the script for your particular type of database system is missing, it should be
			quite easy to write one, taking example on the already existing scripts. If
			you send them to us, we will gladly include missing scripts in future releases.
		</p>

		<p>
			If your JDBC driver supports the
			<code>getGeneratedKeys</code> method introduced in
			JDBC 3.0 specification, then no more steps are required, excluding usual
			configuration. 
		</p>
		<p>
			Otherwise, there must be an <code>SQLDialect</code> appropriate for your
			database system. Currently, we have dialects for PostgreSQL,
			MySQL, Oracle and MsSQL. As mentioned previously, an
			<code>SQLDialect</code> is required only if the JDBC driver for your
			database system does not support the <code>getGeneratedKeys</code>
			method.
		</p>

		<p>
			The table below summarizes the database types and their support of the 
			<code>getGeneratedKeys()</code> method.
		</p>

		<table border="1" cellpadding="4">
			<tr>
				<th>RDBMS</th>
				<th>
					supports
					<br />
					<code>getGeneratedKeys()</code>
					method
				</th>
				<th>
					specific
					<br />
					SQLDialect support
				</th>
			</tr>
			<tr>
				<td>PostgreSQL</td>
				<td>NO</td>
				<td>present and used</td>
			</tr>
			<tr>
				<td>MySQL</td>
				<td>YES</td>
				<td>present, but not actually needed or used</td>
			</tr>
			<tr>
				<td>Oracle</td>
				<td>YES</td>
				<td>present, but not actually needed or used</td>
			</tr>
			<tr>
				<td>DB2</td>
				<td>YES</td>
				<td>not present, and not needed or used</td>
			</tr>
			<tr>
				<td>MsSQL</td>
				<td>YES</td>
				<td>not present, and not needed or used</td>
			</tr>
			<tr>
				<td>HSQL</td>
				<td>NO</td>
				<td>present and used</td>
			</tr>
		</table>
		
		<p>
			Experiments show that writing a single event
			into the database takes approximately 10 milliseconds, on a
			"standard" PC. If pooled connections are used, this figure
			drops to around 1 milliseconds. Note that most JDBC drivers
			already ship with connection pooling support.
		</p>
		
		<p>
			Configuring logback to use <code>DBAppender</code> can be done
			in several different ways, depending on the tools one has to
			connect to the database, and the database itself. All manners of 
			configuring <code>DBAppender</code> are about setting its
			<code>ConnectionSource</code> object, which we will cover in
			a short moment.
		</p>
		
		<p>
			Once logback is configured properly, the logging events are sent to
			the specified database. As stated previously, there are three tables
			used by logback to store logging event data.
		</p>
		
		<p>
			The <em>logging_event</em> table contains the following fields:
		</p>
		<table>
			<tr>
				<th>Field</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><b>timestmp</b></td>
				<td><code>big int</code></td>
				<td>The timestamp that was valid at the logging event's creation.</td>
			</tr>
			<tr>
				<td><b>formatted_message</b></td>
				<td><code>text</code></td>
				<td>The message that has been added to the logging event, after formatting with
				<code>org.slf4j.impl.MessageFormatter</code>, in case object were passed
				along with the message.</td>
			</tr>
			<tr>
				<td><b>logger_name</b></td>
				<td><code>varchar</code></td>
				<td>The name of the logger used to issue the logging request.</td>
			</tr>
			<tr>
				<td><b>level_string</b></td>
				<td><code>varchar</code></td>
				<td>The level of the logging event.</td>
			</tr>
			<tr>
				<td><b>reference_flag</b></td>
				<td><code>smallint</code></td>
				<td>
					<p>
						This field is used by logback to identify logging events that
						have an exception or <code>MDC</code>property values associated. 
					</p>
					<p>
						It's value is computed by
						<code>ch.qos.logback.classic.db.DBHelper</code>. A logging event that 
						contains <code>MDC</code> or <code>Context</code> 
						properties has a flag number of <em>1</em>. One
						that contains an exception has a flag number of <em>2</em>. A logging
						event that contains both elements has a flag number of <em>3</em>.
					</p>
				</td>
			</tr>
			<tr>
				<td><b>caller_filename</b></td>
				<td><code>varchar</code></td>
				<td>The name of the file where the logging request was issued.</td>
			</tr>
			<tr>
				<td><b>caller_class</b></td>
				<td><code>varchar</code></td>
				<td>The class where the logging request was issued.</td>
			</tr>
			<tr>
				<td><b>caller_method</b></td>
				<td><code>varchar</code></td>
				<td>The name of the method where the logging request was issued.</td>
			</tr>
			<tr>
				<td><b>caller_line</b></td>
				<td><code>char</code></td>
				<td>The line number where the logging request was issued.</td>
			</tr>
			<tr>
				<td><b>event_id</b></td>
				<td><code>int</code></td>
				<td>The database id of the logging event.</td>
			</tr>
		</table>
		
		<p>
			The <em>logging_event_property</em> is used to store the keys and values
			contained in the <code>MDC</code> or the <code>Context</code>. 
			It contains these fields:
		</p>

		<table>
			<tr>
				<th>Field</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><b>event_id</b></td>
				<td><code>int</code></td>
				<td>The database id of the logging event.</td>
			</tr>
			<tr>
				<td><b>mapped_key</b></td>
				<td><code>varchar</code></td>
				<td>The key of the <code>MDC</code> property</td>
			</tr>		
			<tr>
				<td><b>mapped_value</b></td>
				<td><code>text</code></td>
				<td>The value of the <code>MDC</code> property</td>
			</tr>				
		</table>
		
		<p>
			The <em>logging_event_exception</em> table contains the following fields:
		</p>
		
		<table>
			<tr>
				<th>Field</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><b>event_id</b></td>
				<td><code>int</code></td>
				<td>The database id of the logging event.</td>
			</tr>
			<tr>
				<td><b>i</b></td>
				<td><code>smallint</code></td>
				<td>The index of the line in the full stack trace.</td>
			</tr>		
			<tr>
				<td><b>trace_line</b></td>
				<td><code>varchar</code></td>
				<td>The corresponding line</td>
			</tr>				
		</table>
		
		<p>
			To give a more visual example of the work done by <code>DBAppender</code>, here
			is a screenshot of a MySQL database with content provided by <code>DBAppender</code>.
		</p>
		
		<p>The <em>logging_event</em> table:</p>

		<img src="images/chapter4/dbAppenderLE.gif" alt="Logging Event table" />

		<p>The <em>logging_event_exception</em> table:</p>
		
		<img src="images/chapter4/dbAppenderLEException.gif" alt="Logging Event Exception table" />

		<p>The <em>logging_event_property</em> table:</p>
		
		<img src="images/chapter4/dbAppenderLEProperty.gif" alt="Logging Event Property table" />

		
		<h4>ConnectionSource</h4>
		
		<p>
			The <id>ConnectionSource</id> interface provides a pluggable means of 
			transparently obtaining JDBC Connections for logback classes that 
			require the use of a <code>java.sql.Connection</code>. There are currently
			three implementations of <code>ConnectionSource</code>, namely
			<code>DataSourceConnectionSource</code>, <code>DriverManagerConnectionSource</code>
			and <code>JNDIConnectionSource</code>.
		</p>
		
		<p>
			The first example that we will review is a configuration using
			<code>DriverManagerConnectionSource</code> and a MySQL database.
			The following configuration file is what one would need.
		</p>
		
<em>Example 4.11: <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">
    &lt;connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
      &lt;driverClass>com.mysql.jdbc.Driver&lt;/driverClass>
      &lt;url>jdbc:mysql://host_name:3306/datebase_name&lt;/url>
      &lt;user>username&lt;/user>
      &lt;password>password&lt;/password>
    &lt;/connectionSource>
  &lt;/appender></b>
  
  &lt;root>
    &lt;level value="debug" />
    &lt;appender-ref ref="DB" />
  &lt;/root>
&lt;/configuration></pre></div>

		<p>
			The correct driver must be declared. Here, the <code>com.mysql.jdbc.Driver</code>
			class is used. The <span class="option">url</span> must begin with <em>jdbc:myslq://</em>.
		</p>
		
		<p>
			The 
			<a href="../xref/ch/qos/logback/core/db/DriverManagerConnectionSource.html">
			<code>DriverManagerConnectionSource</code></a> is an implementation of
			<code>ConnectionSource</code> that obtains the connection in the
			traditional JDBC manner based on the connection URL.
		</p>
		<p>
			Note that this class will establish a new <code>Connection</code> for
			each call to <code>getConnection()</code>. It is recommended
			that you either use a JDBC driver that natively supports
			connection pooling or that you create your own
			implementation of <code>ConnectionSource</code> that taps into
			whatever pooling mechanism you are already using. (If you
			have access to a JNDI implementation that supports
			<code>javax.sql.DataSource</code>, e.g. within a J2EE application
			server, see <code>JNDIConnectionSource</code>).
		</p>
<!-- 
		
		HAS TO BE TESTED

		<p>
			If you do not have another connection pooling mechanism built
			into your application, you can use the
			<a href="http://jakarta.apache.org/commons/dbcp/index.html">
		  commons-dbcp </a> package from Apache:
		</p>

<div class="source"><pre>
  &lt;connectionSource
    class=&quot;ch.qos.logback.core.db.DriverManagerConnectionSource&quot;&gt;
    &lt;param name=&quot;driver&quot; value=&quot;org.apache.commons.dbcp.PoolingDriver&quot;/&gt; 
    &lt;param name=&quot;url&quot; value=&quot;jdbc:apache:commons:dbcp:/myPoolingDriver&quot;/&gt; 
  &lt;/connectionSource&gt;
</pre></div>
		
		<p>
			Then the configuration information for the commons-dbcp
			package goes into the file <em>myPoolingDriver.jocl</em> and is
			placed in the classpath. See the
			<a href="http://jakarta.apache.org/commons/dbcp/index.html"> commons-dbcp </a>
			documentation for details.
		</p>
 -->
 
		<p>
			Connecting to a database using a <code>DataSource</code> is rather similar.
			The configuration now uses 
			<a href="../xref/ch/qos/logback/core/db/DataSourceConnectionSource.html">
			<code>DataSourceConnectionSource</code></a>, 
			which is an implementation of <code>ConnectionSource</code> that obtains the 
			<code>Connection</code> in the recommended JDBC manner based on a 
			<code>javax.sql.DataSource</code>.
		</p>
	
<em>Example 4.12: <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">
     <b>&lt;connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
       
       &lt;dataSource class="${dataSourceClass}">
       	 </b>&lt;!-- Joran cannot substitute variables
       	 that are not attribute values. Therefore, we cannot
       	 declare the next parameter like the others. 
       	 -->
         <b>&lt;param name="${url-key:-url}" value="${url_value}"/>
         &lt;serverName>${serverName}&lt;/serverName>
         &lt;databaseName>${databaseName}&lt;/databaseName>
       &lt;/dataSource></b>
       
       &lt;user>${user}&lt;/user>
       &lt;password>${password}&lt;/password>
     &lt;/connectionSource>
  &lt;/appender>

  &lt;root>
    &lt;level value ="debug"/>
    &lt;appender-ref ref="DB" />
  &lt;/root>  
&lt;/configuration></pre></div>

		<p>
			Not that in this configuration sample, we make heavy use of substitution variables.
			They are sometimes handy when connection details have to be centralised in a
			single configuration file and shared by logback and other frameworks.
		</p>	
		
<!-- 		TO BE TESTED		
		<p>
			The connection created by <code>DataSourceConnectionSource</code> can be placed in a JNDI
			context by using <code>BindDataSourceToJNDIAction</code>. In that case, one has to specify
			the use of this class by adding a new rule to Joran, logback's configuration framework. Here
			is an excerpt of such a configuration file.
		</p>
		
<div class="source"><pre>&lt;configuration>
  ..
  <b>&lt;newRule pattern="configuration/bindDataSourceToJNDI" 
           actionClass="ch.qos.logback.core.db.BindDataSourceToJNDIAction"/>
  	    
  &lt;bindDataSourceToJNDI /></b>
  ..
&lt;/configuration></pre></div>

		<p>
			The <em>newRule</em> element teaches Joran to use specified action class with the given pattern.
			Then, we simply declare the given element. The action class will be called and our connection
			source will be bound to a JNDI context.
		</p>
		<p>
			This is a very powerfull possibility of Joran. If you'd like to read more about Joran, please
			visit our <a href="../joran.html">introduction to Joran</a>.
		</p>
		
		-->

		<p>
			The third implementation of <code>ConnectionSource</code> that is shipped with
			logback is the <code>JNDIConnectionSource</code>.
		</p>

		<p>
			The
			<a href="../xref/ch/qos/logback/core/db/JNDIConnectionSource.html">
			<code>JNDIConnectionSource</code></a>
			is an implementation of <code>ConnectionSource</code> that
			obtains a <code>javax.sql.DataSource</code> from a JNDI provider
			and uses it to obtain a <code>java.sql.Connection</code>. It is
			primarily designed to be used inside of J2EE application
			servers or application server clients, assuming the
			application server supports remote access of <code>javax.sql.DataSource</code>. 
			In this way one can take advantage of connection pooling and whatever other goodies the
			application server provides.
		</p>
		
<div class="source"><pre>&lt;connectionSource class=&quot;ch.qos.logback.core.db.JNDIConnectionSource&quot;&gt;
  &lt;param name=&quot;jndiLocation&quot; value=&quot;jdbc/MySQLDS&quot; /&gt;
  &lt;param name=&quot;username&quot; value=&quot;myUser&quot; /&gt;
  &lt;param name=&quot;password&quot; value=&quot;myPassword&quot; /&gt;
&lt;/connectionSource&gt;</pre></div>

		<p>
			Note that this class will obtain an
			<code>javax.naming.InitialContext</code>
			using the no-argument constructor. This will usually work
			when executing within a J2EE environment. When outside the
			J2EE environment, make sure that you provide a
			<em>jndi.properties</em>
			file as described by your JNDI provider's documentation.
		</p>
		
		<h4>Connection pooling</h4>
		
		<p>
			Logging events can be created at a rather fast pace. To keep up
			with the flow of events that must be inserted into a database, 
			it is recommanded to use connection pooling with
			<code>DBAppender</code>.
		</p>
		
		<p>
			Experiment shows that using connection pooling with <code>DBAppender</code>
			gives a big performance boost. With the following
			configuration file, logging events are sent to a MySQL database,
			without any pooling.
		</p>
<em>Example 4.13: <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">
    &lt;connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
      &lt;dataSource class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
        &lt;serverName>${serverName}&lt;/serverName>
        &lt;port>${port$&lt;/port>
        &lt;databaseName>${dbName}&lt;/databaseName>
        &lt;user>${user}&lt;/user>
        &lt;password>${pass}&lt;/password>
      &lt;/dataSource>
    &lt;/connectionSource>
  &lt;/appender>
    
  &lt;root>
    &lt;level value="debug" />
    &lt;appender-ref ref="DB" />
  &lt;/root>
&lt;/configuration</pre></div>

		<p>
			With this configuration file, sending 500 logging events to
			a MySQL database takes a whopping 5 seconds, that is 
			10 miliseconds per requests. This figure is
			unacceptable when dealing with large applications.
		</p>

		<p>
			A dedicated external library is necessary to use connection pooling
			with <code>DBAppender</code>. The next example uses 
			<a href="http://sourceforge.net/projects/c3p0">c3p0</a>. To be able
			to use c3p0, one must download it and place <em>c3p0-VERSION.jar</em>
			in the classpath.
		</p>

<em>Example 4.14: <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>

  &lt;appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    &lt;connectionSource
      class="ch.qos.logback.core.db.DataSourceConnectionSource">
      <b>&lt;dataSource
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        &lt;driverClass>com.mysql.jdbc.Driver&lt;/driverClass>
        &lt;jdbcUrl>jdbc:mysql://${serverName}:${port}/${dbName}&lt;/jdbcUrl>
        &lt;user>${user}&lt;/user>
        &lt;password>${password}&lt;/password>
      &lt;/dataSource></b>
    &lt;/connectionSource>
  &lt;/appender>

  &lt;root>
    &lt;level value="debug" />
    &lt;appender-ref ref="DB" />
  &lt;/root>
&lt;/configuration></pre></div>

		<p>
			With this new configuration, sending 500 logging requests to
			the same MySQL database as previously used takes around 0.5 seconds,
			for an average time of 1 milisecond per request.
			The gain is a <em>10</em> factor. 
		</p>

		<a name="SyslogAppender" />
		<h3>SyslogAppender</h3>
		
		<p>
			The syslog protocol is a very simple protocol: a syslog sender sends a small 
			message to a syslog receiver. 
			The receiver is commonly called <em>syslog daemon</em> or <em>syslog server</em>.
			Logback can send messages to a remote syslog daemon. This is achieved by using 
			<a href="../xref/ch/qos/logback/classic/net/SyslogAppender.html"><code>SyslogAppender</code></a>.
		</p>
		
		<p>
			Here are its options:
		</p>

		<table>
			<tr>
				<th>Option Name</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td>
					<b>
						<span class="option">SyslogHost</span>
					</b>
				</td>
				<td>
					<code>String</code>
				</td>
				<td>
					The host name of the syslog server.
				</td>
			</tr>
			<tr>
				<td>
					<b>
						<span class="option">Port</span>
					</b>
				</td>
				<td>
					<code>String</code>
				</td>
				<td>
					The port number on the syslog server to connect to. Normally, one would not want 
					to change the default value, that is <em>514</em>.
				</td>
			</tr>
			<tr>
				<td>
					<b>
						<span class="option">Facility</span>
					</b>
				</td>
				<td>
					<code>String</code>
				</td>
				<td>
					<p>
						The <span class="option">Facility</span> is meant to identify 
						the source of a message.
					</p>
					<p>
						The <span class="option">Facility</span> option must be set one 
						of the strings <em>KERN, USER, MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, 
						CRON, AUTHPRIV, FTP, NTP, AUDIT, ALERT, CLOCK, LOCAL0, LOCAL1, LOCAL2, 
						LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7</em>. Case is not important.
					</p>
				</td>
			</tr>
			<tr>
				<td>
					<b>
						<span class="option">SuffixPattern</span>
					</b>
				</td>
				<td>
					<code>String</code>
				</td>
				<td>
					<p>
						The <span class="option">SuffixPattern</span> option specifies the format of the 
						non-standardized part the message sent to the syslog server. By default, its value
						is <em>[%thread] %logger %msg %exception</em>. Any value that a <code>PatternLayout</code>
						could use is a correct <span class="option">SuffixPattern</span>.
					</p>
				</td>
			</tr>
		</table>
		
		<p>
			The syslog severity of a logging event is converted from the level of the logging event.
			The <em>DEBUG</em> level is converted to <em>7</em>, <em>INFO</em> is converted to
			<em>6</em>, <em>WARN</em> is converted to <em>4</em> and <em>ERROR</em> is converted
			to <em>3</em>.
		</p>
		
		<p>
			Since the format of a syslog request follows rather strict rules, there is no layout
			to be used with <code>SyslogAppender</code>. However, the using the 
			<span class="option">SuffixPattern</span> option lets the user display whatever
			information she wishes.
		</p>
		
		<p>
			Here is a sample configuration using a <code>SyslogAppender</code>.
		</p>
		
<em>Example 4.15: <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"
    class="ch.qos.logback.classic.net.SyslogAppender">
    &lt;SyslogHost>remote_home&lt;/SyslogHost>
    &lt;Facility>AUTH&lt;/Facility>
    &lt;SuffixPattern>%-4relative [%thread] %-5level - %msg&lt;/SuffixPattern>
  &lt;/appender>

  &lt;root>
    &lt;level value="debug" />
    &lt;appender-ref ref="STDOUT" />
  &lt;/root>
&lt;/configuration></pre></div>

		<p>
			When testing this configuration, one should verify that the remote syslog daemon
			accepts requests from an external source. Experience shows that syslog daemons
			usually deny such requests by default.
		</p>
		
		
		<a name="Access" />
		<h2>Logback Access</h2>
		
		<p>
			Most of the appenders found in logback classic can be used within
			logback access. They function mostly in the same way as their logback
			classic counterpart. In the next section, we will cover their use, but will
			focuse on the differences with the classic appenders.
		</p>
		
  	<a name="AccessSocketAppender"/>
		<h3>SocketAppender</h3>
		
		<p>
			The <a href="../xref/ch/qos/logback/access/net/SocketAppender.html">
			<code>SocketAppender</code></a> is designed to log to a 
			remote entity by transmitting serialized <code>AccessEvent</code> objects over the wire. 
			Remote logging is non-intrusive as far as the access event is concerned. 
			On the receiving end after de-serialization, the event can be logged as 
			if it were generated locally.
		</p>
		<p>
			The options of access' <code>SocketAppender</code> are the same as those available
			for classic's <code>SocketAppender</code>.
		</p>

	 	<a name="AccessSMTPAppender"/>	
		<h3>SMTPAppender</h3>
		
		<p>
			Access' <a href="../xref/ch/qos/logback/access/net/SMTPAppender.html">
			<code>SMTPAppender</code></a> works in the same way as its Classic counterpart.
			However, the <span class="option">evaluator</span> option is rather different. 
			By default, a <code>URLEvaluator</code> object
			is used by <code>SMTPAppender</code>. This evaluator contains a list of URLs that are
			checked agains the current request's URL. When one of the pages given to the
			<code>URLEvaluator</code> is requested, <code>SMTPAppender</code> sends an email.
		</p>
		
		<p>
			Here is a sample configuration of a <code>SMTPAppender</code> in the access environnement.
		</p>
<em>Example 4.15: <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">
    &lt;Pattern>%h%l%u%t%r%s%b&lt;/Pattern>
  &lt;/layout>
    
  <b>&lt;Evaluator class="ch.qos.logback.access.net.URLEvaluator">
    &lt;URL>url1.jsp&lt;/URL>
    &lt;URL>directory/url2.html&lt;/URL>
  &lt;/Evaluator></b>
  &lt;From>sender_email@host.com&lt;/From>
  &lt;SMTPHost>mail.domain.com&lt;/SMTPHost>
  &lt;To>recipient_email@host.com&lt;/To>
&lt;/appender></pre></div>

		<p>
			This way of triggering the email lets user select pages that are important steps
			in a specific process, for example. 
			When such a page is accessed, the email is sent with the pages
			that were accessed previously, and any information the user wants to be included
			in the email.
		</p>
		
		

		<a name="AccessDBAppender"/>
		<h3>DBAppender</h3>
		
		<p>
			<a href="../xref/ch/qos/logback/access/db/DBAppender.html"><code>DBAppender</code></a>
			is used to insert the access events into a database.
		</p>
		<p>
			Two tables are used by <code>DBAppender</code>: <em>access_event</em> and
			<em>access_event_header</em>. They all must exist before <code>DBAppender</code>
			can be used. Logback ships with SQL scripts that will create the tables. 
			They can be found in the found in the 
			<em>logback-access/src/main/java/ch/qos/logback/access/db/dialect</em> directory. There
			is a specific script for each of the most popular database systems. 
			If the script for your particular type of database system is missing, it should be
			quite easy to write one, taking example on the already existing scripts. If
			you send them to us, we will gladly include missing scripts in future releases.
		</p>
		
		<p>The <em>access_event</em> table's fields are described below:</p>

		<table>
			<tr>
				<th>Field</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><b>timestmp</b></td>
				<td><code>big int</code></td>
				<td>The timestamp that was valid at the access event's creation.</td>
			</tr>
			<tr>
				<td><b>requestURI</b></td>
				<td><code>varchar</code></td>
				<td>The URI that was requested.</td>
			</tr>
			<tr>
				<td><b>requestURL</b></td>
				<td><code>varchar</code></td>
				<td>The URL that was requested. This is a string composed of the request method,
				the request URI and the request protocol.
				</td>
			</tr>
			<tr>
				<td><b>remoteHost</b></td>
				<td><code>varchar</code></td>
				<td>The name of the remote host.</td>
			</tr>
			<tr>
				<td><b>remoteUser</b></td>
				<td><code>varchar</code></td>
				<td>
					The name of the remote user.
				</td>
			</tr>
			<tr>
				<td><b>remoteAddr</b></td>
				<td><code>varchar</code></td>
				<td>The remote IP address.</td>
			</tr>
			<tr>
				<td><b>protocol</b></td>
				<td><code>varchar</code></td>
				<td>The request protocol, like <em>HTTP</em> or <em>HTTPS</em>.</td>
			</tr>
			<tr>
				<td><b>method</b></td>
				<td><code>varchar</code></td>
				<td>The request method, usually <em>GET</em> or <em>POST</em>.</td>
			</tr>
			<tr>
				<td><b>serverName</b></td>
				<td><code>varchar</code></td>
				<td>The name of the server that issued the request.</td>
			</tr>
			<tr>
				<td><b>event_id</b></td>
				<td><code>int</code></td>
				<td>The database id of the access event.</td>
			</tr>
		</table>
		
		<p>
			The <em>access_event_header</em> table contains the header of each
			requests. The information is organised as shown below:
		</p>

		<table>
			<tr>
				<th>Field</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td><b>event_id</b></td>
				<td><code>int</code></td>
				<td>The database id of the corresponding access event.</td>
			</tr>
			<tr>
				<td><b>header_key</b></td>
				<td><code>varchar</code></td>
				<td>The header name, for example <em>User-Agent</em>.</td>
			</tr>
			<tr>
				<td><b>header_value</b></td>
				<td><code>varchar</code></td>
				<td>The header value, for example <em>Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0</em></td>
			</tr>
			</table>

		<p>
			All options of classic's <code>DBAppender</code> are available
			in access' <code>DBAppender</code>. The latter offers one more option,
			described below.
		</p>
		
		<table>
			<tr>
				<th>Option Name</th>
				<th>Type</th>
				<th>Description</th>
			</tr>
			<tr>
				<td>
					<b>
						<span class="option">insertHeaders</span>
					</b>
				</td>
				<td>
					<code>boolean</code>
				</td>
				<td>
					Tells the <code>DBAppender</code> to populate the database with the header
					information of all incoming requests.
				</td>
			</tr>
		</table>
		
		<p>
			Here is a sample configuration that uses <code>DBAppender</code>.
		</p>
		
<div class="source"><pre>&lt;configuration>

  &lt;appender name="DB" class="ch.qos.logback.access.db.DBAppender">
    &lt;connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
      &lt;driverClass>com.mysql.jdbc.Driver&lt;/driverClass>
      &lt;url>jdbc:mysql://localhost:3306/logbackdb&lt;/url>
      &lt;user>logback&lt;/user>
      &lt;password>logback&lt;/password>
    &lt;/connectionSource>
    &lt;insertHeaders>true&lt;/insertHeaders>
  &lt;/appender>

  &lt;appender-ref ref="DB" />
&lt;/configuration></pre></div>


    <a name="WriteOwnAppender" />
		<h2>Writing your own Appender</h2>


    <p>You can easily write your appender by sub-classing <code>AppenderBase</code>. 
    It handles support for filters, status among other functionality shared by most appenders. 
    The derived class only needs to implement one method, namely 
    <code>append(Object eventObject)</code>.
    </p>

    <p>The <code>CountingConsoleAppender</code>, which we list next, appends a limited 
    number of incoming events on the console. It shuts down after the limit is reached.
    It uses a <code>Layout</code> to format the events and accepts a parameter, 
    thus a few more methods are needed.
    </p>
    
<em>Example 4.16: <code>CountingConsoleAppender</code> (logback-examples/src/main/java/chapter4/CountingConsoleAppender.java)</em>					    
<div class="source"><pre>package chapter4;

import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Layout;


public class CountingConsoleAppender extends AppenderBase {
  static int DEFAULT_LIMIT = 16;
  int counter = 0;
  int limit = DEFAULT_LIMIT;
  
  private Layout layout;

  public CountingConsoleAppender() {
  }

  public void setLimit(int limit) {
    this.limit = limit;
  }

  public int getLimit() {
    return limit;
  }  
  
  @Override
  public void start() {
    if (this.layout == null) {
      addError("No layout set for the appender named ["+ name +"].");
      return;
    }
    
    super.start();
  }

  public void append(Object eventObject) {

    if (counter >= limit) {
      return;
    }

    // output the events as formatted by our layout
    System.out.print(this.layout.doLayout(eventObject));

    // prepare for next event
    counter++;
  }

  public Layout getLayout() {
    return layout;
  }

  public void setLayout(Layout layout) {
    this.layout = layout;
  }
}</pre></div>

		<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>
		
		<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>
			<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>
  </body>
</document>