| <!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>Log4j Bridge</title> |
| <link rel="stylesheet" type="text/css" media="screen" href="css/site.css" /> |
| <link rel="stylesheet" type="text/css" media="print" href="css/print.css" /> |
| |
| </head> |
| <body> |
| <script type="text/javascript">prefix='';</script> |
| |
| <script src="templates/header.js" type="text/javascript"></script> |
| <div id="left"> |
| <script src="templates/left.js" type="text/javascript"></script> |
| </div> |
| <div id="content"> |
| |
| |
| <h2>Bridging legacy APIs</h2> |
| |
| <p>Often, some of the components you depend on rely on a logging |
| API other than SLF4J. You may also assume that these components |
| will not switch to SLF4J in the immediate future. To deal with |
| such circumstances, SLF4J ships with several bridging modules |
| which redirect calls made to log4j, JCL and java.util.logging APIs |
| to behave as if they were made to the SLF4J API instead. The |
| figure below illustrates the idea. |
| </p> |
| |
| <p></p> |
| <p></p> |
| |
| |
| <p><a href="images/bridging.png"> |
| <img src="images/bridging.png" alt="click to enlarge" width="800"/> |
| </a></p> |
| |
| <p> |
| </p> |
| |
| <h3><a name="jcl-over-slf4j" href="#jcl-over-slf4j">Gradual migration to |
| SLF4J from Jakarta Commons Logging (JCL)</a></h3> |
| |
| <h4><em>jcl-over-slf4j.jar</em></h4> |
| |
| <p>To ease migration to SLF4J from JCL, SLF4J distributions |
| include the jar file <em>jcl-over-slf4j.jar</em>. This jar file is |
| intended as a drop-in replacement for JCL version 1.1.1. It |
| implements the public API of JCL but using SLF4J underneath, hence |
| the name "JCL over SLF4J." |
| </p> |
| |
| <p>Our JCL over SLF4J implementation will allow you to migrate to |
| SLF4J gradually, especially if some of the libraries your software |
| depends on continue to use JCL for the foreseeable future. You can |
| immediately enjoy the benefits of SLF4J's reliability and preserve |
| backward compatibility at the same time. Just replace |
| <em>commons-logging.jar</em> with |
| <em>jcl-over-slf4j.jar</em>. Subsequently, the selection of the |
| underlying logging framework will be done by SLF4J instead of JCL |
| but without the class loader headaches. The underlying logging |
| framework can be any of the frameworks supported by SLF4J. |
| </p> |
| |
| <h3><em>slf4j-jcl.jar</em></h3> |
| |
| <p>Some of our users after having switched to SLF4J API realize that |
| in some contexts the use of JCL is mandatory and their use of SLF4J |
| can be a problem. For this uncommon but important case, SLF4J offers |
| a JCL binding, found in the file <em>slf4j-jcl.jar</em>. The JCL |
| binding will delegate all logging calls made through SLF4J API to |
| JCL. Thus, if for some reason an existing application <em>must</em> |
| use JCL, your part of that application can still code against the |
| SLF4J API in a manner transparent to the larger application |
| environment. Your choice of SLF4J API will be invisible to the rest |
| of the application which can continue to use JCL. |
| </p> |
| |
| <h3><em>jcl-over-slf4j.jar</em> should not be confused with |
| <em>slf4j-jcl.jar</em></h3> |
| |
| |
| <p>JCL-over-SLF4J, i.e. <em>jcl-over-slf4j.jar</em>, comes in handy |
| in situations where JCL needs to be supported for backward |
| compatibility reasons. It can be used to fix problems associated |
| with JCL, without necessarily adopting the SLF4J API, a decision |
| which can be deferred to a later time. |
| </p> |
| |
| <p>On the other hand, <em>slf4j-jcl.jar</em> is useful |
| <strong>after</strong> you have already adopted the SLF4J API for |
| your component which needs to be embedded in a larger application |
| environment where JCL is a formal requirement. Your software |
| component can still use SLF4J API without disrupting the larger |
| application. Indeed, <em>slf4j-jcl.jar</em> will delegate all |
| logging decisions to JCL so that the dependency on SLF4J API by your |
| component will be transparent to the larger whole. |
| </p> |
| |
| <p>Please note that <em>jcl-over-slf4j.jar</em> and |
| <em>slf4j-jcl.jar</em> cannot be deployed at the same time. The |
| former jar file will cause JCL to delegate the choice of the logging |
| system to SLF4J and the latter jar file will cause SLF4J to delegate |
| the choice of the logging system to JCL, resulting in an infinite |
| loop. |
| </p> |
| |
| |
| <h3><a name="log4j-over-slf4j" href="#log4j-over-slf4j">Log4j over |
| SLF4J</a></h3> |
| |
| <p>SLF4J ship with a module called <em>log4j-over-slf4j</em>. It |
| allows log4j users to migrate existing applications to SLF4J without |
| changing <em>a single line of code</em> but simply by replacing the |
| <em>log4j.jar</em> file with <em>log4j-over-slf4j.jar</em>, as |
| described below. |
| </p> |
| |
| <h4>How does it work?</h4> |
| |
| <p>The log4j-over-slf4j module contains replacements of most widely |
| used log4j classes, namely <code>org.apache.log4j.Category</code>, |
| <code>org.apache.log4j.Logger</code>, |
| <code>org.apache.log4j.Priority</code>, |
| <code>org.apache.log4j.Level</code>, |
| <code>org.apache.log4j.MDC</code>, and |
| <code>org.apache.log4j.BasicConfigurator</code>. These replacement |
| classes redirect all work to their corresponding SLF4J classes. |
| </p> |
| |
| <p>To use log4j-over-slf4j in your own application, the first step |
| is to locate and then to replace <em>log4j.jar</em> with |
| <em>log4j-over-slf4j.jar</em>. Note that you still need an SLF4J |
| binding and its dependencies for log4j-over-slf4j to work properly. |
| </p> |
| |
| <p>In most situations, replacing a jar file is all it takes in |
| order to migrate from log4j to SLF4J. |
| </p> |
| |
| <p>Note that as a result of this migration, log4j configuration |
| files will no longer be picked up. If you need to migrate your |
| log4j.properties file to logback, the <a |
| href="http://logback.qos.ch/translator/">log4j translator</a> might |
| be of help. For configuring logback, please refer to <a |
| href="http://logback.qos.ch/manual/index.html">its manual</a>. |
| </p> |
| |
| <h4>When does it not work?</h4> |
| |
| <p>The <em>log4j-over-slf4j</em> module will not work when the |
| application calls log4j components that are not present in the |
| bridge. For example, direct references to log4j appenders, |
| filters or PropertyConfigurator are not supported by |
| log4j-over-slf4j. While the number of cases where |
| log4j-over-slf4j is insufficient is not completely negligible, in |
| the vast majority of cases where log4j is configured through a |
| configuration file, be it <em>log4j.properties</em> or |
| <em>log4j.xml</em>, log4j-over-slf4j is enough in order to migrate |
| your application to SLF4J. |
| </p> |
| |
| <h4>What about the overhead?</h4> |
| |
| <p>There overhead of using log4j-over-slf4j instead of log4j |
| directly is relatively small. Given that log4j-over-slf4j |
| immediately delegates all work to SLF4J, the CPU overhead should be |
| negligible, in the order of a few <em>nanoseconds</em>. There is a |
| memory overhead corresponding to an entry in a hashmap per logger, |
| which should be usually acceptable even for very large applications |
| consisting of several thousand loggers. Moreover, if you choose |
| logback as your underlying logging system, and given that logback is |
| both much faster and more memory-efficient than log4j, the gains |
| made by using logback should compensate for the overhead of using |
| log4j-over-slf4j instead of log4j directly. |
| </p> |
| |
| <h4>log4j-over-slf4j.jar and slf4j-logj12.jar cannot be present |
| simultaneously |
| </h4> |
| |
| <p>The presence of <em>slf4j-logj12.jar</em>, that is the log4j |
| binding for SLF4J, will force all SLF4J calls to be delegated to |
| log4j. The presence of <em>log4j-over-slf4j.jar</em> will in turn |
| delegate all log4j API calls to their SLF4J equivalents. If both are |
| present simultaneously, slf4j calls will be delegated to log4j, and |
| log4j calls redirected to SLF4j, resulting in an endless loop. |
| </p> |
| |
| <h3><a name="jul-to-slf4j" href="jul-to-slf4j">JUL to SLF4J</a></h3> |
| |
| <p>The jul-to-slf4j module includes a jul handler, namely |
| SLF4JBridgeHandler, that routes all incoming jul records to the |
| SLF4j API. Please see <a |
| href="api/org/slf4j/bridge/SLF4JBridgeHandler.html">SLF4JBridgeHandler |
| javadocs</a> for usage instructions. |
| </p> |
| |
| <p>Contrary to other bridging modules such as jcl-over-slf4j and |
| log4j-over-slf4j, which re-implement JCL and respectively log4j, |
| the jul-to-slf4j modules does not re-implement the |
| java.util.logging package because packages under the java.* |
| namespace cannot be replaced. Instead, translates <a |
| href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/LogRecord.html?is-external=true">LogRecord</a> |
| object into its SLF4J equivalent on each logging event. Please |
| note this traslation process incurs the cost of constructing a |
| <code>LogRecord</code> instance regardless of whether the SLF4J |
| logger is disabled for the given level or nor. <b>Consequently, |
| j.u.l. to SLF4J translation can seriously impact on the cost of |
| disabled logging statements (60 fold increase) and a measurable |
| impact on enabled log statements (20% overall increase).</b> |
| </p> |
| |
| <p>If application performance is a concern, then use of |
| SLF4JBridgeHandler is appropriate only if few j.u.l. logging |
| statements are in play. </p> |
| |
| |
| <h4>jul-to-slf4j.jar and slf4j-jdk14.jar cannot be present |
| simultaneously |
| </h4> |
| |
| <p>The presence of slf4j-jdk14.jar, that is the jul binding for |
| SLF4J, will force SLF4J calls to be delegated to jul. On the other |
| hand, the presence of jul-to-slf4j.jar, plus the installation of |
| SLF4JBridgeHandler, by invoking "SLF4JBridgeHandler.install()" will |
| route jul records to SLF4J. Thus, if both jar are present |
| simultaneously (and SLF4JBridgeHandler is installed), slf4j calls |
| will be delegated to jul and jul records will be routed to SLF4J, |
| resulting in an endless loop. |
| </p> |
| |
| |
| <script src="templates/footer.js" type="text/javascript"></script> |
| </div> |
| </body> |
| </html> |