diff --git a/log4j-1.2-api/.log4j-plugin-processing-activator b/log4j-1.2-api/.log4j-plugin-processing-activator
new file mode 100644
index 00000000000..ba133f36961
--- /dev/null
+++ b/log4j-1.2-api/.log4j-plugin-processing-activator
@@ -0,0 +1 @@
+This file is here to activate the `plugin-processing` Maven profile.
diff --git a/log4j-1.2-api/pom.xml b/log4j-1.2-api/pom.xml
index 58c18dd5bcd..b9f286d49a7 100644
--- a/log4j-1.2-api/pom.xml
+++ b/log4j-1.2-api/pom.xml
@@ -16,17 +16,21 @@
~ limitations under the License.
-->
+
4.0.0
+
org.apache.logging.log4jlog4j${revision}../log4j-parent
+
log4j-1.2-api
- jar
+
Apache Log4j 1.x Compatibility APIThe Apache Log4j 1.x Compatibility API
+
org.apache.log4j
@@ -45,6 +49,7 @@
org.apache.logging.log4j.core
+
@@ -138,27 +143,6 @@
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
-
- org.apache.logging.log4j
- log4j-core
- ${project.version}
-
-
-
-
-
-
-
-
diff --git a/log4j-api/pom.xml b/log4j-api/pom.xml
index 853ebe4d4aa..d6910eed11e 100644
--- a/log4j-api/pom.xml
+++ b/log4j-api/pom.xml
@@ -28,7 +28,7 @@
Apache Log4j APIThe Apache Log4j API
- false
+ false
+
4.0.0
+
org.apache.logging.log4jlog4j
@@ -25,8 +27,10 @@
log4j-cassandra
+
Apache Log4j CassandraCassandra appender for Log4j.
+
-
-
- org.apache.logging.log4j
- log4j-core
- ${project.version}
-
-
-
-
-
-
diff --git a/log4j-core-java9/pom.xml b/log4j-core-java9/pom.xml
index 6b6c0e0b253..2cb3c3d07a2 100644
--- a/log4j-core-java9/pom.xml
+++ b/log4j-core-java9/pom.xml
@@ -30,6 +30,7 @@
9true
+ true
diff --git a/log4j-core-test/.log4j-plugin-processing-activator b/log4j-core-test/.log4j-plugin-processing-activator
new file mode 100644
index 00000000000..ba133f36961
--- /dev/null
+++ b/log4j-core-test/.log4j-plugin-processing-activator
@@ -0,0 +1 @@
+This file is here to activate the `plugin-processing` Maven profile.
diff --git a/log4j-core-test/pom.xml b/log4j-core-test/pom.xml
index 1155ed9989b..ac718f0e72b 100644
--- a/log4j-core-test/pom.xml
+++ b/log4j-core-test/pom.xml
@@ -16,7 +16,9 @@
~ limitations under the License.
-->
+
4.0.0
+
org.apache.logging.log4jlog4j
@@ -25,9 +27,10 @@
log4j-core-test
- jar
+
Apache Log4j Core TestsThe Apache Log4j Implementation Tests
+
9
@@ -351,21 +354,6 @@
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
-
- org.apache.logging.log4j
- log4j-core
- ${project.version}
-
-
-
-
-
org.apache.maven.pluginsmaven-surefire-plugin
diff --git a/log4j-core-test/src/main/resources/Log4j-config.xsd b/log4j-core-test/src/main/resources/Log4j-config.xsd
deleted file mode 100644
index a5ae2d28a52..00000000000
--- a/log4j-core-test/src/main/resources/Log4j-config.xsd
+++ /dev/null
@@ -1,1405 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The Advertiser plugin name which will be used to advertise individual FileAppender or SocketAppender configurations. The only
- Advertiser plugin provided is 'multicastdns".
-
-
-
-
-
- Either "err" for stderr, "out" for stdout, a file path, or a URL.
-
-
-
-
- The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
-
-
-
-
- The name of the configuration.
-
-
-
-
- A comma separated list of package names to search for plugins. Plugins are only loaded once per classloader so changing this value
- may not have any effect upon reconfiguration.
-
-
-
-
-
- Identifies the location for the classloader to located the XML Schema to use to validate the configuration. Only valid when strict
- is set to true. If not set no schema validation will take place.
-
-
-
-
-
- Specifies whether or not Log4j should automatically shutdown when the JVM shuts down. The shutdown hook is enabled by default but
- may be disabled by setting this attribute to "disable".
-
-
-
-
-
-
-
-
-
-
- Specifies how many milliseconds appenders and background tasks will get to shutdown when the JVM shuts down. Default is zero which
- mean that each appender uses its default timeout, and don't wait for background tasks.
-
-
-
-
-
- The level of internal Log4j events that should be logged to the console. Valid values for this attribute are "trace", "debug",
- "info", "warn", "error" and "fatal".
-
-
-
-
-
-
-
-
-
-
- Enables the use of the strict XML format. Not supported in JSON configurations.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL.
-
-
-
-
- Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- One or more KeyValuePair elements that define the matching value for the key and the Level to evaluate when the key matches.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The average number of events per second to allow.
-
-
-
-
- The maximum number of events that can occur before events are filtered for exceeding the average rate. The default is 10 times
- the rate.
-
-
-
-
-
- Level of messages to be filtered. Anything at or below this level will be filtered out if maxBurst has been exceeded. The
- default is WARN meaning any messages that are higher than warn will be logged regardless of the size of a burst.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The filter type, see https://logging.apache.org/log4j/2.x/manual/filters.html
-
-
-
-
-
-
-
-
-
-
-
-
- The name of the item in the ThreadContext Map to compare.
-
-
-
-
-
- Level of messages to be filtered. The default threshold only applies if the log event contains the specified ThreadContext Map
- item and its value does not match any key in the key/value pairs.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The location of the configuration for the filter.
-
-
-
-
-
-
- The frequency in seconds that the configuration file should be checked for modifications.
-
-
-
-
-
-
- If the operator is "or" then a match by any one of the key/value pairs will be considered to be a match, otherwise all the
- key/value pairs must match.
-
-
-
-
-
-
-
-
-
-
-
-
-
- If the operator is "or" then a match by any one of the key/value pairs will be considered to be a match, otherwise all the
- key/value pairs must match.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The regular expression.
-
-
-
-
- If true the unformatted message will be used, otherwise the formatted message will be used.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- If the operator is "or" then a match by any one of the key/value pairs will be considered to be a match, otherwise all the
- key/value pairs must match.
-
-
-
-
-
-
-
-
-
-
-
-
- A valid Level name to match on.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- If true exceptions are always written even if the pattern contains no exception conversions.
-
-
-
-
- The character set to use when converting the syslog String to a byte array.
-
-
-
-
- If true, do not output ANSI escape codes.
-
-
-
-
- Footer string to include at the bottom of each log file.
-
-
-
-
- Header string to include at the top of each log file.
-
-
-
-
- If true and System.console() is null, do not output ANSI escape codes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- One or more KeyValuePair elements that define custom field in the output.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- One or more KeyValuePair elements that define custom field in the output.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The name of the appender.
-
-
-
-
-
- The default is true, causing exceptions encountered while appending events to be internally logged and then ignored.
- When set to false
- exceptions will be propagated to the caller, instead.
- You must set this to false when wrapping this Appender in a FailoverAppender.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Write directly to java.io.FileDescriptor and bypass java.lang.System.out/.err. Can give up to 10x performance boost when the
- output is redirected to file or other process. Cannot be used with Jansi on Windows. Cannot be used with follow.
-
-
-
-
-
-
- Identifies whether the appender honors reassignments of System.out or System.err via System.setOut or System.setErr made after
- configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with direct.
-
-
-
-
-
- Default is SYSTEM_OUT.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- One or more KeyValuePair elements that define the matching value for the key and the Level to evaluate when the
- key
- matches.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- When true, records will be appended to the end of the file.
- When set to false, the file will be cleared before new records are
- written.
-
-
-
-
-
-
-
-
- The name of the file to write to. If the file, or any of its parent directories, do not exist, they will be created.
-
-
-
-
-
-
- When set to true, each write will be followed by a flush.
- This will guarantee that the data is passed to the operating system for writing;
- it does not guarantee that the data is actually written to a physical device
- such as a disk drive.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- When true, records will be written to a buffer and the data will be written to disk when the buffer is full or, if
- immediateFlush is set, when the record is written.
- File locking cannot be used with bufferedIO.
-
-
-
-
-
- When bufferedIO is true, this is the buffer size, the default is 8192 bytes.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The appender creates the file on-demand. The appender only creates the file when a log event passes all filters and is routed
- to this appender.
-
-
-
-
-
-
- File attribute permissions in POSIX format to apply whenever the file is created.
- Underlying files system shall support POSIX
- file attribute view.
-
-
-
-
-
-
- File owner to define whenever the file is created.
- Underlying files system shall support POSIX file attribute view.
-
-
-
-
-
-
- File group to define whenever the file is created.
- Underlying files system shall support POSIX file attribute view.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The length of the mapped region, defaults to 32 MB (32 * 1024 * 1024 bytes). This parameter must be a value between 256 and
- 1,073,741,824 (1 GB or 2^30); values outside this range will be adjusted to the closest valid value. Log4j will round the specified value
- up to the nearest power of two.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The pattern of the file name of the archived log file.
- The format of the pattern is dependent on the RolloverPolicy that is
- used.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The cron expression. The expression is the same as what is allowed in the Quartz scheduler.
-
-
-
-
-
- On startup the cron expression will be evaluated against the file's last modification timestamp. If the cron expression indicates a
- rollover should have occurred between that time and the current time the file will be immediately rolled over.
-
-
-
-
-
-
-
-
-
- The minimum size the file must have to roll over. A size of zero will cause a roll over no matter what the file size is. The default
- value is 1, which will prevent rolling over an empty file.
-
-
-
-
-
-
-
-
-
- The size can be specified in bytes, with the suffix KB, MB or GB, for example 20MB.
-
-
-
-
-
-
-
-
-
- How often a rollover should occur based on the most specific time unit in the date pattern.
-
-
-
-
-
-
- Indicates whether the interval should be adjusted to cause the next rollover to occur on the interval boundary.
-
-
-
-
-
-
- Indicates the maximum number of seconds to randomly delay a rollover. By default, this is 0 which indicates no delay.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sets the compression level, 0-9, where 0 = none, 1 = best speed, through 9 = best compression. Only implemented for ZIP files.
-
-
-
-
-
-
- If set to "max", files with a higher index will be newer than files with a smaller index.
- If set to "min", file renaming and the
- counter will follow the Fixed Window strategy described above.
-
-
-
-
-
-
-
-
-
-
-
-
-
- The maximum value of the counter. Once this values is reached older archives will be deleted on subsequent rollovers.
-
-
-
-
-
- The minimum value of the counter.
-
-
-
-
-
- The pattern of the file name of the archived log file during compression.
-
-
-
-
-
-
-
-
-
-
-
- Sets the compression level, 0-9, where 0 = none, 1 = best speed, through 9 = best compression. Only implemented for ZIP files.
-
-
-
-
-
-
- The maximum number of files to allow in the time period matching the file pattern. If the number of files is exceeded the oldest file
- will be deleted. If specified, the value must be greater than 1. If the value is less than zero or omitted then the number of files will not be
- limited.
-
-
-
-
-
- The pattern of the file name of the archived log file during compression.
-
-
-
-
- Defines whether to stop executing asynchronous actions if an error occurs.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Allow boolean values or variable place holders in the form of ${variablename}
-
-
-
-
-
-
-
-
- Allow long values or variable place holders in the form of ${variablename}
-
-
-
-
-
-
-
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
deleted file mode 100644
index 685f4bd7bc1..00000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
+++ /dev/null
@@ -1,103 +0,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.
- */
-package org.apache.logging.log4j.core.config.xml;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Stream;
-import javax.xml.XMLConstants;
-import javax.xml.transform.sax.SAXSource;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.XMLFilterImpl;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-public class XmlSchemaTest {
-
- private static final String TARGET_NAMESPACE = "http://logging.apache.org/log4j/2.0/config";
-
- private static final List IGNORE_CONFIGS = Arrays.asList( //
- "log4j2-arbiters.xml", // Arbiters violate XML schema as they can appear anywhere
- "log4j2-environmentArbiters.xml",
- "log4j2-scriptArbiters.xml",
- "log4j2-systemPropertyArbiters.xml",
- "log4j2-selectArbiters.xml",
- "log4j-core-gctests/src/test/resources/gcFreeLogging.xml", // has 2 tags defined
- "legacy-plugins.xml", //
- "logback", // logback configs
- "log4j-xinclude", //
- "log4j12", // log4j 1.x configs
- "perf-CountingNoOpAppender.xml", // uses test-appender CountingNoOp
- "reconfiguration-deadlock.xml", // uses test-appender ReconfigurationDeadlockTestAppender
- "AsyncWaitStrategy", // uses AsyncWaitStrategyFactory (LOG4J2-3472)
- "XmlConfigurationSecurity.xml", // used for testing XML parser; shouldn't be parseable in secure settings
- "InvalidConfig.xml",
- "InvalidXML.xml");
-
- static Stream testXmlSchemaValidation() throws IOException {
- return Files.list(Paths.get("src", "test", "resources")).filter(filePath -> {
- final String fileName = filePath.getFileName().toString();
- if (!fileName.endsWith(".xml")) return false;
- for (final String ignore : IGNORE_CONFIGS) {
- if (fileName.contains(ignore)) return false;
- }
- return true;
- });
- }
-
- @ParameterizedTest
- @MethodSource
- public void testXmlSchemaValidation(final Path filePath) throws SAXException, IOException {
- final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- final Schema schema = factory.newSchema(new StreamSource(getClass().getResourceAsStream("/Log4j-config.xsd")));
- final Validator validator = schema.newValidator();
-
- final XMLFilterImpl namespaceAdder = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
- @Override
- public void startElement(
- final String namespace, final String localName, final String qName, final Attributes atts)
- throws SAXException {
- super.startElement(TARGET_NAMESPACE, localName, qName, atts);
- }
- };
-
- final InputSource source = new InputSource(filePath.toAbsolutePath().toString());
- final SAXSource transformedSource = new SAXSource(namespaceAdder, source);
- assertDoesNotThrow(() -> {
- try {
- validator.validate(transformedSource);
- } catch (SAXParseException e) {
- // Wrap the exception to capture the location
- throw new RuntimeException(e.toString(), e);
- }
- });
- }
-}
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 4fa7392c89b..0f9429a41e4 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -16,19 +16,27 @@
~ limitations under the License.
-->
+
4.0.0
+
org.apache.logging.log4jlog4j${revision}../log4j-parent
+
log4j-core
- jar
+
Apache Log4j CoreThe Apache Log4j Implementation
+
- false
+
+ false
+
+
+ trueorg.codehaus.mojobuild-helper-maven-plugin
@@ -222,40 +233,68 @@
+
maven-compiler-plugin
-
-
-
+
+
-
default-compile
-
-
-
- com.google.errorprone
- error_prone_core
- ${error-prone.version}
-
-
-
+
+
-
process-pluginscompileprocess-classes
+
+
+
+ org.apache.logging.log4j
+ log4j-docgen
+ ${log4j-docgen.version}
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${project.version}
+
+
+
+ org.apache.logging.log4j.docgen.processor.DescriptorGenerator
+
org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor
-
+
+
+ -Alog4j.docgen.descriptorFilePath=${log4j.docgen.pluginDescriptorsDir.phase1}/${project.artifactId}-plugins.xml
+ -Alog4j.docgen.groupId=${project.groupId}
+ -Alog4j.docgen.artifactId=${project.artifactId}
+ -Alog4j.docgen.version=${project.version}
+ -Alog4j.docgen.description=${project.description}
+ -Alog4j.docgen.typeFilter.excludePattern=${log4j.docgen.typeFilter.excludePattern}
+ only
+
@@ -291,4 +330,5 @@
+
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java
index 87e439a5f2a..3519980c2ad 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ScriptCondition.java
@@ -89,8 +89,8 @@ public List selectFilesToDelete(
*
pathList - a {@code java.util.List} containing {@link org.apache.logging.log4j.core.appender.rolling.action.PathWithAttributes} objects. (The script is
* free to modify and return this list.)
*
substitutor - a {@link org.apache.logging.log4j.core.lookup.StrSubstitutor} that can be used to look up variables embedded in the base
- * dir or other properties
- *
statusLogger - the {@link StatusLogger} that can be used to log events during script execution
+ * dir or other properties
+ *
statusLogger - the {@link StatusLogger} that can be used to log events during script execution
diff --git a/src/template/docgen/index.adoc.ftl b/src/template/docgen/index.adoc.ftl
new file mode 100644
index 00000000000..9dc1d8c733c
--- /dev/null
+++ b/src/template/docgen/index.adoc.ftl
@@ -0,0 +1,59 @@
+<#ftl output_format="plainText" strip_whitespace=true>
+<#--
+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
+
+https://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.
+-->
+<#-- @ftlvariable name="lookup" type="org.apache.logging.log4j.docgen.generator.TypeLookup" -->
+
+= Plugin reference
+
+This page is a Javadoc-on-steroids specialized for Log4j plugins.
+This reference manual is derived from the source code of all Log4j plugins and types associated with them.
+You can use this reference manual to precisely customize your `log4j2.xml`.
+
+[INFO]
+====
+Every running Log4j system is a constellation of xref:../manual/plugins.adoc[plugins], which is analogous to beans in Java EE and Spring.
+This not only allows Log4j itself to be developed in individual components, but also enables extensibility users can leverage.
+====
+
+[#shortcuts]
+== Shortcuts
+
+* xref:#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Configuration[The `` element assembly in a `log4j2.xml`]
+* xref:#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Appender[The type hierarchy of *appenders*]
+* xref:#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Layout[The type hierarchy of *layouts*]
+* xref:#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Filter[The type hierarchy of *filters*]
+
+[#index]
+== Index
+
+Below is a list of all types reachable by plugins grouped by the Maven coordinate of the artifact bundling them.
+
+<#assign sourcedTypes = lookup?values/>
+<#-- @ftlvariable name="sourcedTypes" type="org.apache.logging.log4j.docgen.generator.ArtifactSourcedType[]" -->
+<#assign lastGroupId = ''/>
+<#assign lastArtifactId = ''/>
+<#list sourcedTypes?sort_by('artifactId', 'groupId', ['type', 'className']) as sourcedType>
+ <#if sourcedType.groupId != lastGroupId || sourcedType.artifactId != lastArtifactId>
+ <#assign lastGroupId = sourcedType.groupId/>
+ <#assign lastArtifactId = sourcedType.artifactId/>
+
+[#${sourcedType.groupId?replace('.', '-')}_${sourcedType.artifactId?replace('.', '-')}]
+=== `${sourcedType.groupId}:${sourcedType.artifactId}`
+
+ #if>
+include::_plugin-reference/${sourcedType.groupId}-${sourcedType.artifactId}-${sourcedType.type.className}.adoc[leveloffset=+4]
+#list>
diff --git a/src/template/docgen/type.adoc.ftl b/src/template/docgen/type.adoc.ftl
new file mode 100644
index 00000000000..48f8dc24781
--- /dev/null
+++ b/src/template/docgen/type.adoc.ftl
@@ -0,0 +1,133 @@
+<#ftl output_format="plainText" strip_whitespace=true>
+<#--
+ 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
+
+ https://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.
+-->
+<#-- @ftlvariable name="sourcedType" type="org.apache.logging.log4j.docgen.model.ArtifactSourcedType" -->
+<#assign type = sourcedType.type/>
+<#-- @ftlvariable name="type" type="org.apache.logging.log4j.docgen.Type" -->
+<#-- @ftlvariable name="lookup" type="org.apache.logging.log4j.docgen.generator.TypeLookup" -->
+
+[#${sourcedType.groupId?replace('.', '-')}_${sourcedType.artifactId?replace('.', '-')}_${type.className?replace('.', '-')}]
+= ${type.name!('`' + type.className + '`')}
+
+Class:: `${type.className}`
+Provider:: `${sourcedType.groupId}:${sourcedType.artifactId}`
+
+${(type.description.text)!}
+
+<#assign hasElements = ((type.elements?size)!0) != 0/>
+<#if type.class.simpleName == 'PluginType'>
+ <#-- @ftlvariable name="type" type="org.apache.logging.log4j.docgen.PluginType" -->
+[#${sourcedType.groupId?replace('.', '-')}_${sourcedType.artifactId?replace('.', '-')}_${type.className?replace('.', '-')}_XML-snippet]
+== XML snippet
+[source, xml]
+----
+ <#assign tag><${type.name} #assign>
+ <#assign indent = tag?replace('.', ' ', 'r')/>
+ <#if !type.attributes?has_content>
+<${type.name}/>
+ <#else>
+ <#list type.attributes?sort_by('name') as attr>
+ <#if attr?is_first>
+${tag}${attr.name}="${attr.defaultValue!}"${attr?is_last?then(hasElements?then('>', '/>'), '')}
+ <#else>
+${indent}${attr.name}="${attr.defaultValue!}"${attr?is_last?then(hasElements?then('>', '/>'), '')}
+ #if>
+ #list>
+ <#if hasElements>
+ <#list type.elements as element>
+ <#assign multiplicitySuffix = (element.multiplicity == '*')?then('','')/>
+ <#assign elementName = 'a-' + element.type?keep_after_last('.') + '-implementation'/>
+ <#if lookup[element.type]??>
+ <#assign element_type = lookup[element.type].type/>
+ <#-- @ftlvariable name="element_type" type="org.apache.logging.log4j.docgen.model.AbstractType" -->
+ <#if element_type.name?? && !element_type.implementations?has_content>
+ <#assign elementName = element_type.name/>
+ #if>
+ #if>
+ <${elementName}/>${multiplicitySuffix}
+ #list>
+${type.name}>
+ #if>
+ #if>
+----
+#if>
+<#if type.attributes?has_content>
+
+[#${sourcedType.groupId?replace('.', '-')}_${sourcedType.artifactId?replace('.', '-')}_${type.className?replace('.', '-')}-attributes]
+== Attributes
+
+Optional attributes are denoted by `?`-suffixed types.
+
+[cols="1m,1m,1m,5"]
+|===
+|Name|Type|Default|Description
+
+ <#list type.attributes?sort_by('name') as attr>
+ <#assign requirementSuffix = attr.required?then('', '?')/>
+|${attr.name}
+ <#assign attrTypeName = attr.type?contains('.')?then(attr.type?keep_after_last('.'), attr.type)/>
+ <#if lookup[attr.type]??>
+ <#assign attrSourcedType = lookup[attr.type]/>
+|xref:#${attrSourcedType.groupId?replace('.', '-')}_${attrSourcedType.artifactId?replace('.', '-')}_${attr.type?replace('.', '-')}[${attrTypeName}]${requirementSuffix}
+ <#else>
+|${attrTypeName}${requirementSuffix}
+ #if>
+|${attr.defaultValue!}
+a|${(attr.description.text)!}
+
+ #list>
+|===
+#if>
+<#if hasElements>
+
+[#${sourcedType.groupId?replace('.', '-')}_${sourcedType.artifactId?replace('.', '-')}_${type.className?replace('.', '-')}_components]
+== Nested components
+
+Optional components are denoted by `?`-suffixed types.
+
+[cols="1m,1m,5"]
+|===
+|Tag|Type|Description
+
+ <#list type.elements?sort_by('type') as element>
+ <#assign requirementSuffix = element.required?then('', '?')/>
+ <#assign descriptionCell = (element.description.text)!/>
+ <#assign elementName = element.type?contains('.')?then(element.type?keep_after_last('.'), element.type)/>
+ <#if lookup[element.type]??>
+ <#assign elementSourcedType = lookup[element.type]/>
+ <#assign tagCell = elementSourcedType.type.name!/>
+|${tagCell}
+|xref:#${elementSourcedType.groupId?replace('.', '-')}_${elementSourcedType.artifactId?replace('.', '-')}_${element.type?replace('.', '-')}[${elementName}]${requirementSuffix}
+ <#else>
+|
+|${elementName}${requirementSuffix}
+ #if>
+a|${descriptionCell}
+
+ #list>
+|===
+#if>
+<#if type.implementations?has_content>
+
+[#${sourcedType.groupId?replace('.', '-')}_${sourcedType.artifactId?replace('.', '-')}_${type.className?replace('.', '-')}_implementations]
+== Known implementations
+
+ <#list type.implementations as impl>
+ <#assign implSourcedType = lookup[impl]/>
+* xref:#${implSourcedType.groupId?replace('.', '-')}_${implSourcedType.artifactId?replace('.', '-')}_${impl?replace('.', '-')}[${impl?contains('.')?then(impl?keep_after_last('.'), impl)}]
+ #list>
+#if>