Status Logger

StatusLogger is a standalone, self-sufficient Logger implementation to record events that occur in the logging system (i.e., Log4j) itself. It is the logging system used by Log4j for reporting status of its internals.

Usage

You can use the status logger for several purposes:

Troubleshooting

When Log4j is not behaving in the way you expect it to, you can increase the verbosity of status logger messages emitted using the log4j2.debug system property for troubleshooting. See Configuration for details.

Reporting internal status

If you have custom Log4j components (layouts, appenders, etc.), you cannot use Log4j API itself for logging, since this will result in a chicken and egg problem. This is where StatusLogger comes into play:

private class CustomLog4jComponent {

    private static final Logger LOGGER = StatusLogger.getInstance();

    void doSomething(String input) {
        LOGGER.trace("doing something with input: `{}`", input);
    }

}
Listening internal status

You can configure where the status logger messages are delivered to. See Listeners.

Configuration

StatusLogger can be configured in following ways:

  1. Passing system properties to the Java process (e.g., -Dlog4j2.statusLoggerLevel=INFO}

    Due to several complexities involved, you are strongly advised to configure the status logger only using system properties!

  2. Providing properties in a "log4j2.StatusLogger.properties" file in the classpath

  3. Using Log4j configuration (i.e., <Configuration status="WARN" dest="out"> in a log4j2.xml in the classpath)

    Since version 2.24.0, status attribute in the Configuration element is deprecated and should be replaced with the log4j2.statusLoggerLevel configuration property.
  4. Programmatically (e.g., StatusLogger.getLogger().setLevel(Level.WARN))

It is crucial to understand that there is a time between the first StatusLogger access and a configuration file (e.g., log4j2.xml) read. Consider the following example:

  1. The default level (of fallback listener) is ERROR

  2. You have <Configuration status="WARN"> in your log4j2.xml

  3. Until your log4j2.xml configuration is read, the effective level will be ERROR

  4. Once your log4j2.xml configuration is read, the effective level will be WARN as you configured

Hence, unless you use either system properties or "log4j2.StatusLogger.properties" file in the classpath, there is a time window that only the defaults will be effective.

StatusLogger is designed as a singleton class accessed statically. If you are running an application containing multiple Log4j configurations (e.g., in a servlet environment with multiple containers), and you happen to have differing StatusLogger configurations (e.g, one log4j2.xml containing <Configuration status="ERROR"> while the other <Configuration status="INFO">), the last loaded configuration will be the effective one.

Properties

StatusLogger can be configured using the following system properties:

log4j2.debug

Env. variable

LOG4J_DEBUG

Type

boolean

Default value

false

If set to a value different from false, sets the level of the status logger to TRACE overriding any other system property.

log4j2.statusEntries

Env. variable

LOG4J_STATUS_ENTRIES

Type

int

Default value

0

Specifies the number of status logger entries to cache. Once the limit is reached newer entries will overwrite the oldest ones.

log4j2.statusLoggerLevel

Env. variable

LOG4J_STATUS_LOGGER_LEVEL

Type

Level

Default value

ERROR

Specifies the level of the status logger. Can be overridden by log4j2.debug.

log4j2.statusLoggerDateFormat

Env. variable

LOG4J_STATUS_LOGGER_DATE_FORMAT

Type

DateTimeFormatter pattern

Default value

DateTimeFormatter.ISO_INSTANT

Sets the DateTimeFormatter pattern used by status logger to format dates.

log4j2.statusLoggerDateFormatZone

Env. variable

LOG4J_STATUS_LOGGER_DATE_FORMAT_ZONE

Type

ZoneId

Default value

ZoneId.systemDefault()

Sets the timezone id used by status logger. See ZoneId for the accepted formats.

Debug mode

When the log4j2.debug system property is present, any level-related filtering will be skipped and all events will be notified to listeners. If no listeners are available, the fallback listener of type StatusConsoleListener will be used.

Listeners

Each recorded log event by StatusLogger will first get buffered and then used to notify the registered StatusListeners. If none are available, the fallback listener of type StatusConsoleListener will be used.

You can programmatically register listeners using the StatusLogger#registerListener(StatusListener) method.