<?xml version="1.0"?>
<!--
    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.
-->

<document xmlns="http://maven.apache.org/XDOC/2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
    <properties>
        <title>Log4j 2 Plugins</title>
        <author email="rgoers@apache.org">Ralph Goers</author>
        <author email="mattsicker@apache.org">Matt Sicker</author>
    </properties>

    <body>
      <section name="Plugins">
        <subsection name="Introduction">
          <a name="Introduction"/>
          <p>
            Log4j 1.x allowed for extension by requiring class attributes on most of the configuration
            declarations. In the case of some elements, notably the PatternLayout, the only way to add
            new pattern converters was to extend the PatternLayout class and add them via code. One of
            goals of Log4j 2 is to make extending it extremely easy through the use of plugins.
          </p>
          <p>
            In Log4j 2 a plugin is declared by adding a
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/Plugin.html">@Plugin</a>
            annotation to the class declaration. During initialization the
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/Configuration.html">Configuration</a>
            will invoke the
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/util/PluginManager.html">PluginManager</a>
            to load the built-in Log4j plugins as well as any custom plugins. The <code>PluginManager</code> locates
            plugins by looking in four places:
          </p>
          <ul>
            <li>Serialized plugin listing files on the classpath. These files are generated automatically during
              the build (more details below).</li>
            <li>(OSGi only) Serialized plugin listing files in each active OSGi bundle. A <code>BundleListener</code>
              is added on activation to continue checking new bundles after <code>log4j-core</code> has started.</li>
            <li>A comma-separated list of packages specified by the <code>log4j.plugin.packages</code>
              system property.</li>
            <li>Packages passed to the static <code>PluginManager.addPackages</code> method (before Log4j configuration
              occurs).</li>
            <li>The <a href="./configuration.html#ConfigurationSyntax">packages</a> declared in your log4j2
              configuration file.</li>
          </ul>
          <p>
            If multiple Plugins specify the same (case-insensitive) <code>name</code>, then the load order above
            determines which one will be used. For example, to override the <code>File</code> plugin which is provided
            by the built-in <code>FileAppender</code> class, you would need to place your plugin in a JAR file in the
            CLASSPATH ahead of<code>log4j-core.jar</code>. This is not recommended; plugin name collisions will cause a
            warning to be emitted. Note that in an OSGi environment, the order that bundles are scanned for plugins
            generally follows the same order that bundles were installed into the framework. See
            <a class="javadoc" href="http://www.osgi.org/javadoc/r5/core/org/osgi/framework/BundleContext.html#getBundles()">getBundles()</a>
            and
            <a class="javadoc" href="http://www.osgi.org/javadoc/r5/core/org/osgi/framework/SynchronousBundleListener.html">SynchronousBundleListener</a>.
            In short, name collisions are even more unpredictable in an OSGi environment.
            <!--
            TODO: in future, plugins will be able to be annotated with @Order which can override priorities
            -->
          </p>
          <p>
            Serialized plugin listing files are generated by an annotation processor contained in the
            log4j-core artifact which will automatically scan your code for Log4j 2 plugins and output a metadata
            file in your processed classes. There is nothing extra that needs to be done to enable this; the Java
            compiler will automatically pick up the annotation processor on the class path unless you explicitly
            disable it. In that case, it would be important to add another compiler pass to your build process that
            only handles annotation processing using the Log4j 2 annotation processor class,
            <code>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</code>. To do this using
            Apache Maven, add the following execution to your <i>maven-compiler-plugin</i> (version 2.2 or higher)
            build plugin:
          </p>
          <pre class="prettyprint linenums"><![CDATA[
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.1</version>
  <executions>
    <execution>
      <id>log4j-plugin-processor</id>
      <goals>
        <goal>compile</goal>
      </goals>
      <phase>process-classes</phase>
      <configuration>
        <proc>only</proc>
        <annotationProcessors>
          <annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor>
        </annotationProcessors>
      </configuration>
    </execution>
  </executions>
</plugin>
          ]]></pre>
          <p>
            As the configuration is processed the appropriate plugins will be automatically configured and
            initialized.  Log4j 2 utilizes a few different categories of plugins which are described in the following
            sections.
          </p>
        </subsection>
        <subsection name="Core">
          <a name="Core"/>
          <p>
            Core plugins are those that are directly represented by an element in a configuration file, such as an
            Appender, Logger or Filter. Custom plugins that conform to the rules laid out in the next paragraph
            may simply be referenced in the configuration, provided they are appropriate configured to be
            loaded by the PluginManager.
          </p>
          <p>
            Every Core plugin must declare a static method that is marked with a PluginFactory annotation. To
            allow the Configuration to pass the correct parameters to the method, every
            parameter to the method must be annotated as one of the following attribute types. Each
            attribute or element annotation must include the name that must be present in the configuration
            in order to match the configuration item to its respective parameter.
          </p>
          <h4>Attribute Types</h4>
            <dl>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginAttribute.html">PluginAttribute</a></dt>
              <dd>The parameter must be convertible from a String using a <a href="#TypeConverters">TypeConverter</a>.
              Most built-in types are already supported, but custom <code>TypeConverter</code> plugins may also be
              provided for more type support.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginElement.html">PluginElement</a></dt>
              <dd>The parameter may represent a complex object that itself has parameters that can be configured.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.html">PluginConfiguration</a></dt>
              <dd>The current <code>Configuration</code> object will be passed to the plugin as a parameter.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginNode.html">PluginNode</a></dt>
              <dd>The current <code>Node</code> being parsed will be passed to the plugin as a parameter.</dd>
              <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/validation/constraints/Required.html">Required</a></dt>
              <dd>While not strictly an attribute, this annotation can be added to any plugin factory parameter to
              make it automatically validated as non-<code>null</code> and non-empty.</dd>
            </dl>
        </subsection>
        <subsection name="Converters">
          <a name="Converters"/>
          <p>
            Converters are used by
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html">PatternLayout</a>
            to render the elements identified by the conversion pattern. Every converter must specify its type as
            "Converter" on the Plugin attribute, have a static newInstance method that accepts an array of Strings as
            its only parameter and returns an instance of the Converter, and must have a ConverterKeys annotation
            present that contains the array of converter patterns that will cause the Converter to be selected.
            Converters that are meant to handle LogEvents must extend the LogEventPatternConverter class and
            must implement a format method that accepts a LogEvent and a StringBuilder as arguments. The Converter
            should append the result of its operation to the StringBuilder.
          </p>
          <p>
            A second type of Converter is the FileConverter - which must have "FileConverter" specified in the
            type attribute of the Plugin annotation. While similar to a LogEventPatternConverter, instead
            of a single format method these Converters will have two variations; one that takes an Object and
            one that takes an array of Objects instead of the LogEvent. Both append to the provided StringBuilder
            in the same fashion as a LogEventPatternConverter. These Converters are typically used by the
            RollingFileAppender to construct the name of the file to log to.
          </p>
          <p>
            If multiple Converters specify the same <code>ConverterKeys</code>, then the load order above determines
            which one will be used. For example, to override the <code>%date</code> converter which is provided by the
            built-in <code>DatePatternConverter</code> class, you would need to place your plugin in a JAR file in the
            CLASSPATH ahead of<code>log4j-core.jar</code>. This is not recommended; pattern ConverterKeys collisions
            will cause a warning to be emitted. Try to use unique ConverterKeys for your custom pattern converters.
          </p>
        </subsection>
        <subsection name="KeyProviders">
          <a name="KeyProviders"/>
          <p>
          Some components within Log4j may provide the ability to perform data encryption. These components require
          a secret key to perform the encryption. Applications may provide the key by creating a class that
          implements the
          <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/util/SecretKeyProvider.html">SecretKeyProvider</a>
          interface.
          </p>
        </subsection>
        <subsection name="Lookups">
          <a name="Lookups"/>
          <p>
            Lookups are perhaps the simplest plugins of all. They must declare their type as "Lookup" on the
            plugin annotation and must implement the
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html">StrLookup</a>
            interface. They will have two methods; a
            lookup method that accepts a String key and returns a String value and a second lookup method that
            accepts both a LogEvent and a String key and returns a String. Lookups may be referenced by
            specifying ${<var>name</var>:key} where <var>name</var> is the name specified in the Plugin annotation and
            key is the name of the item to locate.
          </p>
        </subsection>
        <subsection name="TypeConverters">
          <a name="TypeConverters"/>
          <p>
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html">TypeConverter</a>s
            are a sort of meta-plugin used for converting strings into other types in a plugin factory method
            parameter. Other plugins can already be injected via the <code>@PluginElement</code> annotation; now, any
            type supported by the type conversion system can be used in a <code>@PluginAttribute</code> parameter.
            Conversion of enum types are supported on demand and do not require custom <code>TypeConverter</code>
            classes. A large number of built-in Java classes are already supported; see
            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.html">TypeConverters</a>
            for a more exhaustive listing.
          </p>
          <p>
            Unlike other plugins, the plugin name of a <code>TypeConverter</code> is purely cosmetic. Appropriate
            type converters are looked up via the <code>Type</code> interface rather than via <code>Class&lt;?&gt;</code>
            objects only. Do note that <code>TypeConverter</code> plugins must have a default constructor.
          </p>
        </subsection>
      </section>
      <section name="Developer Notes">
        <a name="DeveloperNotes"/>
        <p>
          If a plugin class implements
          <a class="javadoc" href="http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html">Collection</a> or
          <a class="javadoc" href="http://docs.oracle.com/javase/6/docs/api/java/util/Map.html">Map</a>, then no
          factory method is used. Instead, the class is instantiated using the default constructor, and all child
          configuration nodes are added to the <code>Collection</code> or <code>Map</code>.
        </p>
      </section>
    </body>
</document>
