| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width,initial-scale=1"> |
| <title>Migrating from Logback :: Apache Log4j</title> |
| <link rel="canonical" href="https://logging.apache.org/log4j/2.x/migrate-from-logback.html"> |
| <meta name="generator" content="Antora 3.2.0-alpha.8"> |
| <link rel="stylesheet" href="./_/css/site.css"> |
| <link rel="icon" href="./_/../_images/favicon.ico" type="image/x-icon"> |
| <!-- `@asciidoctor/tabs` extension styles --> |
| <link rel="stylesheet" href="./_/css/vendor/tabs.css"> |
| <style> |
| /* Swap colors of `IMPORTANT` and `WARNING` blocks */ |
| .doc .admonitionblock.important .icon { background-color: #f70; } |
| .doc .admonitionblock.warning .icon { background-color: #e40046; } |
| /* Default `h4`, `h5`, and `h6` are smaller than the normal text, fix header font sizing: */ |
| .doc h1 { font-size: 1.9rem; } |
| .doc h2 { font-size: 1.7rem; } |
| .doc h3 { font-size: 1.5rem; font-weight: 400; } |
| .doc h4 { font-size: 1.3rem; font-weight: 500; } |
| .doc h5 { font-size: 1.1rem; font-weight: 500; text-decoration: underline; } |
| .doc h6 { font-size: 0.9rem; font-weight: 500; text-decoration: underline; } |
| /* Default `code`, `pre`, and `.colist` (source code annotations) fonts are too big, adjust them: */ |
| .doc .colist>table code, .doc p code, .doc thead code { font-size: 0.8em; } |
| .doc pre { font-size: 0.7rem; } |
| .doc .colist { font-size: 0.75rem; } |
| /* Make links more visible: */ |
| .doc a { text-decoration: underline; } |
| .doc a code { text-decoration: underline; color: #1565c0; } |
| /* Tab header fonts aren't rendered good, adjusting the font weight: */ |
| .tablist > ul li { font-weight: 500; } |
| /* `page-toclevels` greater than 4 are not supported by Antora UI, patching it: */ |
| .toc .toc-menu li[data-level="4"] a { |
| padding-left: 2.75rem; |
| } |
| /* Replace the default highlight.js color for strings from red (unnecessarily signaling something negative) to green: */ |
| .hljs-string { |
| color: #0f8532; |
| } |
| </style> |
| </head> |
| <body class="article"> |
| <header class="header"> |
| <nav class="navbar"> |
| <div class="navbar-brand"> |
| <div class="navbar-item"> |
| <img src="./_/../_images/logo-small-white.png" alt="Apache Log4j"/> |
| </div> |
| </div> |
| <div id="topbar-nav" class="navbar-menu"> |
| <div class="navbar-end"> |
| <a class="navbar-item" href="https://logging.apache.org">a subproject of <strong>Apache Logging Services</strong></a> |
| </div> |
| </div> |
| </nav> |
| </header> |
| <div class="body"> |
| <div class="nav-container" data-component="ROOT" data-version=""> |
| <aside class="nav"> |
| <div class="panels"> |
| <div class="nav-panel-menu is-active" data-panel="menu"> |
| <nav class="nav-menu"> |
| <button class="nav-menu-toggle" aria-label="Toggle expand/collapse all" style="display: none"></button> |
| <h3 class="title"><a href="index.html">Home</a></h3> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="0"> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="download.html">Download</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="release-notes.html">Release notes</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="https://logging.apache.org/support.html">Support</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="https://logging.apache.org/security.html">Security</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="0"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/index.html">Manual</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="manual/getting-started.html">Getting started</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="manual/installation.html">Installation</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/api.html">API</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/api.html#loggers">Loggers</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/eventlogging.html">Event Logger</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/simple-logger.html">Simple Logger</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/status-logger.html">Status Logger</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="manual/logbuilder.html">Fluent API</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/api.html#fish-tagging">Fish tagging</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/customloglevels.html">Levels</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/markers.html">Markers</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/thread-context.html">Thread Context</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="manual/messages.html">Messages</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="manual/flowtracing.html">Flow Tracing</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/implementation.html">Implementation</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="manual/architecture.html">Architecture</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/config-intro.html">Configuration</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/configuration.html">Configuration file</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/systemproperties.html">Configuration properties</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/customconfig.html">Programmatic configuration</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/appenders.html">Appenders</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/appenders/file.html">File appenders</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/appenders/rolling-file.html">Rolling file appenders</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/appenders/database.html">Database appenders</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/appenders/network.html">Network Appenders</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/appenders/message-queue.html">Message queue appenders</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/appenders/delegating.html">Delegating Appenders</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/layouts.html">Layouts</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/json-template-layout.html">JSON Template Layout</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="manual/pattern-layout.html">Pattern Layout</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/lookups.html">Lookups</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/filters.html">Filters</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/scripts.html">Scripts</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/jmx.html">JMX</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/extending.html">Extending</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/plugins.html">Plugins</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="manual/performance.html">Performance</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/async.html">Asynchronous loggers</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="manual/garbagefree.html">Garbage-free logging</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="0"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">References</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="plugin-reference.html">Plugin reference</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="javadoc.html">Java API reference</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="0"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Resources</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="faq.html">F.A.Q.</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="migrate-from-log4j1.html">Migrating from Log4j 1</a> |
| </li> |
| <li class="nav-item is-current-page" data-depth="1"> |
| <a class="nav-link" href="migrate-from-logback.html">Migrating from Logback</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="migrate-from-slf4j.html">Migrating from SLF4J</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="graalvm.html">Building GraalVM native images</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="hibernate.html">Integrating with Hibernate</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="jakarta.html">Integrating with Jakarta EE</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="soa.html">Integrating with service-oriented architectures</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="development.html">Development</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="0"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="components.html">Components</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="log4j-iostreams.html">Log4j IOStreams</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="log4j-spring-boot.html">Log4j Spring Boot Support</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="log4j-spring-cloud-config-client.html">Log4j Spring Cloud Configuration</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="log4j-jul.html">JUL-to-Log4j bridge</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="log4j-to-jul.html">Log4j-to-JUL bridge</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="0"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Related projects</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="https://logging.apache.org/log4j/jakarta/index.html">Log4j Jakarta EE</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="https://logging.apache.org/log4j/jmx-gui/index.html">Log4j JMX GUI</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="https://logging.apache.org/log4j/kotlin/index.html">Log4j Kotlin</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="https://logging.apache.org/log4j/scala/index.html">Log4j Scala</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="https://logging.apache.org/log4j/tools/index.html">Log4j Tools</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="https://logging.apache.org/log4j/transform/index.html">Log4j Transformation Tools</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </nav> |
| </div> |
| </div> |
| </aside> |
| </div> |
| <main class="article"> |
| <div class="toolbar" role="navigation"> |
| <button class="nav-toggle"></button> |
| <a href="index.html" class="home-link"></a> |
| <nav class="breadcrumbs" aria-label="breadcrumbs"> |
| <ul> |
| <li><a href="index.html">Home</a></li> |
| <li>Resources</li> |
| <li><a href="migrate-from-logback.html">Migrating from Logback</a></li> |
| </ul> |
| </nav> |
| <div class="edit-this-page"><a href="https://github.com/apache/logging-log4j2/edit/2.x/src/site/antora/modules/ROOT/pages/migrate-from-logback.adoc">Edit this Page</a></div> |
| </div> |
| <div class="content"> |
| <aside class="toc sidebar" data-title="Contents" data-levels="4"> |
| <div class="toc-menu"></div> |
| </aside> |
| <article class="doc"> |
| <h1 class="page">Migrating from Logback</h1> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p><a href="https://logback.qos.ch">Logback</a> is a logging implementation for the <a href="https://www.slf4j.org">SLF4J</a> logging API, just like Log4j Core is a logging implementation for the <a href="manual/api.html" class="xref page">Log4j API</a>. |
| In this page we will guide you through migrating from Logback to Log4j Core as your logging implementation.</p> |
| </div> |
| <div class="admonitionblock tip"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-tip" title="Tip"></i> |
| </td> |
| <td class="content"> |
| <div class="paragraph"> |
| <p>Instead of migrating your logging implementation, Logback, are you looking for migrating your logging API, SLF4J? |
| Please refer to <a href="migrate-from-slf4j.html" class="xref page">Migrating from SLF4J</a>.</p> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| <details> |
| <summary class="title">Struggling with the logging API, implementation, and bridge concepts? Click for an introduction.</summary> |
| <div class="content"> |
| <div id="logging-api" class="dlist"> |
| <dl> |
| <dt class="hdlist1">Logging API</dt> |
| <dd> |
| <p>A logging API is an interface your code or your dependencies directly logs against. |
| It is required at compile-time. |
| It is implementation agnostic to ensure that your application can write logs, but is not tied to a specific logging implementation. |
| Log4j API, <a href="https://www.slf4j.org">SLF4J</a>, <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html">JUL (Java Logging)</a>, <a href="https://commons.apache.org/proper/commons-logging/">JCL (Apache Commons Logging)</a>, <a href="https://openjdk.org/jeps/264">JPL (Java Platform Logging)</a> and <a href="https://github.com/jboss-logging/jboss-logging">JBoss Logging</a> are major logging APIs.</p> |
| </dd> |
| </dl> |
| </div> |
| <div id="logging-impl" class="dlist"> |
| <dl> |
| <dt class="hdlist1">Logging implementation</dt> |
| <dd> |
| <p>A logging implementation is only required at runtime and can be changed without the need to recompile your software. |
| Log4j Core, <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html">JUL (Java Logging)</a>, <a href="https://logback.qos.ch">Logback</a> are the most well-known logging implementations.</p> |
| </dd> |
| </dl> |
| </div> |
| <div id="logging-bridge" class="dlist"> |
| <dl> |
| <dt class="hdlist1">Logging bridge</dt> |
| <dd> |
| <p>Logging implementations accept input from a single logging API of their preference; Log4j Core from Log4j API, Logback from SLF4J, etc. |
| A logging bridge is a simple logging implementation of a logging API that forwards all messages to a foreign logging API. |
| Logging bridges allow a logging implementation to accept input from other logging APIs that are not their primary logging API. |
| For instance, <code>log4j-slf4j2-impl</code> <em>bridges</em> SLF4J calls to Log4 API and effectively enables Log4j Core to accept input from SLF4J.</p> |
| </dd> |
| </dl> |
| </div> |
| <div class="paragraph"> |
| <p>To make things a little bit more tangible, consider the following visualization of a typical Log4j Core installation with bridges for an application:</p> |
| </div> |
| <div class="imageblock kroki"> |
| <div class="content"> |
| <img src="_images/diag-a51b68065f249459078382aa4c61888857f01b2c.svg" alt="Visualization of a typical Log4j Core installation with SLF4J, JUL, and JPL bridges"> |
| </div> |
| <div class="title">Figure 1. Visualization of a typical Log4j Core installation with SLF4J, JUL, and JPL bridges</div> |
| </div> |
| </div> |
| </details> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="migrating"><a class="anchor" href="#migrating"></a>Migrating</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>You either have an application using Logback at runtime, or have a library using Logback for tests. |
| In either case, you can replace Logback with Log4j Core as follows:</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Remove <code>ch.qos.logback:logback-classic</code> dependency</p> |
| </li> |
| <li> |
| <p>Remove <code>logback.xml</code> and <code>logback-test.xml</code> files</p> |
| </li> |
| <li> |
| <p>Follow the instructions shared in the <em>"Getting started"</em> page</p> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="manual/getting-started.html#install-app" class="xref page">for applications</a></p> |
| </li> |
| <li> |
| <p><a href="manual/getting-started.html#install-lib" class="xref page">for libraries</a></p> |
| </li> |
| </ul> |
| </div> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>Next you need to re-organize your logging API bridges such that all foreign APIs are bridged to Log4j API, the logging API implemented by Log4j Core. |
| This is explained in the next section.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="bridges"><a class="anchor" href="#bridges"></a>Bridges</h3> |
| <div class="paragraph"> |
| <p>It is highly likely that you were bridging all logging APIs (including Log4j API!) to SLF4J, the logging API implemented by Logback. |
| There are two particular approaches you can take here to ensure all logging APIs are instead bridged to Log4j API, the logging API implemented by Log4j Core:</p> |
| </div> |
| <div class="sect3"> |
| <h4 id="bridge-to-log4j"><a class="anchor" href="#bridge-to-log4j"></a>Bridge all logging APIs to Log4j API</h4> |
| <div class="paragraph"> |
| <p>We strongly advise you to bridge all foreign logging APIs <strong>directly</strong> to Log4j API. |
| You can use the cheat sheet shared below to implement that.</p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <caption class="title">Table 1. Dependency migration cheat sheet</caption> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top">If dependency present</th> |
| <th class="tableblock halign-left valign-top">replace with</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.apache.logging.log4j:log4j-to-slf4j</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.apache.logging.log4j:log4j-slf4j2-impl</code></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.slf4j:jcl-over-slf4j</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>commons-logging:commons-logging</code> version <code>>=1.3.0</code></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.slf4j:jul-to-slf4j</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.apache.logging.log4j:log4j-jul</code></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.slf4j:log4j-over-slf4j</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.apache.logging.log4j:log4j-1.2-api</code></p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework:spring-boot-starter-logging</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework:spring-boot-starter-log4j2</code></p></td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| <div class="sect3"> |
| <h4 id="bridge-to-sfl4j"><a class="anchor" href="#bridge-to-sfl4j"></a>Bridge all logging APIs to SLF4J, and bridge SLF4J to Log4j API</h4> |
| <div class="paragraph"> |
| <p>You can implement this by replacing <code>org.apache.logging.log4j:log4j-to-slf4j</code> dependency with <code>org.apache.logging.log4j:log4j-slf4j2-impl</code>.</p> |
| </div> |
| <div class="admonitionblock warning"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-warning" title="Warning"></i> |
| </td> |
| <td class="content"> |
| <div class="paragraph"> |
| <p><strong>This approach is not recommended!</strong> |
| It incurs certain drawbacks since some logging API calls will need to cross multiple bridges. |
| For instance, a call to JUL will first be bridged to SLF4J, and then from there to Log4j API.</p> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="config"><a class="anchor" href="#config"></a>Configuration</h3> |
| <div class="paragraph"> |
| <p>It might not always be trivial to match the contents of the newly created <code>log4j2.xml</code> and <code>log4j2-test.xml</code> files with your old <code>logback.xml</code> and <code>logback-test.xml</code> files. |
| While all Logback components have corresponding equivalents in Log4j Core, they might not be sharing the same name or configuration. |
| To assist with migrating Logback configuration components to Log4j Core, see the following pages:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="manual/appenders.html" class="xref page">Appenders</a></p> |
| </li> |
| <li> |
| <p><a href="manual/layouts.html" class="xref page">Layouts</a></p> |
| </li> |
| <li> |
| <p><a href="manual/filters.html" class="xref page">Filters</a></p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>For the complete list of all Log4j configuration knobs, see <a href="manual/configuration.html" class="xref page">the Configuration page</a>.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="parameterized-logging"><a class="anchor" href="#parameterized-logging"></a>Parameterized logging</h3> |
| <div class="paragraph"> |
| <p>A common mistake in parameterized logging is to add a <code>{}</code> placeholder for the exception associated with a log event:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">} catch (Exception exception) { |
| logger.error("The foo process exited with an error: {}", exception); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Log4j Core and Logback differ in the way they treat this statement:</p> |
| </div> |
| <div class="dlist"> |
| <dl> |
| <dt class="hdlist1">Logback</dt> |
| <dd> |
| <p>Logback interprets the <code>exception</code> argument as throwable and removes it from the list of parameters. |
| We end up with a parameterized statement with one placeholder, but zero parameters. |
| The placeholder therefore remains as is:</p> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-none hljs">The foo process exited with and error: {} |
| java.lang.RuntimeException: Message |
| at example.MigrateFromLogback.doLogWrong(MigrateFromLogback.java:10) |
| ...</code></pre> |
| </div> |
| </div> |
| </dd> |
| <dt class="hdlist1">Log4j Core</dt> |
| <dd> |
| <p>Log4j Core first looks for the parameters of the message. |
| Since the format string has one placeholder, the <code>exception</code> argument is interpreted as a parameter of the log message. |
| The throwable associated to the log event is <code>null</code>, which results in a missing stack trace:</p> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-none hljs">The foo process exited with and error: java.lang.RuntimeException: Message</code></pre> |
| </div> |
| </div> |
| </dd> |
| </dl> |
| </div> |
| <div class="paragraph"> |
| <p>To fix this problem and get the same output in both backends, you should remove the placeholder from the format string:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">} catch (Exception exception) { |
| logger.error("The foo process exited with an error.", exception); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>After the change, the output will look us:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-none hljs">The foo process exited with and error. |
| java.lang.RuntimeException: Message |
| at example.MigrateFromLogback.doLogWrong(MigrateFromLogback.java:10) |
| ...</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock tip"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-tip" title="Tip"></i> |
| </td> |
| <td class="content"> |
| <div class="paragraph"> |
| <p>As a temporary solution, the SLF4J-to-Log4j API bridges contain a special |
| <a href="manual/api.html#logger-message-factories" class="xref page"><code>MessageFactory</code></a> |
| that classifies trailing <code>Throwable</code> arguments in the same way Logback does. |
| To use it, you need to set the <a href="manual/systemproperties.html#log4j2.messageFactory" class="xref page"><code>log4j2.messageFactory</code></a> configuration property to <code>org.apache.logging.slf4j.message.ThrowableConsumingMessageFactory</code>.</p> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| </div> |
| </article> |
| </div> |
| </main> |
| </div> |
| <footer class="footer"> |
| <p> |
| Copyright © 1999-2025 <a href="https://www.apache.org/">The Apache Software Foundation</a>. |
| Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache Software License, Version 2.0</a>. |
| Please read our <a href="https://privacy.apache.org/policies/privacy-policy-public.html">privacy policy</a>. |
| </p> |
| <p> |
| Apache, Log4j, and the Apache feather logo are trademarks or registered trademarks of The Apache Software Foundation. |
| Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
| Other names may be trademarks of their respective owners. |
| </p> |
| </footer> |
| <!-- Matomo --> |
| <script> |
| var _paq = window._paq = window._paq || []; |
| _paq.push(["disableCookies"]); |
| _paq.push(['trackPageView']); |
| _paq.push(['enableLinkTracking']); |
| (function() { |
| var u="https://analytics.apache.org/"; |
| _paq.push(['setTrackerUrl', u+'matomo.php']); |
| _paq.push(['setSiteId', '42']); |
| var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; |
| g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); |
| })(); |
| </script> |
| <noscript><p><img src="https://analytics.apache.org/matomo.php?idsite=42&rec=1" style="border:0;" alt="" /></p></noscript> |
| <!-- End Matomo Code --> |
| <script id="site-script" src="./_/js/site.js" data-ui-root-path="./_"></script> |
| <script async src="./_/js/vendor/highlight.js"></script> |
| <!-- `@asciidoctor/tabs` extension scripts --> |
| <script async src="./_/js/vendor/tabs.js"></script> |
| </body> |
| </html> |