////
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
////

= 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:

* Log4j API
** xref:manual/customloglevels.adoc[Extending levels]
** xref:manual/markers.adoc[Extending markers]
** xref:manual/messages.adoc#extending[Extending messages]
** xref:manual/thread-context.adoc#extending[Extending thread context]
* Log4j Core
** xref:manual/appenders.adoc#extending[Extending appenders]
** xref:manual/filters.adoc#extending[Extending filters]
** xref:manual/layouts.adoc#extending[Extending layouts]
*** xref:manual/json-template-layout.adoc#extending[Extending JSON Template Layout]
*** xref:manual/pattern-layout.adoc#extending[Extending Pattern Layout]
** xref:manual/lookups.adoc#extending[Extending lookups]

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

[#mechanisms]
== Extension mechanisms

Log4j allows extensions primarily using following mechanisms:

[#Custom_Plugins]
=== Plugins

include::partial$manual/plugin-preliminaries.adoc[]

[#service-loader]
=== ``ServiceLoader``s

https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/ServiceLoader.html[`ServiceLoader`] is a simple service-provider loading facility baked into the Java platform itself.
Log4j uses ``ServiceLoader``s for extending places where

* The service needs to be implementation agnostic.
As a result, <<Custom_Plugins,the Log4j plugin system>> cannot be used, since it is provided by the logging implementation, i.e., Log4j Core.
For instance, this is why xref:manual/thread-context.adoc#extending[extending Thread Context], which is a Log4j API component, works using ``ServiceLoader``s.

* The service needs to be loaded before <<Custom_Plugins,the Log4j plugin system>>.
For instance, this is why <<Provider,extending `Provider`>> works using ``ServiceLoader``s.

Refer to https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/ServiceLoader.html[the `ServiceLoader` documentation] for details.

[#system-properties]
=== System properties

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

[WARNING]
====
Loading a class using _only_ its FQCN can result in unexpected behaviour when there are multiple class loaders.
====

[#points]
== Extension points

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

[#Provider]
=== `Provider`

link:../javadoc/log4j-api/org/apache/logging/log4j/spi/Provider.html[`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, link:../javadoc/log4j-api/org/apache/logging/log4j/LogManager.html[`LogManager`] locates a `Provider` implementation using <<service-loader,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 ``Provider``s in the classpath is strongly discouraged.
Yet when this happens, you can use xref:manual/systemproperties.adoc#log4j2.provider[the `log4j2.provider` property] to explicitly select one.

[#LoggerContextFactory]
=== `LoggerContextFactory`

link:../javadoc/log4j-api/org/apache/logging/log4j/spi/LoggerContextFactory.html[`LoggerContextFactory`] is the factory class used by Log4j API implementations to create xref:manual/architecture.adoc#LoggerContext[`LoggerContext`]s.
If you are using Log4j Core, you can use <<ContextSelector>>s to influence the way its `LoggerContextFactory` implementation works.
If you are creating a new Log4j API implementation, you should <<Provider,provide a custom `Provider`>> to introduce your custom `LoggerContextFactory` implementation.

[#ContextSelector]
=== `ContextSelector`

link:../javadoc/log4j-core/org/apache/logging/log4j/core/impl/Log4jContextFactory.html[`Log4jContextFactory`], the Log4j Core implementation of <<LoggerContextFactory>>, delegates the actual work to a link:../javadoc/log4j-core/org/apache/logging/log4j/core/selector/ContextSelector.html[`ContextSelector`].
It can be configured using xref:manual/systemproperties.adoc#log4j2.contextSelector[the `log4j2.contextSelector` property].

[#ConfigurationFactory]
=== `ConfigurationFactory`

link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/ConfigurationFactory.html[`ConfigurationFactory`] is the factory class used by Log4j Core to create link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html[`Configuration`] instances given a xref:manual/architecture.adoc#LoggerContext[`LoggerContext`] and a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/ConfigurationSource.html[`ConfigurationSource`].

You can provide a custom `ConfigurationFactory` in the form of a <<Custom_Plugins,plugin>>.
For example, see {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfigurationFactory.java[`XmlConfigurationFactory.java`] and {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java[`XmlConfiguration.java`] of Log4j Core.

You can use xref:manual/systemproperties.adoc#log4j2.configurationFactory[the `log4j2.configurationFactory` property] to explicitly set a `ConfigurationFactory` to be used before any other factory implementation.

[#LoggerConfig]
=== `LoggerConfig`

link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/LoggerConfig.html[`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 <<Custom_Plugins,plugin>>
** Its plugin `category` should be set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]

For example, see `RootLogger` definition in {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java[`LoggerConfig.java`].

[#LogEventFactory]
=== `LogEventFactory`

Log4j Core uses link:../javadoc/log4j-core/org/apache/logging/log4j/core/impl/LogEventFactory.html[`LogEventFactory`] to create link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[`LogEvent`]s.
You can replace the default `LogEventFactory` implementation with a custom one of yours by using xref:manual/systemproperties.adoc#log4j2.logEventFactory[the `log4j2.logEventFactory` property].

[NOTE]
====
xref:manual/async.adoc[] discard `LogEventFactory` and any configuration related with it.
====

[#MessageFactory]
=== `MessageFactory2`

Log4j Core uses link:../javadoc/log4j-api/org/apache/logging/log4j/message/MessageFactory2.html[`MessageFactory2`] to create link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`]s.
You can replace the default `MessageFactory2` implementation with a custom one of yours by using xref:manual/systemproperties.adoc#log4j2.messageFactory[the `log4j2.messageFactory` property].

In the case of xref:manual/flowtracing.adoc[], Log4j Core uses link:../javadoc/log4j-api/org/apache/logging/log4j/message/FlowMessageFactory.html[`FlowMessageFactory`].
You can replace the default `FlowMessageFactory` implementation with a custom one of yours by using xref:manual/systemproperties.adoc#log4j2.flowMessageFactory[the `log4j2.flowMessageFactory` property].

[IMPORTANT]
====
Message factory implementations are expected to interpret formatting patterns containing placeholders denoted with `{}`.
For instance, the default message factory chooses between a xref:manual/messages.adoc#SimpleMessage[`SimpleMessage`] and a xref:manual/messages.adoc#ParameterizedMessage[`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 link:../javadoc/log4j-api/org/apache/logging/log4j/LogManager.html[`LogManager`] methods accepting a message factory to create ``Logger``s with your custom message factory implementations.
====
