<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>Short introduction</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-nd/2.5/">
    				<img alt="Creative Commons License" border="0"
    					valign="top" align="top"
    					src="http://creativecommons.org/images/public/somerights20.png" />
    			</a>
    		</td>
    		<td>
    			<p>Copyright &#169; 2000-2006, QOS.ch</p>

    			<p>
    				This work is licensed under a
    				<a rel="license"
    					href="http://creativecommons.org/licenses/by-nc-nd/2.5/">
    					Creative Commons Attribution-Noncommercial-No
    					Derivative Works 2.5 License
    				</a>
    				.
    			</p>
    		</td>
    	</tr>
    </table>

    <h2>Introduction</h2>

    <p>
    	Logback is intended as a successor to the popular log4j project.
    	It was designed by Ceki G&#252;lc&#252;, the founder of the
    	log4j project. It builds upon a decade long experience gained in
    	designing industrial-strength logging systems. The resulting
    	product is at faster and has a smaller footprint than all the
    	existing logging systems, sometimes by a wide margin. Logback
    	also offers unique and rather useful features such as Markers,
    	parameterized logging statements, conditional stack tracing and
    	powerful event filtering, to cite a few. For its own error
    	reporting, logback relies on
    	<code>Status</code>
    	objects which come in handy in contexts other than logging.
    </p>

    <p>
    	This document presents the more basic concepts in logback,
    	probably just enough to get you started.
    </p>

    <h2>Logback architecture</h2>

    <p>
    	Logback's basic architecture is sufficiently generic so as to
    	apply under different circumstances. At present time, logback is
    	divided into three modules, Core, Classic and Access.
    </p>

    <p>
    	The Core module lays the groundwork for the other two modules.
    	The Classic module extends Core. Classic can be assimilated to
    	an improved version of log4j. Logback Classic natively
    	implements the
    	<a href="http://www.slf4j.org">SLF4J API</a>
    	so that you can readily switch back and forth between logback
    	and other logging systems such as log4j or JDK14 Logging. The
    	Access module integrates with Servlet containers to provide
    	HTPP-access log functionality. The Access module will be covered
    	in a separate document.
    </p>
    <p>
    	In this document, we will use the word logback to refer to the
    	logback classic module.
    </p>

    <h2>First Baby Step</h2>

    <p>
    	After you have added the jar files
    	<em>logback-core.jar</em>
    	and
    	<em>logback-classic.jar</em>
    	to your classpath, you can begin experimenting with logback.
    </p>

<div class="source"><em>Example 1.1: Basic template for logging (examples/chapter1/HelloWorld1.java)</em>
package chapter1;

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

public class HelloWorld1 {

  public static void main(String[] args) {

    Logger logger = LoggerFactory.getLogger(HelloWorld1.class);
    logger.debug("Hello world.");

  }
}</div>

		<p>
			The <code>HelloWorld</code> class is defined in the
			<code>chapter1</code> package. It starts by importing the <code>Logger</code>
			and <code>LoggerFactory</code>
			classes as defined in the SLF4J API, more specifically in the <code>org.slf4j</code>
			package.
		</p>


		<p>
			On line 10, the variable named <code>logger</code>
			is assigned a <code>Logger</code>
			instance retreived by invoking the static method <code>getLogger</code>
			in the <code>LoggerFactory</code> class. 
			This logger is named "chapter1/HelloWorld1". The main method proceeds to call its
			<code>debug</code> method with the argument "Hello world." We say that the main
			method contains a logging statement of level debug containing the message “Hello world”.
		</p>

		<p>
			You will note that the above example does not reference any
			logback classes. In most cases, as far as logging is
			concerned, your classes will need to import only SLF4J
			classes. In principle, you will have to import logback
			classes only for configuring logback. Thus, the vast
			majority of your classes will only be cognizant of SLF4J API
			and oblivious to the existence of logback.
		</p>


		<p>
			<b>ceki: compile?</b>
			You can compile and run this class with the command:
		</p>

		<div class="source">java chapter1.HelloWorld1</div>

		<p>
			Suprisingly enough, launching the <code>HelloWorld1</code>
			application will not produce <em>any</em> output. 
			Logback does not posses a default configuration.
			Without a valid configuration, logback will be as silent as a mummy.
		</p>

		<p>
			Logback can report information about its internal state
			using a built-in status system. Important events occuring
			during logback's lifetime can be accessed through a
			<code>StatusManager</code>. For the time being, let us tell logback to print its
			internal state. This is accomplished by a static method in
			the <code>LoggerStatusPrinter</code>
			class.
		</p>

<div class="source"><em>Example 1.2: Printing Logger Status (examples/chapter1/HelloWorld2.java)</em>
package chapter1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
<b>import ch.qos.logback.classic.util.LoggerStatusPrinter;</b>

public class HelloWorld2 {

  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld2.class);
    logger.debug("Hello world.");
    <b>LoggerStatusPrinter.printStatusInDefaultContext();</b>
  }
}</div>


   <p>Running the <code>HelloWorld2</code> application will produce
   the following output:</p>

<div class="source">ERROR in Logger[chapter1.HelloWorld2] - \
No appenders present in context [default] for logger [chapter1.HelloWorld2].</div>


  <!-- =========  CEKI: STOPPED HERE =================== -->

  <p>
  	Logback is complaining that no appenders were configured for the
  	default context. An Appender is a class that can be seen as an
  	output destination. Appenders exist for many different
  	destinations including the console, files, and many more. Users
  	can also easily create their own Appenders for any specific
  	situation.
  </p>

  <p>
  	Configuring logback can be done a different ways. The
  	simplest but less flexible way is by calling the
  	<code>BasicConfigurator</code> class, like in the following code snippet.
  </p>
  <div class="source"><em>Example 1.3: Configuring before logging (examples/chapter1/HelloWorld3.java)</em>
package chapter1;

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

<b>import ch.qos.logback.BasicConfigurator;</b>
import ch.qos.logback.classic.util.LoggerStatusPrinter;

public class HelloWorld3 {

  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld3.class);
    <b>BasicConfigurator.configureDefaultContext();</b>
    logger.debug("Hello world.");
    LoggerStatusPrinter.printStatusInDefaultContext();

  }
}</div>

		<p>
			Let's run the <code>HelloWorld3</code>
			application again. Now, the <code>BasicConfigurator</code>
			will create a simple <code>ConsoleAppender</code>. 
			The logging request will then be propagated to the
			Appender and the console will output the following:
		</p>
<div class="source">0    [main] DEBUG chapter1.HelloWorld3 - Hello world.</div>

		<p>
			This example is very simple. However, actual logging in a larger
			application is not much more complicated. The logging statement
			will barely change. Only the configuration process will be
			different, since you don't need (nor should) configure the
			logging context in each and every class that will require
			logging. As well, the LoggerStatusPrinter will certainly not be
			used after all the logging statements.
		</p>

		<p>	
			These are the three steps that are required to allow full logging in any application.
		</p>

		<ol>
			<li>Configure the logback environment. You can do it using several 
			sophisticated ways. The BasicConfigurator is the simplest but also least flexible.</li>
			<li>In every class where you wish to perform logging, retrieve a Logger 
			instance by invoking the LoggerFactory and passing the current class as the parameter.</li>
			<li>Use this logger instance by invoking its printing methods, namely 
			the debug(), info(), warn() and error() methods. This will produce logging on the 
			configured devices.</li>
		</ol>

		<div class="section">
			<h2>Logger, Appenders and Layouts</h2>
		</div>
		<p>
			Logback has three main components: Loggers,
			Appenders and Layouts. These three types of components work
			together to enable developers to log messages according to
			message type and level, and to control at runtime how these
			messages are formatted and where they are reported.
		</p>
		<p>
			Loggers are defined in the classic module. On the other
			hand, Appenders and Layouts are defined in the core module
			of logback.
		</p>

    <h3>Logger context</h3>

		<p>
			The first and foremost advantage of any logging API over
			plain System.out.println resides in its ability to disable
			certain log statements while allowing others to print
			unhindered. This capability assumes that the logging space,
			that is, the space of all possible logging statements, is
			categorized according to some developer-chosen criteria.
		</p>
			
		<p>
			In logback, Loggers are named entities. Their names are case-sensitive and they follow the
			contextual naming rule:
		</p>
		<div class="definition">
			<div class="deftitle">Named Context</div>
			<p>
				A logger is said to be an ancestor of another logger if
				its name followed by a dot is a prefix of the descendant
				logger name. A logger is said to be a parent of a child
				logger if there are no ancestors between itself and the
				descendant logger.
			</p>
		</div>

		<p>
			For example, the logger named <code>"com.foo"</code>
			is a parent of the logger named <code>"com.foo.Bar"</code>. 
			Similarly, <code>"java"</code>
			is a parent of <code>"java.util"</code> and an ancestor of
			<code>"java.util.Vector"</code>. 
			This naming scheme should be familiar to most developers.
		</p>
		<p>
			The root logger resides at the top of the logger context.
			It is exceptional in a way that is always exists. Like every
			logger, it can be retrieved by its name, like this:
		</p>
		<div class="source">Logger rootLogger = LoggerFactory.getLogger("root");</div>

		<p>
			All other loggers are retrieved with the class static
			LoggerFactory.getLogger method. This method takes the name
			of the desired logger as a parameter. Some of the basic
			methods in the Logger interface are listed below.
		</p>

		<div class="source">package org.slf4j; 
public interface Logger {

  // Printing methods: 
  public void debug(Object message);
  public void info(Object message); 
  public void warn(Object message); 
  public void error(Object message); 
  public void fatal(Object message); 
}</div>

		<p>
			Loggers may be assigned levels. The set of possible levels,
			that is DEBUG, INFO, WARN and ERROR are defined in the
			<em>ch.qos.logback.classic.Level</em> class. The level class cannot
			be sub-classed as a much better approach exist in the form
			of Marker objects.
		</p>

		<p>
			If a given logger is not assigned a level, then it inherits
			one from its closest ancestor with an assigned level. More
			formally:
		</p>

		<div class="definition">
			<div class="deftitle">Level Inheritance</div>
			<p>
				The inherited level for a given logger <em>L</em>, 
				is equal to the first non-null level in the logger context, starting at
				<em>L</em> and proceeding upwards in the context towards the root logger.
			</p>
		</div>
		<p>
			To ensure that all loggers can eventually inherit a level,
			the root logger always has an assigned level.
		</p>
		<p>
			Below are four examples with various assigned level values
			and the resulting inherited levels according to the above
			rule.
		</p>

		<table>
			<tr>
				<th>
					Logger
					<br />
					name
				</th>
				<th>
					Assigned
					<br />
					level
				</th>

				<th>
					Inherited
					<br />
					level
				</th>
			</tr>
			<tr>
				<td>root</td>
				<td>L<sub>root</sub></td>
				<td>L<sub>root</sub></td>
			</tr>
			<tr>
				<td>X</td>
				<td>none</td>
				<td>L<sub>root</sub></td>
			</tr>

			<tr>
				<td>X.Y</td>
				<td>none</td>
				<td>L<sub>root</sub></td>
			</tr>
			<tr>
				<td>X.Y.Z</td>
				<td>none</td>
				<td>L<sub>root</sub></td>
			</tr>
		</table>
		<p>
			In example 1 above, only the root logger is assigned a
			level.
		</p>
		This level value, <code>L<sub>root</sub></code>, is inherited by the other loggers
		<code>X</code>, <code>X.Y</code> and <code>X.Y.Z</code>
		<table>
			<tr>
				<th>
					Logger
					<br />
					name
				</th>
				<th>
					Assigned
					<br />
					level
				</th>

				<th>
					Inherited
					<br />
					level
				</th>
			</tr>
			<tr align="left">
				<td>root</td>
				<td>L<sub>root</sub></td>
				<td>L<sub>root</sub></td>
			</tr>
			<tr align="left">
				<td>X</td>
				<td>L<sub>x</sub></td>
				<td>L<sub>x</sub></td>
			</tr>

			<tr align="left">
				<td>X.Y</td>
				<td>L<sub>xy</sub></td>
				<td>L<sub>xy</sub></td>
			</tr>
			<tr align="left">
				<td>X.Y.Z</td>
				<td>L<sub>xyz</sub></td>
				<td>L<sub>xyz</sub></td>
			</tr>
		</table>

		<p>
			In example 2, all loggers have an assigned level value.
			There is no need for level inheritence.
		</p>

		<table>
			<tr>
				<th>
					Logger
					<br />
					name
				</th>
				<th>
					Assigned
					<br />
					level
				</th>
				<th>
					Inherited
					<br />
					level
				</th>
			</tr>
			<tr align="left">
				<td>root</td>
				<td>L<sub>root</sub></td>
				<td>L<sub>root</sub></td>
			</tr>

			<tr align="left">
				<td>X</td>
				<td>L<sub>x</sub></td>
				<td>L<sub>x</sub></td>
			</tr>
			<tr align="left">
				<td>X.Y</td>
				<td>none</td>
				<td>L<sub>x</sub></td>
			</tr>
			<tr align="left">
				<td>X.Y.Z</td>
				<td>L<sub>xyz</sub></td>
				<td>L<sub>xyz</sub></td>
			</tr>
		</table>
		<p>
			In example 3, the loggers <code>root</code>, <code>X</code>
			and <code>X.Y.Z</code> are assigned the levels <code>L<sub>root</sub></code>,
			<code>L<sub>x</sub></code> and <code>L<sub>xyz</sub></code>
			respectively. The logger <code>X.Y</code>
			inherits its level value from its parent <code>X</code>.
		</p>
		<table>

			<tr>
				<th>
					Logger
					<br />
					name
				</th>
				<th>
					Assigned
					<br />
					level
				</th>
				<th>
					Inherited
					<br />
					level
				</th>
			</tr>
			<tr align="left">
				<td>root</td>
				<td>L<sub>root</sub></td>
				<td>L<sub>root</sub></td>
			</tr>

			<tr align="left">
				<td>X</td>
				<td>L<sub>x</sub></td>
				<td>L<sub>x</sub></td>
			</tr>
			<tr align="left">
				<td>X.Y</td>
				<td>none</td>
				<td>L<sub>x</sub></td>
			</tr>
			<tr align="left">
				<td>X.Y.Z</td>
				<td>none</td>
				<td>L<sub>x</sub></td>
			</tr>
		</table>

		<p>
			In example 4, the loggers <code>root</code> and <code>X</code>
			and are assigned the levels <code>L<sub>root</sub></code> and
			<code>L<sub>x</sub></code> respectively. The loggers <code>X.Y</code> and
			<code>X.Y.Z</code> inherits their level value from their nearest
			parent <code>X</code> having an assigned level.
		</p>

    <h3>Printing methods</h3>
		<p>
			By definition, the printing method determines the level of a
			logging request. For example, if <code>L</code>
			is a logger instance, then the statement <code>L.info("..")</code>
			is a logging request of level INFO.
		</p>
		<p>
			A logging request is said to be <em>enabled</em>
			if its level is higher than or equal to the level of its
			logger. Otherwise, the request is said to be
			<em>disabled</em>. A logger without an assigned level will inherit one from
			the context. This rule is summarized below.
		</p>
		<div class="definition">
			<div class="deftitle">Basic Selection Rule</div>

			<p>
				A log request of level <em>p</em>
				in a logger with (either assigned or inherited,
				whichever is appropriate) level <em>q</em>, is enabled if
				<em>p &gt;= q</em>.
			</p>

		</div>

		<p>
			This rule is at the heart of logback. It assumes
			that levels are ordered. For the standard levels, we have
			<code>DEBUG &lt; INFO &lt; WARN &lt; ERROR</code>.
		</p>
				
		<p>
			In a more graphic way, here is how the selection rule works: in the following
			table, the horizontal header shows the level of the logging request, while the
			vertical header shows the level of the logger.
		</p>
		
		<table>
			<tr>
				<td></td>
				<th>DEBUG</th>
				<th>INFO</th>
				<th>WARN</th>
				<th>ERROR</th>				
			</tr>
			<tr>
				<th>DEBUG</th>
				<td><span class="greenBold">YES</span></td>
				<td><span class="greenBold">YES</span></td>
				<td><span class="greenBold">YES</span></td>
				<td><span class="greenBold">YES</span></td>
			</tr>
			<tr>
				<th>INFO</th>
				<td><span class="redBold">NO</span></td>
				<td><span class="greenBold">YES</span></td>
				<td><span class="greenBold">YES</span></td>
				<td><span class="greenBold">YES</span></td>
			</tr>
			<tr>
				<th>WARN</th>
				<td><span class="redBold">NO</span></td>
				<td><span class="redBold">NO</span></td>
				<td><span class="greenBold">YES</span></td>
				<td><span class="greenBold">YES</span></td>
			</tr>
			<tr>
				<th>ERROR</th>
				<td><span class="redBold">NO</span></td>
				<td><span class="redBold">NO</span></td>
				<td><span class="redBold">NO</span></td>
				<td><span class="greenBold">YES</span></td>
			</tr>		
		</table>
		
		<p>Here is an example of this rule.</p>

		<div class="source">// get a logger instance named "com.foo", with an <span class="blue">INFO</span>level. 
Logger logger = LoggerFactory.getLogger("com.foo");
Logger barlogger = LoggerFactory.getLogger("com.foo.Bar");

// This request is enabled, because <span class="green">WARN</span> &gt;= <span class="blue">INFO</span>
logger.<span class="green">warn</span>("Low fuel level.");

// This request is disabled, because <span class="green">DEBUG</span> &lt; <span class="blue">INFO</span>. 
logger.<span class="green">debug</span>("Starting search for nearest gas station.");

// The logger instance barlogger, named "com.foo.Bar", 
// will inherit its level from the logger named 
// "com.foo" Thus, the following request is enabled 
// because <span class="green">INFO</span> &gt;= <span class="blue">INFO</span>. 
barlogger.<span class="green">info</span>("Located nearest gas station.");

// This request is disabled, because<span class="green">DEBUG</span> &lt; <span class="blue">INFO</span>. 
barlogger.<span class="green">debug</span>("Exiting gas station search");</div>

		<p>
			Calling the <code>getLogger</code>
			method with the same name will always return a reference to
			the exact same logger object.
		</p>

		<p>For example, in</p>
		<div class="source">Logger x = LoggerFactory.getLogger("wombat"); 
Logger y = LoggerFactory.getLogger("wombat");</div>

		<p>
			<code>x</code> and <code>y</code> refer to
			<em>exactly</em> the same logger object.
		</p>

		<p>
			Thus, it is possible to configure a logger and then to
			retrieve the same instance somewhere else in the code
			without passing around references. In fundamental
			contradiction to biological parenthood, where parents always
			preceed their children, logback loggers can be
			created and configured in any order. In particular, a
			"parent" logger will find and link to its descendants even
			if it is instantiated after them.
		</p>
		<p>
			Configuration of the logback environment is typically done
			at application initialization. The preferred way is by
			reading a configuration file. This approach will be
			discussed shortly.
		</p>
		<p>
			Logback makes it easy to name loggers by
			<em>software component</em>. 
			This can be accomplished by statically instantiating a
			logger in each class, with the logger name equal to the
			fully qualified name of the class. This is a useful and
			straightforward method of defining loggers. As the log
			output bears the name of the generating logger, this naming
			strategy makes it easy to identify the origin of a log
			message. However, this is only one possible, albeit common,
			strategy for naming loggers. Logback does not restrict the
			possible set of loggers. The developer is free to name the
			loggers as desired.
		</p>
		<p>
			Nevertheless, naming loggers after the class where they are
			located seems to be the best strategy known so far.
		</p>

    <h3>Appenders and Layouts</h3>

		<p>
			The ability to selectively enable or disable logging
			requests based on their logger is only part of the picture.
			Logback allows logging requests to print to multiple
			destinations. In logback speak, an output destination is
			called an appender. Currently, appenders exist for the
			console, files, remote socket servers, JMS, and remote UNIX
			Syslog daemons. It is also possible to log asynchronously.
		</p>

		<p>More than one appender can be attached to a logger.</p>
		<p>
			The addAppender method adds an appender to a given logger.
			Each enabled logging request for a given logger will be
			forwarded to all the appenders in that logger as well as the
			appenders higher in the context. In other words, appenders
			are inherited additively from the logger context. For
			example, if a console appender is added to the root logger,
			then all enabled logging requests will at least print on the
			console. If in addition a file appender is added to a
			logger, say <em>L</em>, then enabled logging requests for
			<em>L</em> and <em>L</em>'s children will print on a file and on the console. 
			It is possible to override this default behavior so that appender
			accumulation is no longer additive by setting the additivity
			flag to false.
		</p>

		<p>
			The rules governing appender additivity are summarized
			below.
		</p>
		<div class="definition">

			<div class="deftitle">Appender Additivity</div>

			<p>
				The output of a log statement of logger <em>L</em>
				will go to all the appenders in <em>L</em>
				and its ancestors. This is the meaning of the term
				"appender additivity".
			</p>

			<p>
				However, if an ancestor of logger <em>L</em>, say
				<em>P</em>, has the additivity flag set to false, then
				<em>L</em>'s output will be directed to all the appenders in
				<em>L</em> and it's ancestors upto and including
				<em>P</em> but not the appenders in any of the ancestors of
				<em>P</em>.
			</p>

			<p>
				Loggers have their additivity flag set to true by
				default.
			</p>

		</div>
		The table below shows an example:

		<table class="bodyTable">
			<tr>
				<th>Logger Name</th>
				<th>Added Appenders</th>
				<th>Additivity Flag</th>
				<th>Output Targets</th>
				<th>Comment</th>
			</tr>
			<tr>
				<td>root</td>
				<td>A1</td>
				<td>not applicable</td>
				<td>A1</td>
				<td>
					The root logger is anonymous but can be accessed
					with the Logger.getRootLogger() method. There is no
					default appender attached to root.
				</td>
			</tr>
			<tr>
				<td>x</td>
				<td>A-x1, A-x2</td>
				<td>true</td>
				<td>A1, A-x1, A-x2</td>
				<td>Appenders of "x" and root.</td>
			</tr>
			<tr>
				<td>x.y</td>
				<td>none</td>
				<td>true</td>
				<td>A1, A-x1, A-x2</td>
				<td>Appenders of "x" and root.</td>
			</tr>
			<tr>
				<td>x.y.z</td>
				<td>A-xyz1</td>
				<td>true</td>
				<td>A1, A-x1, A-x2, A-xyz1</td>
				<td>Appenders in "x.y.z", "x" and root.</td>
			</tr>
			<tr>
				<td>security</td>
				<td>A-sec</td>
				<td class="blue">false</td>
				<td>A-sec</td>
				<td>
					No appender accumulation since the additivity flag
					is set to
					<code>false</code>.
				</td>
			</tr>
			<tr>
				<td>security.access</td>
				<td>none</td>
				<td>true</td>
				<td>A-sec</td>
				<td>
					Only appenders of "security" because the additivity
					flag in "security" is set to
					<code>false</code>.
				</td>
			</tr>
		</table>


		<p>
			More often than not, users wish to customize not only the
			output destination but also the output format. This is
			accomplished by associating a <em>layout</em>
			with an appender. The layout is responsible for formatting
			the logging request according to the user's wishes, whereas
			an appender takes care of sending the formatted output to
			its destination. The PatternLayout, part of the standard
			logback distribution, lets the user specify the output
			format according to conversion patterns similar to the C
			language <code>printf</code>
			function.
		</p>

		<p>
			For example, the PatternLayout with the conversion pattern
			"%r [%t] %-5p %c - %m%n" will output something akin to:
		</p>

		<div class="source">176 [main] INFO org.foo.Bar - Located nearest gas station.</div>

		<p>
			The first field is the number of milliseconds elapsed since
			the start of the program. The second field is the thread
			making the log request. The third field is the level of the
			log statement. The fourth field is the name of the logger
			associated with the log request. The text after the '-' is
			the message of the statement.
		</p>

		<h4>More sophitsicated ways of logging</h4>

		<p>
			If you are a SLF4J user (if not, you should be...), you'll
			notice that the methods used to request logging do not only
			take a String as a parameter. Some methods allow more
			sophisticated parameter configurations.
		</p>

		<p>
			For some Logger <code>logger</code>, writing,
		</p>

		<div class="source">logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));</div>

		<p>
			incurs the cost of constructing the message parameter, that
			is converting both integer <code>i</code> and <code>entry[i]</code>
			to a String, and concatenating intermediate strings. This,
			regardless of whether the message will be logged or not.
		</p>

		<p>
			One possible way to avoid the cost of parameter construction
			is by surrounding the log statement with a test. Here is an
			example.
		</p>

		<div class="source">if(logger.isDebugEnabled()) { 
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}</div>


		<p>
			This way you will not incur the cost of parameter
			construction if debugging is disabled for <code>logger</code>. 
			On the other hand, if the logger is enabled for the DEBUG
			level, you will incur the cost of evaluating whether the
			logger is enabled or not, twice: once in <code>debugEnabled</code>
			and once in <code>debug</code>. 
			This is an insignificant overhead because evaluating a
			logger takes less than 1% of the time it takes to actually
			log a statement.
		</p>

		<h4>Better alternative based on format messages</h4>

		<p>
			There exists a very convenient alternative based on message
			formats. Assuming <code>entry</code> is an object, you can write:
		</p>


		<div class="source">Object entry = new SomeObject(); logger.debug("The entry is {}.", entry);</div>

		<p>
			After evaluting whether to log or not, and only if the
			decision is affirmative, will the logger implementation
			format the message and replace the '{}' pair with the string
			value of <code>entry</code>. 
			In other words, tis form does not incur the cost of
			parameter construction in case the log statement is
			disabled.
		</p>


		<p>
			The following two lines will yield the exact same output.
			However, the second form will outperform the first form by a
			factor of at least 30, in case of a <em>disabled</em>
			logging statement.
		</p>

		<div class="source">logger.debug("The new entry is "+entry+".");
logger.debug("The new entry is {}.", entry);</div>


		<p>
			A two argument variant is also availalble. For example, you
			can write:
		</p>

		<div class="source">logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);</div>

		<p>
			If three or more arguments need to be passed, an <code>Object[]</code>
			variant is also availalble. For example, you can write:
		</p>


		<div class="source">logger.debug("Value {} was inserted between {} and {}.", new Object[] {newVal, below, above});</div>

    <h3>Configuration</h3>

		<p>
			Inserting log requests into the application code requires 
			a fair amount of planning and effort. Observation shows that 
			approximately 4 percent of code is dedicated to logging. Consequently, 
			even moderately sized applications will have thousands of logging 
			statements embedded within their code. Given their number, it becomes 
			imperative to manage these log statements without the need to 
			modify them manually.
		</p>
		<p>
			The logback environment is fully configurable programmatically. 
			However, it is far more flexible to configure logback using 
			configuration files. Currently, configuration files must be written in 
			XML format.
		</p>
		<p>
			Let us give a taste of how this is done with the help of an 
			imaginary application MyApp that uses logback. 
		</p>
<div class="source"><em>Example 1.4: Basic configuration (examples/chapter1/MyApp.java)</em>
package chapter1;

// Import SLF4J classes.
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;

import ch.qos.logback.BasicConfigurator;

public class MyApp {

  public static void main(String[] args) {
	
    // Set up a simple configuration that logs on the console.
    BasicConfigurator.configureDefaultContext();

	Logger logger = LoggerFactory.getLogger(MyApp.class);
	
    logger.info("Entering application.");
    Bar bar = new Bar();
    bar.doIt();
    logger.info("Exiting application.");
  }
}</div>
		<p>
			This class begins by defining a static logger instance variable 
			with the name MyApp. It then uses the Bar class, defined as shown below:
		</p>
<div class="source">class Bar {

  Logger logger = LoggerFactory.getLogger(Bar.class);	
	
  public void doIt() {
    logger.debug("doing my job");
  }
}</div>
		<p>
			The invocation of the BasicConfigurator create, as we have seen, 
			a simple yet sufficient logback setup. By default, 
			the root Logger is assigned to Level.DEBUG.
		</p>
		<p>The BasicConfigurator has to be called only once. Any other class that wishes to
		issue log statements only has to import the <em>Logger class</em> and use it.</p>
		<p>
			The output of MyApp is:
		</p>
<div class="source">0    [main] INFO  ch.qos.logback.classic.examples.MyApp - Entering application.
0    [main] DEBUG ch.qos.logback.classic.examples.Bar - doing my job
0    [main] INFO  ch.qos.logback.classic.examples.MyApp - Exiting application.</div>
		
	<p>Let's configure logback to do exactly the same output, this time 
	with an XML configuration file.</p>
	
<div class="source">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;

&lt;configuration&gt;

  &lt;appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender"&gt;
    &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
      &lt;param name="pattern"
        value="%-4relative [%thread] %-5level %class - %msg%n" /&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;

  &lt;root&gt;
    &lt;level value="debug" /&gt;
    &lt;appender-ref ref="STDOUT" /&gt;
  &lt;/root&gt;
&lt;/configuration&gt;</div>
	
	<p>We first created an Appender, named <em>STDOUT</em> that is of ConsoleAppender tye. Its layout
	is managed by a PatternLayout, that uses the value of the "pattern" parameter to generate 
	the logging statement. We then configured the root logger, set its level to DEBUG, 
	and linked the newly configured ConsoleAppender to the root logger.</p>
	<p>Note that we've set the root logger level explicitly. Since root logger have a DEBUG level
	by default we could have omitted this.</p>
	
	<p>To run this examle, use this command:</p>
	
<div class="source">java MyApp sample-config-1.xml</div>

	<p>The console output will be exactly the same as before. However, this time, we didn't need
	to import and call the BasicConfigurator class, as you can see in the following code section: 
	</p>
<div class="source"><em>Example 1.5: Logback configuration from file (examples/chapter1/MyAppWithConfigFile.java)</em>
package chapter1;

//Import SLF4J classes.
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
<b>import ch.qos.logback.classic.joran.JoranConfigurator;</b>

public class MyAppWithConfigFile {

  public static void main(String[] args) throws Exception {
    Logger logger = (Logger) LoggerFactory.getLogger(MyAppWithConfigFile.class);
    
    JoranConfigurator configurator = new JoranConfigurator();
    configurator.setContext(logger.getLoggerContext());
    configurator.doConfigure(args[0]);

    logger.info("Entering application.");
    Bar bar = new Bar();
    bar.doIt();
    logger.info("Exiting application.");
  }
}</div>	
	<p>
	We used the JoranConfigurator class to parse the configuration file we just created.
	Joran is a XML interpreter, similar to the commons-digester API, but offering several
	small advantages over commons-digester. Here, it parses the xml file and runs actions depending
	on the tags it finds.
	</p>
	
	<p>Logging to the console is a rather simple example. Let's now configure logback
	so that it logs to the console, but also to a custom file.</p>

<div class="source">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;

&lt;configuration&gt;

  &lt;appender name="STDOUT"
      class="ch.qos.logback.core.ConsoleAppender"&gt;
    &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
      &lt;param name="pattern"
        value="%-4relative [%thread] %-5level %class - %msg%n" /&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;

  &lt;appender name="FILE"
      class="ch.qos.logback.core.FileAppender"&gt;
    &lt;layout class="ch.qos.logback.classic.PatternLayout"&gt;
      &lt;param name="pattern"
        value="%-4relative [%thread] %-5level %class - %msg%n" /&gt;
    &lt;/layout&gt;
    &lt;param name="File"
      value="sample-log.txt" /&gt;
  &lt;/appender&gt;

  &lt;root&gt;
    &lt;level value="debug" /&gt;
    &lt;appender-ref ref="STDOUT" /&gt;
    &lt;appender-ref ref="FILE" /&gt;
  &lt;/root&gt;
&lt;/configuration&gt;</div>
	
	<p>Now, all the logging statements are directed to the console and to a file named <em>sample-log.txt</em>.
	As you can see, the configuration needed to add an Appender is very small. The param element, in either
	Appender configuration, reads the <em>name</em> attribute and assigns its value to the corresponding attribute
	in the specified java class.
	</p>
	
	<p>Suppose that we do not want to see the DEBUG level statements in the chapter1 package anymore.
	This is done by adding a <em>logger</em> element, with a nested element specifying its level value.</p>
	
	<p>This done, the output is modified to show only statements of level INFO and higher.</p>
	
<div class="source">0    [main] INFO  chapter1.MyAppWithConfigFile - Entering application.
0    [main] INFO  chapter1.MyAppWithConfigFile - Exiting application.</div>

	<p>Note that to obtain these different logging behaviors we did not need to recompile code. 
	We could just as easily have logged to a UNIX Syslog daemon, redirected all chapter1 output 
	to an NT Event logger, or forwarded logging events to a remote logback server, 
	which would log according to local server policy, for example by forwarding the log event 
	to a second logback server.</p>
	
	</body>
</document>
