F.A.Q.

This page compiles a list of frequently asked questions. If you don’t find the answer to your question, please consult to the support page.

How do I specify the configuration file location?

By default, Log4j looks for a configuration file named log4j2.xml, log4j2.properties, etc. in the classpath.

Log4j 1 (which has reached its end-of-life in 2015!) uses log4j.xml. Log4j 2 and onwards use log4j2.xml.

You can also specify the full path of the configuration file using a system property:
-Dlog4j2.configurationFile=/path/to/log4j2.xml

That property can also be included in a classpath resource file named log4j2.component.properties.

Web applications can specify the Log4j configuration file location with a servlet context parameter. See the Log4j Jakarta project for details.

Refer to the Configuration page for further details.

How do I configure Log4j programmatically?

Starting with version 2.4, Log4j provides an API for programmatic configuration. The new ConfigurationBuilder API allows you to create Configurations in code by constructing component definitions without requiring you to know about the internals of actual configuration objects like loggers and appenders.

How do I reconfigure Log4j programmatically?

You can reconfigure Log4j programmatically using the Configurator API as follows:

import org.apache.logging.log4j.core.config.Configurator;

URI configSourceUri = new File("/path/to/a/different/log4j2.xml").toURI();
Configurator.reconfigure(configSourceUri);

How do I shut down Log4j programmatically?

Normally there is no need to do this manually. Each LoggerContext registers a shutdown hook that takes care of releasing resources when the JVM exits, unless the log4j.shutdownHookEnabled system property is set to false. Likewise, Web applications replace the shutdown hook with their own resource management mechanisms. That is, they clean up necessary resources when the web application is stopped. However, if you need to manually shut down Log4j, you can use one of the shutdown() methods of LogManager.

How do I set a logger level programmatically?

You can set the level of a logger using Configurator from Log4j Core:

import org.apache.logging.log4j.core.config.Configurator;

// Set the level of particular logger associated with a class
Configurator.setLevel("com.example.Foo", Level.DEBUG);

// Set the level of the root logger
Configurator.setRootLevel(Level.DEBUG);

How do I send log messages with different levels to different appenders?

You don’t need to declare separate loggers to achieve this. You can set the logging level on the AppenderRef element.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns="https://logging.apache.org/xml/ns"
               xsi:schemaLocation="
                       https://logging.apache.org/xml/ns
                       https://logging.apache.org/xml/ns/log4j-config-3.xsd">
  <appenders>
    <File name="file" fileName="app.log">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m %ex%n"/>
    </File>
    <Console name="stdout" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
  </appenders>
  <loggers>
    <root level="WARN">
      <AppenderRef ref="file" level="DEBUG"/>
      <AppenderRef ref="stdout" level="INFO"/>
    </root>
  </loggers>
</Configuration>

How do I debug my configuration?

  1. Make sure you have the right JAR files on your classpath.

  2. Check the name of your configuration file. By default, Log4j looks for a configuration file named log4j2.xml on the classpath. Note the 2 in the file name! (See the Configuration page for more details.)

  3. Increase the logging verbosity of the internal status logger:
    -Dlog4j2.statusLoggerLevel=TRACE

  4. Enable all internal debug logging: -Dlog4j2.debug. This disables level-based status logger filtering and effectively allows all status logs.

How do I dynamically write to separate log files?

You can use the routing appender to evaluate a log message and forward it to a particular appender.

What are the trade-offs of using Log4j API versus SLF4J?

Log4j API and SLF4J have a lot in common. They both share the objective of cleanly separating the logging API from the implementation. We believe that Log4j API can help make your application more performant while offering more functionality and more flexibility.

There may be a concern that using the Log4j API will tightly couple your application to Log4j. This is not the case: applications coded to Log4j API always have the option to use any SLF4J-compliant logging implementation with the log4j-to-slf4j bridge. See the Installation page for details.

There are several advantages to using Log4j API:

  • SLF4J forces your application to log Strings. Log4j API supports logging any CharSequence if you want to log text, but also supports logging any Object as is. It is the responsibility of the logging implementation to handle this object, and we consider it a design mistake to limit applications to logging Strings.

  • Log4j API offers support for logging Message objects. Messages allow support for interesting and complex constructs to be passed through the logging system and be efficiently manipulated. Users are free to create their own message types and write custom layouts, filters and lookups to manipulate them.

  • Log4j API supports lambda expressions both in its plain and fluent API.

  • Log4j API has better support for garbage-free logging: it avoids creating vararg arrays and avoids creating Strings when logging CharSequences.

Is Log4j still garbage-free when I use SLF4J?

If you use SLF4J as your logging API and Log4j Core as the logging implementation, yes. The log4j-slf4j-impl and log4j-slf4j2-impl bridges (together with log4j-core) implement the org.slf4j.Logger methods to be garbage-free. However, bear in mind that there are some limitations:

  • The SLF4J API only offers up to two parameters for a parameterized message. More than that uses varargs, which create a temporary object for the parameter array. In contrast, Log4j API has methods for up to ten unrolled parameters.

  • SLF4J forces your application to log Strings. Log4j API lets you log any CharSequence or Object. Log4j Core can log any Object that implements CharSequence or org.apache.logging.log4j.util.StringBuilderFormattable without creating garbage.

  • The org.slf4j.spi.LocationAwareLogger::log method is not yet implemented in a garbage-free manner in the log4j-slf4j-impl and log4j-slf4j2-impl bridges. It creates a new message object for each call.

How do I log my domain object without creating garbage?

One option is to let the domain object implement CharSequence. However, for many domain objects it may not be trivial to implement this without allocating temporary objects.

An alternative is to implement the org.apache.logging.log4j.util.StringBuilderFormattable interface. If an object is logged that implements this interface, its formatTo(StringBuilder) method is called instead of toString().

How do I create a custom logger wrapper that shows the correct class, method, and line number?

Log4j remembers the fully qualified class name (FQCN) of the logger and uses this to walk the stack trace for every log event when configured to print location.

Be aware that logging with location is slow and may impact the performance of your application.

The problem with custom logger wrappers is that they have a different FQCN than the actual logger, so Log4j can’t find the place where your custom logger was called.

The solution is to provide the correct FQCN. The easiest way to do this is to let Log4j generate the logger wrapper for you. Log4j comes with a Logger wrapper generator tool. This tool was originally meant to support custom log levels and was moved to the Log4j Transform subproject. The generated logger code will take care of the FQCN.

Which rules do I need to add when ProGuard minification is enabled?

When you are using Log4j with ProGuard/R8 enabled, you need to add the following rules to your configuration file:

-keep,allowoptimization class org.apache.logging.log4j.** { *; }

Can I use Log4j with Android?

Of course, you can! Since version 2.25.0 both the Log4j API and our three Log4j API implementations are tested for compatibility with the Android platform.

If you use Log4j API in an Android project, you have four choices for the Log4j API implementation:

Log4j Core

Our reference Log4j API implementation works on Android out-of-the-box. However, due to the limitations of the Android platform, the following features will not work:

  • The XInclude feature for XML configuration files will not work if you are using the standard Android XML parser. You might need to add the Xerces parser to use the feature.

  • Due to the lack of Android support for multi-release JARs, some location-based features like the no-arg LogManager.getLogger() method or ClassLoaderContextSelector (default on JRE) are not available. You should use BasicContextSelector (default on Android) or BasicAsyncLoggerContextSelector instead.

JUL
Logback

Both our Log4j API-to-JUL and Log4j API-to-SLF4J bridges are tested for compatibility with Android.

Log4j API-to-Android logging API bridge

If you wish to bridge Log4j API to Android’s native logging API directly, you can use the third-party com.celeral:log4j2-android artifact. See the log4j2-android project website for more information.