<document>
	<!-- 
		
		Warning: do not use any auto-format function on this file.
		Since "source" divs use pre as white-space, it affects the
		look of the code parts in this document.
		
	-->


	<body>
		<h2>Chapter 4: Appenders</h2>
		<div class="author">
			Authors: Ceki G&#252;lc&#252;, S&#233;bastien Pennec
		</div>


		<table>
			<tr>
				<td valign="top" align="top">
						<a rel="license"
							href="http://creativecommons.org/licenses/by-nc-sa/2.5/">
							<img alt="Creative Commons License"
								style="border-width: 0"
								src="http://creativecommons.org/images/public/somerights20.png" />
						</a>
				</td>
				<td>
					<p>Copyright &#169; 2000-2006, QOS.ch</p>

					<p>
						<!--Creative Commons License-->
						This work is licensed under a
						<a rel="license"
							href="http://creativecommons.org/licenses/by-nc-sa/2.5/">
							Creative Commons
							Attribution-NonCommercial-ShareAlike 2.5
							License
						</a>.
						<!--/Creative Commons License-->
					</p>
				</td>
			</tr>
		</table>

		<h2>What is an Appender</h2>

		<p>
			Logback delegates the task of writing a logging event to appenders. 
			Appenders must imple-ment the <code>ch.qos.logback.core.Appender</code> interface. 
			The salient methods of this interface are summarized below:
		</p>
		<div class="source"><pre>package ch.qos.logback.core;
  
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.LifeCycle;
  

public interface Appender extends LifeCycle, ContextAware, FilterAttachable {

  public String getName();
  <b>void doAppend(Object event);</b>
  public void setLayout(Layout layout);
  public Layout getLayout();
  public void setName(String name);
  
}</pre></div>

	<p>
		Most of the methods in the Appender interface are made of setter 
		and getter methods. A notable exception is the <code>doAppend()</code> 
		method taking an Object instance as its only parameter. 
		This method is perhaps the most important in the logback framework. 
		It is responsible for outputting the logging events in a suitable format 
		to the appropriate output device. Appenders are named entities. 
		This ensures that they can be referenced by name, a quality confirmed 
		to be especially significant in configuration scripts. 
		An appender can contain multiple filters, thus the <code>Appender</code>
		interface extending the <code>FilterAttachable</code> interface.
		Filters are discussed in detail in a subsequent chapter.
	</p>
	
	<p>
		Appenders are ultimately responsible for outputting logging events. 
		However, they may delegate the actual formatting of the event to a 
		<code>Layout</code> object. 
		Each layout is associated with one and only one appender, referred to 
		as the containing appender. Some appenders have a built-in or fixed 
		event format, such that they do not require a layout. For example, the 
		<code>SocketAppender</code> simply serialize logging events before 
		transmitting them over the wire.
	</p>
	
	<a name="AppenderBase"/>
	<h2>AppenderBase</h2>
	
	<p>
		The <code>ch.qos.logback.core.AppenderSkeleton</code> class is an abstract 
		class implementing the <code>Appender</code> interface. 
		It provides basic functionality shared by all appenders, 
		such as methods for getting or setting their name, their started status, 
		their layout and their filters. 
		It is the super-class of all appenders shipped with logback. 
		Although an abstract class, AppenderBase actually implements the 
		<code>doAppend()</code> method in the <code>Append</code> interface. 
		Perhaps the clearest way to discuss AppenderBase class is by 
		presenting a bit of its actual source code.
		<code>AppenderBase</code>'s complete source code is also 
		<a href="../xref/ch/qos/logback/core/AppenderBase.html">
		available for viewing</a>.  
	</p>
	
<div class="source"><pre>public synchronized void doAppend(Object eventObject) {

  // prevent re-entry.
  if (guard) {
    return;
  }

  try {
    guard = true;

    if (!this.started) {
      if (statusRepeatCount++ &lt; ALLOWED_REPEATS) {
        addStatus(new WarnStatus(
            "Attempted to append to non started appender [" + name + "].",this));
      }
      return;
    }

    if (getFilterChainDecision(eventObject) == FilterReply.DENY) {
      return;
    }
    
    // ok, we now invoke derived class' implementation of append
    this.append(eventObject);

  } finally {
    guard = false;
  }
}</pre></div>
	
	<p>
		This implementation of the <code>doAppend()</code> method is synchronized. 
		It follows that logging to the same appender from different 
		threads is safe. While a thread, say <em>T</em>, is executing the <code>doAppend()</code> 
		method, subsequent calls by other threads are queued until <em>T</em> 
		leaves the <code>doAppend()</code> method, ensuring 
		<em>T</em>'s exclusive access to the appender. 
	</p>
	
	<p>
		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. Why could it call itself, you  might ask? Well, 
		just imagine that a logback component, called somewhere beyond the <code>append()</code>
		method, might want 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> object implement the <code>LifeCycle</code> interface, 
		which implies that they implement <code>start()</code>, <code>stop()</code>
		and <code>isStarted()</code> methods. After setting all the options of an appender,
		Joran, logback's configuration framework, calls this method to signal the appender
		to bind or activate its options.
		Indeed, depending on the appender, certain options cannot be activated because 
		of interferences with other options, or appenders can even not start at all if
		some options are missing. 
		For example, since file creation depends on truncation mode, 
		<code>FileAppender</code> cannot act on the value of its <code>File</code> option 
		until the value of the Append option is also known for certain.
		Sub-classes of <code>AppenderBase</code> are required to set the boolean variable 
		<code>started</code> to false when their <code>stop()</code> method is invoked.
	</p>
	
	<p>
		If a warning message is sent due to incorrect calls to the <code>doAppend()</code>
		method, logback's powerful <code>Status</code> error reporting system is used. In case
		several incorrect calls on <code>doAppend()</code> are issued, <code>AppenderBase</code>
		does not send an unlimited number of warnings. Once a certain limit is reached, the
		<code>AppenderBase</code> instance stops its warnings.
	</p>
	
	<p>
		The next <code>if</code> statement checks the result
		of the attached <code>Filter</code> objects. 
		Depending on the decision made by the filters 
		in the filter chain, events can be denied or alternatively accepted. 
		In the absence of a decision by the filter chain, events are accepted by default.
	</p>
	
	<p>
		Lastly, the <code>doAppend()</code> method invoke the derived classes' implementation
		of the <code>append()</code> method, which does the actual work of appending the
		event to the appropriate device.
	</p>
	
	<p>DO WE ADD A UML DIAGRAM?? YES!!</p>
	
	<p>In appenders, the term option or property is reserved for named attributes 
	that are dynamically inferred using JavaBeans introspection. </p>
	
	<h2>Logback Core</h2>
	<a name="WriterAppender" />
	<h3>WriterAppender</h3>
	
	<p>
		<code>WriterAppender</code> appends events to a <code>java.io.Writer</code>. 
		This class provides basic services that other appenders build upon. 
		Users do not usually instantiate <code>WriterAppender</code> objects directly. 
		Since <code>java.io.Writer</code> type cannot be mapped to a string, there is no 
		way to specify the target <code>Writer</code> object in a configuration script. 
		Simply put, you cannot configure a <code>WriterAppender</code> from a script. 
		However, this does not mean that <code>WriterAppender</code> lacks configurable options. 
		These options are described next.
	</p>
	
	<table>
		<tr>
			<th>Option Name</th>
			<th>Type</th>
			<th>Description</th>
		</tr>
		<tr>
			<td><b><span class="option">Encoding</span></b></td>
			<td><code>String</code></td>
			<td>
				The encoding specifies the method of conversion between 16-bit Unicode 
				characters into raw 8-bit bytes. This appender will use the local platform's 
				default encoding unless you specify otherwise using the 
				<span class="option">Encoding</span> option. 
				According to the <code>java.lang</code> package documentation, acceptable values 
				are dependent on the VM implementation although all implementations are 
				required to support at least the following encodings: 
				<em>US-ASCII</em>, <em>ISO-8859-1</em>, <em>UTF-8</em>, <em>UTF-16BE</em>,
				<em>UTF-16LE</em> and <em>UTF-16</em>. 
				By default, the <span class="option">Encoding</span> option is null such 
				that the platform's default encoding is used.
			</td>
		</tr>
		<tr>
			<td><b><span class="option">ImmediateFlush</span></b></td>
			<td><code>boolean</code></td>
			<td>
				If set to true, each write of a logging event is followed by a flush operation 
				on the underlying <code>Writer</code> object. Conversely, if the option is set to false, 
				each write will not be followed by a flush. 
				In general, skipping the flush operation improves logging throughput by roughly 15%. 
				The downside is that if the application exits abruptly, the unwritten characters 
				buffered inside the <code>Writer</code> might be lost. 
				This can be particularly troublesome as those unwritten characters may contain 
				crucial information needed in identifying the reasons behind a crash. 
				By default, the <span class="option">ImmediateFlush</span> option is set to true.
			</td>
		</tr>
	</table>
	
	<p>
		In general, if you disable immediate flushing, then make sure to flush 
		any output streams when your application exits. Otherwise, log messages 
		will be lost as illustrated by the next example. 
	</p>
	
	<em>Example 4.1: Exiting an application without flushing (logback-examples/src/main/java/chapter4/
	<a href="../xref/chapter4/ExitWoes.html">ExitWoes.java</a>)</em>
<div class="source"><pre>package chapter4;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.WriterAppender;
import ch.qos.logback.core.layout.DummyLayout;

public class ExitWoes {

  public static void main(String[] args) throws Exception {
    LoggerContext lc = new LoggerContext();
    WriterAppender writerAppender = new WriterAppender();
    writerAppender.setContext(lc);
    writerAppender.setLayout(new DummyLayout());

    OutputStream os = new FileOutputStream("exitWoes1.log");
    writerAppender.setWriter(new OutputStreamWriter(os));
    writerAppender.setImmediateFlush(false);
    writerAppender.start();

    Logger logger = LoggerFactory.getLogger(ExitWoes1.class);

    logger.debug("Hello world.");
  }
}</pre></div>

	<p>
		This example creates a <code>WriterAppender</code> that uses an 
		<code>OutputStreamWriter</code> 
		wrapping a <code>FileOutputStream</code> as its underlying <code>Writer</code> object, 
		with immediate flushing disabled. It then proceeds to log a single debug message. 
		According to <code>OutputStreamWriter</code> javadocs, each invocation of a 
		<code>write()</code>
		method causes the encoding converter to be invoked on the given character(s). 
		The resulting bytes are accumulated in a buffer before being written 
		to the underlying output stream. As astonishing as this may seem, 
		running <code>ExitWoes1</code> will not produce any output in the file 
		<em>exitWoes1.log</em>
		because the Java VM does not flush output streams when it exits. 
		Calling the <code>shutdown()</code> method of a <b>XXXXXX</b> ensures that all 
		appenders in the hierarchy are closed and their buffers are flushed. 
		For most applications this is as simple as including the following statement 
		before exiting the application.
	</p>
	<p>WHAT TO DO IN LB ???</p>

	<p>
		The <code>WriterAppender</code> is the super class of four other appenders, 
		namely <code>ConsoleAppender</code>, <code>FileAppender</code> which in turn is 
		the super class of <code>RollingFileAppender</code>. 
	</p>
	<p><b>include UML??</b>
		Figure 4 2 illustrates the class diagram for WriterAppender and its subclasses
	</p>
	<a name="ConsoleAppender" />
	<h3>ConsoleAppender</h3>
	
	<p>
		The <code>ConsoleAppender</code>, as the name indicates, appends on the console, 
		or more precisely on <em>System.out</em> or <em>System.err</em>, the former 
		being the default target. <code>ConsoleAppender</code> formats events with 
		a layout specified by the user. Both <em>System.out</em> and <em>System.err</em> 
		are <code>java.io.PrintStream</code> objects. 
		Consequently, they are wrapped inside an <code>OutputStreamWriter</code> 
		which buffers I/O operations but not character conversions. 
	</p>
	
	<table>
			<tr>
			<th>Option Name</th>
			<th>Type</th>
			<th>Description</th>
		</tr>
		<tr>
			<td><b><span class="option">Encoding</span></b></td>
			<td><code>String</code></td>
			<td>See <code>WriterAppender</code> options.</td>
		</tr>
		<tr>
			<td><b><span class="option">ImmediateFlush</span></b></td>
			<td><code>boolean</code></td>
			<td>See <code>WriterAppender</code> options.</td>
		</tr>
		<tr>
			<td><b><span class="option">Target</span></b></td>
			<td><code>String</code></td>
			<td>
				One of the String values <em>System.out</em> or 
				<em>System.err</em>. The default target is <em>System.out</em>.
			</td>
		</tr>
	</table>
	<a name="FileAppender" />
	<h3>FileAppender</h3>
	
	<p>
		The <code>FileAppender</code>, a subclass of <code>WriterAppender</code>, 
		appends log events into a file. The file to write to is specified by 
		the <span class="option">File</span> option. 
		If the file already exists, it is either appended to, or truncated 
		depending on the value of the <span class="option">Append</span> option. 
		It uses a <code>FileOutputStream</code> which is wrapped by an <code>OutputStreamWriter</code>. 
		Note that <code>OutputStreamWriter</code> buffers I/O operations 
		but not character conversions. To optimize character conversions one 
		can set the <span class="option">BufferedIO</span> option to true 
		which effectively wraps the <code>OutputStreamWriter</code> with 
		a <code>BufferedWriter</code>. Options for <code>FileAppender</code> are summarized below. 
	</p>
	
	<table>
			<tr>
			<th>Option Name</th>
			<th>Type</th>
			<th>Description</th>
		</tr>
		<tr>
			<td><b><span class="option">Append</span></b></td>
			<td><code>boolean</code></td>
			<td>If true, events are appended at the end of an existing file. 
			Otherwise, if <span class="option">Append</span> is false, any existing 
			file is truncated. The <span class="option">Append</span> option is set to true by default.</td>
		</tr>
		<tr>
			<td><b><span class="option">Encoding</span></b></td>
			<td><code>String</code></td>
			<td>See <code>WriterAppender</code> options.</td>
		</tr>
		<tr>
			<td><b><span class="option">BufferedIO</span></b></td>
			<td><code>boolean</code></td>
			<td>
				The <span class="option">BufferedIO</span> option is set to false by default. 
				If set to true, the underlying <code>OutputStreamWriter</code> is wrapped 
				by a <code>BufferedWriter</code> object. 
				Setting <span class="option">BufferedIO</span> to true automatically 
				sets the <span class="option">ImmediateFlush</span> option to false. 
				The name <span class="option">BufferedIO</span> is slightly misleading because 
				buffered IO is already supported by <code>OutputStreamWriter</code>. 
				Setting <span class="option">BufferedIO</span> to true has the effect of 
				buffering I/O as well as character to raw byte conversions, saving a few 
				CPU cycles in the process.
			</td>
		</tr>
		<tr>
			<td><b><span class="option">BufferSize</span></b></td>
			<td><code>int</code></td>
			<td>Size of <code>BufferedWriter</code> buffer. The default value is 8192.</td>
		</tr>
		<tr>
			<td><b><span class="option">File</span></b></td>
			<td><code>int</code></td>
			<td>
				The name of the file to write to. If the file does not exist, it is created. <br />
				On the MS Windows platform users frequently forget to escape back slashes. 
				For example, the value <em>c:\temp\test.log</em> is not likely to be interpreted 
				properly as <em>'\t'</em> is an escape sequence interpreted as a single 
				tab character <em>(\u0009)</em>. 
				Correct values can be specified as <em>c:/temp/test.log</em> or 
				alternatively as <em>c:\\temp\\test.log</em>. 
				The <span class="option">File</span> option has no default value.
			</td>
		</tr>
	</table>
	
	<p>
		By default, <code>FileAppender</code> performs a flush operation for 
		each event, ensuring that events are immediately written to disk. 
		Setting the <span class="option">ImmediateFlush</span> option to false can drastically reduce 
		I/O activity by letting <code>OutputStreamWriter</code> buffer bytes 
		before writing them on disk. For short messages, we have observed 2 or 3 
		fold increases in logging throughput, i.e. the number of logs output 
		per unit of time. For longer messages, the throughput gains are somewhat 
		less dramatic, and range between 1.4 and 2 fold. Enabling the 
		<span class="option">BufferedIO</span> 
		option, that is buffering character to byte conversions, increases 
		performance by an additional 10% to 40% compared to only disk 
		I/O buffering (<span class="option">ImmediateFlush</span>=false). 
		Performance varies somewhat depending on the host machine as well as JDK version. 
		Throughput measurements are based on the <code>chapter4.IO</code> application.
		Please refer to the file <em>logback-examples/src/main/java/chapter4/IO.java</em> 
		for actual source code. 
		<a href="../xref/chapter4/IO.html">Online viewing</a> 
		of this file is also available. 
	</p>
	
	<a name="RollingFileAppender" />
	<h3>RollingFileAppender</h3>
	
	<p>
		<code>RollingFileAppender</code> 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>
		implementation 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>int</code></td>
			<td>See <code>WriterAppender</code> options.</td>
		</tr>	
		<tr>
			<td><b><span class="option">File</span></b></td>
			<td><code>int</code></td>
			<td>See <code>FileAppender</code> options.</td>
		</tr>	
		<tr>
			<td><b><span class="option">ImmediateFlush</span></b></td>
			<td><code>int</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 the 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><code>RollingPolicy</code> implementations are responsible for the
	procedure of the rollover. They manage file renaming and sometimes deleting.</p>
	
	<p>The <code>RollingPolicy</code> interface is rather simple:</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 {


  public void rollover() throws RolloverFailure;
  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, <code>FixedWindowRollingPolicy</code>
		renames files according to a fixed window algorithm as described below.
	</p>
	<p>
		The <b>File</b>property, which is configured in the 
		<code>FileAppender</code> element, is required. It represents the name of the file
		where current logging output will be written. The <b>FileNamePattern</b>
		option represents the file name pattern for the archived (rolled over) log files. 
		The <b>FileNamePattern</b> 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 <code>FileAppender</code>'s <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>
				At 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>
<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 %class - %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>
		<code>TimeBasedRollingPolicy</code> 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 uses the pattern to custom each rolled files. 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 customizations.
	</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 <code>RollingPolicy</code> as well as <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>
	
<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 %class - %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><code>TriggeringPolicy</code> implementations are responsible for instructing
		the <code>RollingFileAppender</code> to proceed to the 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 {

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

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

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

		<p>
			<code>SizeBasedTriggeringPolicy</code>
			looks at size of the file being currently written to. If it
			grows bigger 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>
			<b>Althought values expressed in <em>GB</em> are possible, 
			we do not recommand setting the <span class="option">MaxFileSize</span>
			option to a value bigger than XXX GB</b>.
		</p>
		<p>
			Here is a sample configuration with a <code>RollingFileAppender</code>
			using a <code>SizeBasedTriggeringPolicy</code>.
		</p>

<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 %class - %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>












		<h2>Logback Classic</h2>
	
	<h2>Logback Access</h2>
	
	
	
	
	
	
	
	

	</body>
</document>
