| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| |
| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head> |
| <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> |
| <title>SLF4J Manual</title> |
| <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" /> |
| <link rel="stylesheet" type="text/css" href="css/prettify.css" /> |
| </head> |
| <body onload="prettyPrint(); decorate();"> |
| <script type="text/javascript">prefix='';</script> |
| <script type="text/javascript" src="js/prettify.js"></script> |
| <script type="text/javascript" src="js/jquery-min.js"></script> |
| <script type="text/javascript" src="js/decorator.js"></script> |
| <script type="text/javascript" src="templates/header.js"></script> |
| <div id="left"> |
| <script type="text/javascript" src="templates/left.js"></script> |
| </div> |
| <div id="content"> |
| |
| |
| <h2>SLF4J user manual</h2> |
| |
| <p>The Simple Logging Facade for Java (SLF4J) serves as a simple |
| facade or abstraction for various logging frameworks, such as |
| java.util.logging, logback and log4j. SLF4J allows the end-user to |
| plug in the desired logging framework at <em>deployment</em> time. |
| Note that SLF4J-enabling your library/application implies the |
| addition of only a single mandatory dependency, namely |
| <em>slf4j-api-${project.version}.jar</em>.</p> |
| |
| <p><span class="label">since 1.6.0</span> If no binding is found on the |
| class path, then SLF4J will default to a no-operation |
| implementation. |
| </p> |
| |
| <p><span class="label">since 1.7.0</span> Printing methods in the |
| <a href="apidocs/org/slf4j/Logger.html"><code>Logger</code></a> |
| interface now offer variants accepting <a |
| href="http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html">varargs</a> |
| instead of <code>Object[]</code>. This change implies that SLF4J |
| requires JDK 1.5 or later. Under the hood the Java compiler |
| transforms the varargs part in methods into |
| <code>Object[]</code>. Thus, the Logger interface generated by the |
| compiler is indistinguishable in 1.7.x from its 1.6.x |
| counterpart. It follows that SLF4J version 1.7.x is totally 100% |
| no-ifs-or-buts compatible with SLF4J version 1.6.x. |
| </p> |
| |
| <p><span class="label">since 1.7.5</span> Significant improvement |
| in logger retrieval times. Given the extent of the improvement, |
| users are highly encouraged to migrate to SLF4J 1.7.5 or later. |
| </p> |
| |
| <p><span class="label">since 1.7.9</span> By setting the |
| <code>slf4j.detectLoggerNameMismatch</code> system property to |
| true, SLF4J can automatically <a |
| href="codes.html#loggerNameMismatch">spot incorrectly named |
| loggers</a>. |
| </p> |
| |
| |
| <h3 class="doAnchor" name="hello_world">Hello World</h3> |
| |
| <p>As customary in programming tradition, here is an example |
| illustrating the simplest way to output "Hello world" using SLF4J. |
| It begins by getting a logger with the name "HelloWorld". This |
| logger is in turn used to log the message "Hello World". |
| </p> |
| |
| <pre class="prettyprint source">import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public class HelloWorld { |
| public static void main(String[] args) { |
| Logger logger = LoggerFactory.getLogger(HelloWorld.class); |
| logger.info("Hello World"); |
| } |
| }</pre> |
| |
| <p>To run this example, you first need to <a |
| href="download.html">download the slf4j distribution</a>, and |
| then to unpack it. Once that is done, add the file |
| <em>slf4j-api-${project.version}.jar</em> to your class path.</p> |
| |
| <p>Compiling and running <em>HelloWorld</em> will result in the |
| following output being printed on the console.</p> |
| |
| <pre>SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". |
| SLF4J: Defaulting to no-operation (NOP) logger implementation |
| SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.</pre> |
| |
| <p>This warning is printed because no slf4j binding could be |
| found on your class path.</p> |
| |
| <p>The warning will disappear as soon as you add a <a |
| href="#swapping">binding</a> to your class path. Assuming you add |
| <em>slf4j-simple-${project.version}.jar</em> so that your class |
| path contains:</p> |
| |
| <ul> |
| <li>slf4j-api-${project.version}.jar</li> |
| <li>slf4j-simple-${project.version}.jar</li> |
| </ul> |
| |
| <p>Compiling and running <em>HelloWorld</em> will now result in |
| the following output on the console.</p> |
| |
| <pre class="output">0 [main] INFO HelloWorld - Hello World</pre> |
| |
| <h3 class="doAnchor" name="typical_usage">Typical usage |
| pattern</h3> |
| |
| <p>The sample code below illustrates the typical usage pattern |
| for SLF4J. Note the use of {}-placeholders on line 15. See the |
| question <a href="faq.html#logging_performance">"What is the |
| fastest way of logging?"</a> in the FAQ for more details. |
| </p> |
| |
| <p></p> |
| |
| <pre class="prettyprint source"> 1: <b>import org.slf4j.Logger;</b> |
| 2: <b>import org.slf4j.LoggerFactory;</b> |
| 3: |
| 4: public class Wombat { |
| 5: |
| 6: <b>final Logger logger = LoggerFactory.getLogger(Wombat.class);</b> |
| 7: Integer t; |
| 8: Integer oldT; |
| 9: |
| 10: public void setTemperature(Integer temperature) { |
| 11: |
| 12: oldT = t; |
| 13: t = temperature; |
| 14: |
| 15: <b>logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);</b> |
| 16: |
| 17: if(temperature.intValue() > 50) { |
| 18: <b>logger.info("Temperature has risen above 50 degrees.");</b> |
| 19: } |
| 20: } |
| 21: } </pre> |
| |
| |
| |
| <h3 class="doAnchor" name="swapping">Binding with a logging |
| framework at deployment time</h3> |
| |
| <p>As mentioned previously, SLF4J supports various logging |
| frameworks. The SLF4J distribution ships with several jar files |
| referred to as "SLF4J bindings", with each binding corresponding |
| to a supported framework. </p> |
| |
| <dl> |
| |
| <dt><em>slf4j-log4j12-${project.version}.jar</em> |
| </dt> |
| <dd>Binding for <a |
| href="http://logging.apache.org/log4j/1.2/index.html">log4j |
| version 1.2</a>, a widely used logging framework. You also |
| need to place <em>log4j.jar</em> on your class path.<p/></dd> |
| |
| <dt><em>slf4j-jdk14-${project.version}.jar</em> </dt> |
| <dd>Binding for java.util.logging, also referred to as JDK 1.4 |
| logging <p/></dd> |
| |
| <dt><em>slf4j-nop-${project.version}.jar</em></dt> |
| <dd>Binding for <a |
| href="http://www.slf4j.org/api/org/slf4j/helpers/NOPLogger.html">NOP</a>, |
| silently discarding all logging.<p/></dd> |
| |
| <dt><em>slf4j-simple-${project.version}.jar</em></dt> |
| <dd>Binding for <a |
| href="http://www.slf4j.org/apidocs/org/slf4j/impl/SimpleLogger.html">Simple |
| </a> implementation, which outputs all events to |
| System.err. Only messages of level INFO and higher are |
| printed. This binding may be useful in the context of small |
| applications.<p/></dd> |
| |
| <dt><em>slf4j-jcl-${project.version}.jar</em></dt> |
| |
| <dd>Binding for <a |
| href="http://commons.apache.org/logging/">Jakarta Commons |
| Logging</a>. This binding will delegate all SLF4J logging to |
| JCL.<p/> |
| </dd> |
| |
| <dt><em>logback-classic-${logback.version}.jar (requires logback-core-${logback.version}.jar)</em></dt> |
| |
| <dd><span class="label notice">Native implementation</span> There are also |
| SLF4J bindings external to the SLF4J project, e.g. <a |
| href="http://logback.qos.ch/">logback</a> which implements |
| SLF4J natively. Logback's |
| <a href="http://logback.qos.ch/apidocs/ch/qos/logback/classic/Logger.html"> |
| <code>ch.qos.logback.classic.Logger</code></a> class is a |
| direct implementation of SLF4J's <a |
| href="http://www.slf4j.org/apidocs/org/slf4j/Logger.html"> |
| <code>org.slf4j.Logger</code></a> interface. Thus, using SLF4J |
| in conjunction with logback involves strictly zero memory and |
| computational overhead. |
| |
| </dd> |
| </dl> |
| |
| <p> |
| </p> |
| |
| |
| <p>To switch logging frameworks, just replace slf4j bindings on |
| your class path. For example, to switch from java.util.logging |
| to log4j, just replace slf4j-jdk14-${project.version}.jar with |
| slf4j-log4j12-${project.version}.jar. |
| </p> |
| |
| <p>SLF4J does not rely on any special class loader machinery. In |
| fact, each SLF4J binding is hardwired <em>at compile time</em> |
| to use one and only one specific logging framework. For |
| example, the slf4j-log4j12-${project.version}.jar binding is |
| bound at compile time to use log4j. In your code, in addition |
| to <em>slf4j-api-${project.version}.jar</em>, you simply drop |
| <b>one and only one</b> binding of your choice onto the |
| appropriate class path location. Do not place more than one |
| binding on your class path. Here is a graphical illustration of |
| the general idea. |
| </p> |
| |
| <p><a href="images/concrete-bindings.png"> |
| <img border="1" src="images/concrete-bindings.png" alt="click to enlarge" width="800"/> |
| </a></p> |
| |
| <p>The SLF4J interfaces and their various adapters are extremely |
| simple. Most developers familiar with the Java language should |
| be able to read and fully understand the code in less than one |
| hour. No knowledge of class loaders is necessary as SLF4J does |
| not make use nor does it directly access any class loaders. As a |
| consequence, SLF4J suffers from none of the class loader |
| problems or memory leaks observed with Jakarta Commons Logging |
| (JCL). |
| </p> |
| |
| <p>Given the simplicity of the SLF4J interfaces and its |
| deployment model, developers of new logging frameworks should |
| find it very easy to write SLF4J bindings. |
| </p> |
| |
| <h3 class="doAnchor" name="libraries">Libraries</h3> |
| |
| <p>Authors of widely-distributed components and libraries may |
| code against the SLF4J interface in order to avoid imposing an |
| logging framework on their end-user. Thus, the end-user may |
| choose the desired logging framework at deployment time by |
| inserting the corresponding slf4j binding on the classpath, |
| which may be changed later by replacing an existing binding with |
| another on the class path and restarting the application. This |
| approach has proven to be simple and very robust. |
| </p> |
| |
| <p><b>As of SLF4J version 1.6.0</b>, if no binding is found on |
| the class path, then slf4j-api will default to a no-operation |
| implementation discarding all log requests. Thus, instead of |
| throwing a <code>NoClassDefFoundError</code> because the |
| <code>org.slf4j.impl.StaticLoggerBinder</code> class is missing, |
| SLF4J version 1.6.0 and later will emit a single warning message |
| about the absence of a binding and proceed to discard all log |
| requests without further protest. For example, let Wombat be |
| some biology-related framework depending on SLF4J for |
| logging. In order to avoid imposing a logging framework on the |
| end-user, Wombat's distribution includes <em>slf4j-api.jar</em> |
| but no binding. Even in the absence of any SLF4J binding on the |
| class path, Wombat's distribution will still work |
| out-of-the-box, and without requiring the end-user to download a |
| binding from SLF4J's web-site. Only when the end-user decides to |
| enable logging will she need to install the SLF4J binding |
| corresponding to the logging framework chosen by her. |
| </p> |
| |
| <p><span class="label">Basic rule</span> <b>Embedded components |
| such as libraries or frameworks should not declare a dependency |
| on any SLF4J binding but only depend on slf4j-api</b>. When a |
| library declares a transitive dependency on a specific binding, |
| that binding is imposed on the end-user negating the purpose of |
| SLF4J. Note that declaring a non-transitive dependency on a |
| binding, for example for testing, does not affect the |
| end-user.</p> |
| |
| <p>SLF4J usage in embedded components is also discussed in the |
| FAQ in relation with <a |
| href="faq.html#configure_logging">logging configuration</a>, <a |
| href="faq.html#optional_dependency">dependency reduction</a> and |
| <a href="faq.html#optional_dependency">testing</a>.</p> |
| |
| <h3 class="doAnchor" name="projectDep">Declaring project |
| dependencies for logging</h3> |
| |
| <p>Given Maven's transitive dependency rules, for "regular" |
| projects (not libraries or frameworks) declaring logging |
| dependencies can be accomplished with a single dependency |
| declaration. |
| </p> |
| |
| <p><span class="label notice">logback-classic</span> If you wish |
| to use logback-classic as the underlying logging framework, all |
| you need to do is to declare "ch.qos.logback:logback-classic" as |
| a dependency in your <em>pom.xml</em> file as shown below. In |
| addition to <em>logback-classic-${logback.version}.jar</em>, |
| this will pull <em>slf4j-api-${project.version}.jar</em> as well |
| as <em>logback-core-${logback.version}.jar</em> into your |
| project. Note that explicitly declaring a dependency on |
| <em>logback-core-${logback.version}</em> or |
| <em>slf4j-api-${project.version}.jar</em> is not wrong and may |
| be necessary to impose the correct version of said artifacts by |
| virtue of Maven's "nearest definition" dependency mediation |
| rule. |
| </p> |
| |
| <pre class="prettyprint source"><dependency> |
| <groupId>ch.qos.logback</groupId> |
| <artifactId>logback-classic</artifactId> |
| <version>${logback.version}</version> |
| </dependency></pre> |
| |
| <p/> |
| |
| <p><span class="label notice">log4j</span> If you wish to use |
| log4j as the underlying logging framework, all you need to do is |
| to declare "org.slf4j:slf4j-log4j12" as a dependency in your |
| <em>pom.xml</em> file as shown below. In addition to |
| <em>slf4j-log4j12-${project.version}.jar</em>, this will pull |
| <em>slf4j-api-${project.version}.jar</em> as well as |
| <em>log4j-${log4j.version}.jar</em> into your project. Note |
| that explicitly declaring a dependency on |
| <em>log4j-${log4j.version}.jar</em> or |
| <em>slf4j-api-${project.version}.jar</em> is not wrong and may |
| be necessary to impose the correct version of said artifacts by |
| virtue of Maven's "nearest definition" dependency mediation |
| rule.</p> |
| |
| <pre class="prettyprint source"><dependency> |
| <groupId>org.slf4j</groupId> |
| <artifactId>slf4j-log4j12</artifactId> |
| <version>${project.version}</version> |
| </dependency></pre> |
| |
| <p/> |
| |
| <p><span class="label notice">java.util.logging</span> If you |
| wish to use java.util.logging as the underlying logging |
| framework, all you need to do is to declare |
| "org.slf4j:slf4j-jdk14" as a dependency in your <em>pom.xml</em> |
| file as shown below. In addition to |
| <em>slf4j-jdk14-${project.version}.jar</em>, this will pull |
| <em>slf4j-api-${project.version}.jar</em> into your project. |
| Note that explicitly declaring a dependency on |
| <em>slf4j-api-${project.version}.jar</em> is not wrong and may |
| be necessary to impose the correct version of said artifact by |
| virtue of Maven's "nearest definition" dependency mediation |
| rule.</p> |
| |
| <pre class="prettyprint source"><dependency> |
| <groupId>org.slf4j</groupId> |
| <artifactId>slf4j-jdk14</artifactId> |
| <version>${project.version}</version> |
| </dependency></pre> |
| |
| |
| |
| <h3 class="doAnchor" name="compatibility">Binary |
| compatibility</h3> |
| |
| <p>An SLF4J binding designates an artifact such as |
| <em>slf4j-jdk14.jar</em> or <em>slf4j-log4j12.jar</em> used to |
| <em>bind</em> slf4j to an underlying logging framework, say, |
| java.util.logging and respectively log4j. |
| </p> |
| |
| <p class="highlight">From the client's perspective all versions |
| of slf4j-api are compatible. Client code compiled with |
| slf4j-api-N.jar will run perfectly fine with slf4j-api-M.jar for |
| any N and M. You only need to ensure that the version of your |
| binding matches that of the slf4j-api.jar. You do not have to |
| worry about the version of slf4j-api.jar used by a given |
| dependency in your project. </p> |
| |
| |
| <p>Mixing different versions of <em>slf4j-api.jar</em> and SLF4J |
| binding can cause problems. For example, if you are using |
| slf4j-api-${project.version}.jar, then you should also use |
| slf4j-simple-${project.version}.jar, using |
| slf4j-simple-1.5.5.jar will not work.</p> |
| |
| |
| <p>However, from the client's perspective all versions of |
| slf4j-api are compatible. Client code compiled with |
| <em>slf4j-api-N.jar</em> will run perfectly fine with |
| <em>slf4j-api-M.jar</em> for any N and M. You only need to |
| ensure that the version of your binding matches that of the |
| slf4j-api.jar. You do not have to worry about the version of |
| slf4j-api.jar used by a given dependency in your project. You |
| can always use any version of <em>slf4j-api.jar</em>, and as |
| long as the version of <em>slf4j-api.jar</em> and its binding |
| match, you should be fine. |
| </p> |
| |
| <p>At initialization time, if SLF4J suspects that there may be |
| an slf4j-api vs. binding version mismatch problem, it will emit |
| a warning about the suspected mismatch. |
| </p> |
| |
| |
| <h3 class="doAnchor" name="consolidate">Consolidate logging via |
| SLF4J</h3> |
| |
| <p>Often times, a given project will depend on various |
| components which rely on logging APIs other than SLF4J. It is |
| common to find projects depending on a combination of JCL, |
| java.util.logging, log4j and SLF4J. It then becomes desirable to |
| consolidate logging through a single channel. SLF4J caters for |
| this common use-case by providing bridging modules for JCL, |
| java.util.logging and log4j. For more details, please refer to |
| the page on <a href="legacy.html"><b>Bridging legacy |
| APIs</b></a>. |
| </p> |
| |
| <h3 class="doAnchor" name="mdc">Mapped Diagnostic Context (MDC) support</h3> |
| |
| <p>"Mapped Diagnostic Context" is essentially a map maintained |
| by the logging framework where the application code provides |
| key-value pairs which can then be inserted by the logging |
| framework in log messages. MDC data can also be highly helpful |
| in filtering messages or triggering certain actions.</p> |
| |
| <p>SLF4J supports MDC, or mapped diagnostic context. If the |
| underlying logging framework offers MDC functionality, then |
| SLF4J will delegate to the underlying framework's MDC. Note that |
| at this time, only log4j and logback offer MDC functionality. If |
| the underlying framework does not offer MDC, for example |
| java.util.logging, then SLF4J will still store MDC data but the |
| information therein will need to be retrieved by custom user |
| code.</p> |
| |
| <p>Thus, as a SLF4J user, you can take advantage of MDC |
| information in the presence of log4j or logback, but without |
| forcing these logging frameworks upon your users as |
| dependencies. |
| </p> |
| |
| <p>For more information on MDC please see the <a |
| href="http://logback.qos.ch/manual/mdc.html">chapter on MDC</a> |
| in the logback manual. |
| </p> |
| |
| |
| |
| <h3 class="doAnchor" name="summary">Executive summary</h3> |
| |
| <table class="bodyTable striped" cellspacing="4" cellpadding="4"> |
| <tr> |
| <th align="left">Advantage</th> |
| <th align="left">Description</th> |
| </tr> |
| |
| <tr> |
| |
| <td>Select your logging framework at deployment time</td> |
| |
| <td>The desired logging framework can be plugged in at |
| deployment time by inserting the appropriate jar file |
| (binding) on your class path. |
| </td> |
| </tr> |
| |
| |
| <tr> |
| <td>Fail-fast operation</td> |
| |
| <td>Due to the way that classes are loaded by the JVM, the |
| framework binding will be verified automatically very early |
| on. If SLF4J cannot find a binding on the class path it |
| will emit a single warning message and default to |
| no-operation implementation. |
| </td> |
| </tr> |
| |
| |
| <tr> |
| <td>Bindings for popular logging frameworks |
| </td> |
| |
| <td>SLF4J supports popular logging frameworks, namely log4j, |
| java.util.logging, Simple logging and NOP. The <a |
| href="http://logback.qos.ch">logback</a> project supports |
| SLF4J natively. </td> |
| |
| </tr> |
| |
| <tr> |
| <td>Bridging legacy logging APIs</td> |
| |
| <td> |
| <p>The implementation of JCL over SLF4J, i.e |
| <em>jcl-over-slf4j.jar</em>, will allow your project to |
| migrate to SLF4J piecemeal, without breaking compatibility |
| with existing software using JCL. Similarly, |
| log4j-over-slf4j.jar and jul-to-slf4j modules will allow |
| you to redirect log4j and respectively java.util.logging |
| calls to SLF4J. See the page on <a |
| href="legacy.html">Bridging legacy APIs</a> for more |
| details. |
| </p> |
| </td> |
| </tr> |
| |
| <tr> |
| <td>Migrate your source code</td> |
| <td>The <a href="migrator.html">slf4j-migrator</a> utility |
| can help you migrate your source to use SLF4J. |
| </td> |
| </tr> |
| |
| |
| |
| <tr> |
| <td>Support for parameterized log messages</td> |
| |
| <td>All SLF4J bindings support parameterized log messages |
| with significantly <a |
| href="faq.html#logging_performance">improved performance</a> |
| results.</td> |
| </tr> |
| |
| |
| </table> |
| |
| <script src="templates/footer.js" type="text/javascript"></script> |
| |
| </div> |
| </body> |
| </html> |