[LOGBack-dev] svn commit: r361 - logback/classic/trunk/src/site/xdocTemplates
noreply.seb at qos.ch
noreply.seb at qos.ch
Thu Jul 27 18:52:41 CEST 2006
Author: seb
Date: Thu Jul 27 18:52:41 2006
New Revision: 361
Added:
logback/classic/trunk/src/site/xdocTemplates/shortIntro.xml
Modified:
logback/classic/trunk/src/site/xdocTemplates/documentation.xml
Log:
first commit of a short introduction to logback classic
Modified: logback/classic/trunk/src/site/xdocTemplates/documentation.xml
==============================================================================
--- logback/classic/trunk/src/site/xdocTemplates/documentation.xml (original)
+++ logback/classic/trunk/src/site/xdocTemplates/documentation.xml Thu Jul 27 18:52:41 2006
@@ -12,16 +12,20 @@
<h2>Documentation</h2>
</div>
+ <p>Here are some documents about ${pom.name}.</p>
<p>
- Here are some documents about ${pom.name}.
- </p>
- <p>
- This section is pretty light at the moment, but will grow with the developping
- of ${pom.name}.
+ This section is pretty light at the moment, but will grow
+ with the developping of ${pom.name}.
</p>
<ul>
<li>
+ <a href="shortIntro.html">
+ A Short Introduction to logback classic
+ </a>
+
+ </li>
+ <li>
<a href="apidocs/index.html">${pom.name} Javadoc</a>
</li>
</ul>
Added: logback/classic/trunk/src/site/xdocTemplates/shortIntro.xml
==============================================================================
--- (empty file)
+++ logback/classic/trunk/src/site/xdocTemplates/shortIntro.xml Thu Jul 27 18:52:41 2006
@@ -0,0 +1,924 @@
+<document>
+ <body>
+ <div class="section">
+ <h2>Short introduction</h2>
+ </div>
+ <div class="author">
+ Authors: Ceki Gülcü, Sébastien Pennec
+ </div>
+ <p>
+ Copyright © 2000-2006, The Apache Software Foundation.
+ Licensed under the Apache License, Version 2.0. The present
+ short manual also borrows some text from "The complete log4j
+ manual", which contains more detailed and up to date
+ information, by Ceki Gülcü.
+ </p>
+
+ <div class="section">
+ <h2>Introduction</h2>
+ </div>
+ <p>
+ Logging is a low-tech way of debugging your code. It might
+ also be the only way, when debuggers are not available or
+ applicable. Logback classic can help you insert logging
+ functionalities in your code without polluting its
+ readability with useless statements, or diminishing its
+ performance.
+ </p>
+ <p>
+ Logback is intended as a successor to the popular log4j
+ project. It was also designed by Ceki Gülcü, the
+ founder of the log4j project. It builds upon experience
+ gained in building industrial-strength logging systems going
+ back as far as 1999.
+ </p>
+ <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 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. Note
+ that you can easily build your own modules on top of the
+ Core module.
+ </p>
+ <p>
+ Before rushing to install and configure logback classic on
+ your own application, here is a presentation of how things
+ work.
+ </p>
+
+ <div class="section">
+ <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 the core module, it
+ can be assimilated to an improved version of log4j.
+ Logback Classic natively implements the SLF4J API so
+ that you can readily switch back and forth between
+ logback and other logging systems such as log4j or JDK14
+ Logging. The Access module also extends the core
+ functionnalities and integrates with Servlet containers
+ to provide HTPP-access log functionality.
+ </p>
+ <p>
+ Note that you can easily build your own modules on top
+ of the Core module.
+ </p>
+ </div>
+
+ <div class="section">
+ <h2>Logger, Appenders and Layouts</h2>
+ </div>
+ <p>
+ Logback classic 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>
+ The Loggers are defined in the classic module. On the other
+ hand, Appenders and Layouts are defined in the core module
+ of logback.
+ </p>
+
+ <div class="section">
+ <h3>Logger hierarchy</h3>
+ </div>
+ <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.
+ Loggers are named entities.
+ </p>
+ <p>
+ Logger names are case-sensitive and they follow the
+ hierarchical naming rule:
+ </p>
+ <div class="definition">
+ <div class="deftitle">Named Hierarchy</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 hierarchy.
+ It is exceptional in two ways:
+ </p>
+ <ol>
+ <li>it always exists,</li>
+ <li>it cannot be retrieved by name.</li>
+ </ol>
+ 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.
+ <div class="source">
+ <p>package org.slf4j;</p>
+
+ <p>public interface Logger {</p>
+ <p>
+ // Creation and retrieval method:
+ <br />
+ public static Logger getLogger(String name);
+ <br />
+ </p>
+ <p>
+ // printing methods:
+ <br />
+ public void debug(Object message);
+ <br />
+ public void info(Object message);
+ <br />
+ public void warn(Object message);
+ <br />
+ public void error(Object message);
+ <br />
+ public void fatal(Object message);
+ <br />
+ </p>
+ <p>}</p>
+ </div>
+ <p>
+ Loggers may be assigned levels. The set of possible levels,
+ that is DEBUG, INFO, WARN, ERROR and FATAL are defined in
+ the org.apache.log4j.Level class. Although we do not
+ encourage you to do so, you may define your own levels by
+ sub-classing the Level class. A perhaps better approach will
+ be explained later on.
+ </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 C, is equal to
+ the first non-null level in the logger hierarchy,
+ starting at C and proceeding upwards in the hierarchy
+ 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 class="exampleTable">
+ <tr>
+ <th>
+ Logger
+ <br />
+ name
+ </th>
+ <th>
+ Assigned
+ <br />
+ level
+ </th>
+
+ <th>
+ Inherited
+ <br />
+ level
+ </th>
+ </tr>
+ <tr>
+ <td>root</td>
+ <td>Proot</td>
+ <td>Proot</td>
+ </tr>
+ <tr>
+ <td>X</td>
+ <td>none</td>
+ <td>Proot</td>
+ </tr>
+
+ <tr>
+ <td>X.Y</td>
+ <td>none</td>
+ <td>Proot</td>
+ </tr>
+ <tr>
+ <td>X.Y.Z</td>
+ <td>none</td>
+ <td>Proot</td>
+ </tr>
+ </table>
+ <p>
+ In example 1 above, only the root logger is assigned a
+ level.
+ </p>
+ This level value,
+ <code>Proot</code>
+ , is inherited by the other loggers
+ <code>X</code>
+ ,
+ <code>X.Y</code>
+ and
+ <code>X.Y.Z</code>
+ <table class="exampleTable">
+ <tr>
+ <th>
+ Logger
+ <br />
+ name
+ </th>
+ <th>
+ Assigned
+ <br />
+ level
+ </th>
+
+ <th>
+ Inherited
+ <br />
+ level
+ </th>
+ </tr>
+ <tr align="left">
+ <td>root</td>
+ <td>Proot</td>
+ <td>Proot</td>
+ </tr>
+ <tr align="left">
+ <td>X</td>
+ <td>Px</td>
+ <td>Px</td>
+ </tr>
+
+ <tr align="left">
+ <td>X.Y</td>
+ <td>Pxy</td>
+ <td>Pxy</td>
+ </tr>
+ <tr align="left">
+ <td>X.Y.Z</td>
+ <td>Pxyz</td>
+ <td>Pxyz</td>
+ </tr>
+ </table>
+
+ <p>
+ In example 2, all loggers have an assigned level value.
+ There is no need for level inheritence.
+ </p>
+
+ <table class="exampleTable">
+ <tr>
+ <th>
+ Logger
+ <br />
+ name
+ </th>
+ <th>
+ Assigned
+ <br />
+ level
+ </th>
+ <th>
+ Inherited
+ <br />
+ level
+ </th>
+ </tr>
+ <tr align="left">
+ <td>root</td>
+ <td>Proot</td>
+ <td>Proot</td>
+ </tr>
+
+ <tr align="left">
+ <td>X</td>
+ <td>Px</td>
+ <td>Px</td>
+ </tr>
+ <tr align="left">
+ <td>X.Y</td>
+ <td>none</td>
+ <td>Px</td>
+ </tr>
+ <tr align="left">
+ <td>X.Y.Z</td>
+ <td>Pxyz</td>
+ <td>Pxyz</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>Proot</code>
+ ,
+ <code>Px</code>
+ and
+ <code>Pxyz</code>
+ respectively. The logger
+ <code>X.Y</code>
+ inherits its level value from its parent
+ <code>X</code>
+ .
+ </p>
+ <table class="exampleTable">
+
+ <tr>
+ <th>
+ Logger
+ <br />
+ name
+ </th>
+ <th>
+ Assigned
+ <br />
+ level
+ </th>
+ <th>
+ Inherited
+ <br />
+ level
+ </th>
+ </tr>
+ <tr align="left">
+ <td>root</td>
+ <td>Proot</td>
+ <td>Proot</td>
+ </tr>
+
+ <tr align="left">
+ <td>X</td>
+ <td>Px</td>
+ <td>Px</td>
+ </tr>
+ <tr align="left">
+ <td>X.Y</td>
+ <td>none</td>
+ <td>Px</td>
+ </tr>
+ <tr align="left">
+ <td>X.Y.Z</td>
+ <td>none</td>
+ <td>Px</td>
+ </tr>
+ </table>
+
+ <p>
+ In example 4, the loggers
+ <code>root</code>
+ and
+ <code>X</code>
+ and are assigned the levels
+ <code>Proot</code>
+ and
+ <code>Px</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>
+
+ <p>
+ In a more graphic way, here is how you the logger hierarchy
+ works:
+ </p>
+
+
+ <p>
+ By definition, the printing method determines the level of a
+ logging request. For example, if
+ <code>c</code>
+ is a logger instance, then the statement
+ <code>c.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 hierarchy. 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 >= q</em>
+ .
+ </p>
+
+ </div>
+
+ <p>
+ This rule is at the heart of logback classic. It assumes
+ that levels are ordered. For the standard levels, we have
+ <code>DEBUG < INFO < WARN < ERROR</code>
+ .
+ </p>
+ <p>Here is an example of this rule.</p>
+
+ <div class="source">
+ <p>
+ // get a logger instance named "com.foo", with an
+ <span class="blue">INFO</span>
+ level.
+ <br />
+ Logger logger = LoggerFactory.getLogger("com.foo");
+ <br />
+ </p>
+ <p>
+ Logger barlogger =
+ LoggerFactory.getLogger("com.foo.Bar");
+ <br />
+ </p>
+ <p>
+ // This request is enabled, because
+ <span class="green">WARN</span>
+ >=
+ <span class="blue">INFO</span>
+ .
+ <br />
+ logger.
+ <span class="green">warn</span>
+ ("Low fuel level.");
+ <br />
+ </p>
+ <p>
+ // This request is disabled, because
+ <span class="green">DEBUG</span>
+ <
+ <span class="blue">INFO</span>
+ .
+ <br />
+ logger.
+ <span class="green">debug</span>
+ ("Starting search for nearest gas station.");
+ <br />
+ </p>
+ <p>
+ // The logger instance barlogger, named "com.foo.Bar",
+ <br />
+ // will inherit its level from the logger named
+ <br />
+ // "com.foo" Thus, the following request is enabled
+ <br />
+ // because
+ <span class="green">INFO</span>
+ >=
+ <span class="blue">INFO</span>
+ .
+ <br />
+ barlogger.
+ <span class="green">info</span>
+ ("Located nearest gas station.");
+ <br />
+ </p>
+ <p>
+ // This request is disabled, because
+ <span class="green">DEBUG</span>
+ <
+ <span class="blue">INFO</span>
+ .
+ <br />
+ barlogger.
+ <span class="green">debug</span>
+ ("Exiting gas station search");
+ <br />
+ </p>
+ </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");
+ <br />
+ Logger y = LoggerFactory.getLogger("wombat");
+ </div>
+ <code>x</code>
+ and
+ <code>y</code>
+ refer to
+ <em>exactly</em>
+ the same logger object.
+
+
+ <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 classic 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>
+
+ <div class="section">
+ <h3>Appenders and Layouts</h3>
+ </div>
+ <p>
+ The ability to selectively enable or disable logging
+ requests based on their logger is only part of the picture.
+ Log4j allows logging requests to print to multiple
+ destinations. In log4j speak, an output destination is
+ called an appender. Currently, appenders exist for the
+ console, files, GUI components, remote socket servers, JMS,
+ NT Event Loggers, 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 hierarchy. In other words, appenders
+ are inherited additively from the logger hierarchy. 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 C, then enabled logging requests for C and C'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>C</em>
+ will go to all the appenders in
+ <em>C</em>
+ and its ancestors. This is the meaning of the term
+ "appender additivity".
+ </p>
+ <p>
+ However, if an ancestor of logger
+ <em>C</em>
+ , say
+ <em>P</em>
+ , has the additivity flag set to false, then
+ <em>C</em>
+ 's output will be directed to all the appenders in
+ <em>C</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
+ log4j 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>
+ <p>
+ Just as importantly, log4j will render the content of the
+ log message according to user specified criteria. For
+ example, if you frequently need to log
+ <code>Oranges</code>
+ , an object type used in your current project, then you can
+ register an
+ <code>OrangeRenderer</code>
+ that will be invoked whenever an orange needs to be logged.
+ </p>
+ <p>
+ Object rendering follows the class hierarchy. For example,
+ assuming oranges are fruits, if you register an
+ <code>FruitRenderer</code>
+ , all fruits including oranges will be rendered by the
+ <code>FruitRenderer</code>
+ , unless of course you registered an orange specific
+ <code>OrangeRenderer</code>
+ .
+ </p>
+ <p>
+ Object renderers have to implement the ObjectRenderer
+ interface.
+ </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()) {
+ <br />
+ logger.debug("Entry number: " + i + " is " +
+ String.valueOf(entry[i]));
+ <br />
+ }
+ </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();
+ <br />
+ 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+".");
+ <br />
+ 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>
+
+
+
+
+
+
+ </body>
+</document>
More information about the logback-dev
mailing list