Extending

Log4j provides numerous extension points to adapt it for custom needs. Several of such extension points are covered in the page of the associated component:

This section guides you on the rest of the Log4j extension points.

Extension mechanisms

Log4j allows extensions primarily using following mechanisms:

Plugins

Log4j plugin system is the de facto extension mechanism embraced by various Log4j components. Plugins provide extension points to components, that can be used to implement new features, without modifying the original component. It is analogous to a dependency injection framework, but curated for Log4j-specific needs.

In a nutshell, you annotate your classes with @Plugin and their (static) factory methods with @PluginFactory. Last, you inform the Log4j plugin system to discover these custom classes. This is done using running the PluginProcessor annotation processor while building your project. Refer to Plugins for details.

ServiceLoaders

ServiceLoader is a simple service-provider loading facility baked into the Java platform itself. Log4j uses ServiceLoaders for extending places where

Refer to the ServiceLoader documentation for details.

System properties

Log4j uses system properties to determine the fully-qualified class name (FQCN) to load for extending a certain functionality. For instance, extending MessageFactory2 works using system properties.

Loading a class using only its FQCN can result in unexpected behaviour when there are multiple class loaders.

Extension points

In this section we will guide you on certain Log4j extension points that are not covered elsewhere.

Provider

Provider is the anchor contract binding Log4j API to an implementation. For instance, it has been implemented by Log4j Core, Log4j-to-JUL bridge, and Log4j-to-SLF4J bridge modules.

Under the hood, LogManager locates a Provider implementation using the ServiceLoader mechanism, and delegates invocations to it. Hence, you can extend it by providing a org.apache.logging.log4j.spi.Provider implementation in the form of a ServiceLoader.

Having multiple Providers in the classpath is strongly discouraged. Yet when this happens, you can use the log4j2.provider property to explicitly select one.

LoggerContextFactory

LoggerContextFactory is the factory class used by Log4j API implementations to create LoggerContexts. If you are using Log4j Core, you can use ContextSelectors to influence the way its LoggerContextFactory implementation works. If you are creating a new Log4j API implementation, you should provide a custom Provider to introduce your custom LoggerContextFactory implementation.

ContextSelector

Log4jContextFactory, the Log4j Core implementation of LoggerContextFactory, delegates the actual work to a ContextSelector. It can be configured using the log4j2.contextSelector property.

ConfigurationFactory

ConfigurationFactory is the factory class used by Log4j Core to create Configuration instances given a LoggerContext and a ConfigurationSource.

You can provide a custom ConfigurationFactory in the form of a plugin. For example, see XmlConfigurationFactory.java and XmlConfiguration.java of Log4j Core.

You can use the log4j2.configurationFactory property to explicitly set a ConfigurationFactory to be used before any other factory implementation.

LoggerConfig

LoggerConfig denotes the Logger configurations in a Configuration. A custom LoggerConfig needs to satisfy the following conditions:

  • It needs to extend from LoggerConfig class

  • It needs to be declared as a plugin

For example, see RootLogger definition in LoggerConfig.java.

LogEventFactory

Log4j Core uses LogEventFactory to create LogEvents. You can replace the default LogEventFactory implementation with a custom one of yours by using the log4j2.logEventFactory property.

Asynchronous loggers discard LogEventFactory and any configuration related with it.

MessageFactory2

Log4j Core uses MessageFactory2 to create Messages. You can replace the default MessageFactory2 implementation with a custom one of yours by using the log4j2.messageFactory property.

In the case of Flow Tracing, Log4j Core uses FlowMessageFactory. You can replace the default FlowMessageFactory implementation with a custom one of yours by using the log4j2.flowMessageFactory property.

Message factory implementations are expected to interpret formatting patterns containing placeholders denoted with {}. For instance, the default message factory chooses between a SimpleMessage and a ParameterizedMessage depending on the presence of placeholders in the formatting pattern.

If you want to change the placeholder style (e.g., switching from {} to %s), you should not replace the default message factory. Because this will break the existing Log4j API calls using the standard placeholder style. Instead, you can use LogManager methods accepting a message factory to create Loggers with your custom message factory implementations.