| //// |
| 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. |
| ==== |