This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch doc/2.x/extending
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 65b9924f21d04e60271008a028c7a655d318a54a
Merge: d495947f48 2c8790d406
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Thu Jun 13 11:02:46 2024 +0200

    Merge remote-tracking branch 'origin/2.x' into doc/2.x/extending

 .github/workflows/labeler.yaml                     |   8 +-
 log4j-parent/pom.xml                               |   2 +-
 src/changelog/.2.x.x/update_io_netty_netty_bom.xml |   4 +-
 .../manual/migration/Migration1Example.java        |  33 +
 .../manual/migration/Migration2Example.java        |  32 +
 .../modules/ROOT/images/whichjar-log4j-1.2-api.png | Bin 24992 -> 0 bytes
 .../modules/ROOT/images/whichjar-log4j-api.png     | Bin 16515 -> 0 bytes
 src/site/antora/modules/ROOT/nav.adoc              |  12 +-
 src/site/antora/modules/ROOT/pages/faq.adoc        |   2 +-
 .../antora/modules/ROOT/pages/log4j-1.2-api.adoc   |  85 ---
 .../pages/log4j-spring-cloud-config-client.adoc    |   2 +-
 .../antora/modules/ROOT/pages/log4j-taglib.adoc    |   2 +-
 src/site/antora/modules/ROOT/pages/manual/api.adoc |   8 +-
 .../modules/ROOT/pages/manual/appenders.adoc       | 218 +++---
 .../antora/modules/ROOT/pages/manual/async.adoc    |  24 +-
 .../antora/modules/ROOT/pages/manual/cloud.adoc    |   2 +-
 .../modules/ROOT/pages/manual/configuration.adoc   |  35 +-
 .../modules/ROOT/pages/manual/customconfig.adoc    |   2 +-
 .../modules/ROOT/pages/manual/customloglevels.adoc |   2 +-
 .../modules/ROOT/pages/manual/eventlogging.adoc    |   4 +-
 .../modules/ROOT/pages/manual/extending.adoc       |   4 +-
 .../antora/modules/ROOT/pages/manual/filters.adoc  |   6 +-
 .../modules/ROOT/pages/manual/garbagefree.adoc     |  30 +-
 .../modules/ROOT/pages/manual/getting-started.adoc |  16 +-
 .../modules/ROOT/pages/manual/installation.adoc    |  16 +-
 src/site/antora/modules/ROOT/pages/manual/jmx.adoc |  11 +-
 .../ROOT/pages/manual/json-template-layout.adoc    | 112 +--
 .../antora/modules/ROOT/pages/manual/layouts.adoc  |  38 +-
 .../antora/modules/ROOT/pages/manual/logsep.adoc   |   2 +-
 .../antora/modules/ROOT/pages/manual/lookups.adoc  |  16 +-
 .../antora/modules/ROOT/pages/manual/messages.adoc |  38 +-
 .../modules/ROOT/pages/manual/migration.adoc       | 820 ++++++++++++---------
 .../modules/ROOT/pages/manual/pattern-layout.adoc  | 124 ++--
 .../modules/ROOT/pages/manual/performance.adoc     |   4 +-
 .../antora/modules/ROOT/pages/manual/plugins.adoc  |   2 +-
 .../antora/modules/ROOT/pages/manual/scripts.adoc  |   8 +-
 .../modules/ROOT/pages/manual/status-logger.adoc   |  10 +-
 .../ROOT/pages/manual/systemproperties.adoc        |  10 +-
 .../modules/ROOT/pages/manual/thread-context.adoc  |   4 +-
 .../antora/modules/ROOT/pages/manual/webapp.adoc   |   6 +-
 .../ROOT/partials/manual/async-trade-offs.adoc     |   3 +-
 .../manual/layouts-location-information.adoc       |   2 +-
 .../properties-async-logger-config.adoc            |  24 +-
 .../systemproperties/properties-async-logger.adoc  |  32 +-
 .../manual/systemproperties/properties-async.adoc  |  14 +-
 .../properties-configuration-factory.adoc          |  24 +-
 .../properties-context-selector.adoc               |  21 +-
 .../properties-garbage-collection.adoc             |  30 +-
 .../manual/systemproperties/properties-jansi.adoc  |   2 +-
 .../manual/systemproperties/properties-jmx.adoc    |   4 +-
 .../manual/systemproperties/properties-jndi.adoc   |  10 +-
 .../systemproperties/properties-loader-util.adoc   |   2 +-
 .../systemproperties/properties-log4j-12-api.adoc  |  55 ++
 .../properties-log4j-core-misc.adoc                |  86 +--
 .../systemproperties/properties-log4j-jul.adoc     |  24 +-
 .../properties-log4j-spring-boot.adoc              |   2 +-
 .../manual/systemproperties/properties-meta.adoc   |   6 +-
 .../systemproperties/properties-provider.adoc      |  16 +-
 .../systemproperties/properties-simple-logger.adoc |  24 +-
 .../systemproperties/properties-status-logger.adoc |  24 +-
 .../properties-thread-context.adoc                 |  18 +-
 .../properties-transport-security.adoc             |  84 +--
 src/site/resources/.htaccess                       |  28 +-
 63 files changed, 1222 insertions(+), 1067 deletions(-)

diff --cc src/site/antora/modules/ROOT/pages/manual/appenders.adoc
index be44a32d4d,5e8300a271..d710b4be8e
--- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
@@@ -1257,7 -1251,8 +1257,8 @@@ table based on a Log4j `MapMessage` ins
  </Configuration>
  ----
  
- === JMS Appender
+ [#jms-appender]
 -== [[JMSAppender]]JMS Appender
++=== [[JMSAppender]]JMS Appender
  
  The JMS Appender sends the formatted log event to a JMS Destination.
  
@@@ -1986,10 -1981,10 +1987,10 @@@ If you are note sure, which implementat
  ====
  
  [#log4j-mongodb]
 -==== NoSQL provider for MongoDB (current)
 +===== NoSQL provider for MongoDB (current)
  
  This section details specializations of the
- link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the current 
MongoDB driver (version 5).
+ <<NoSQLAppender>> provider for MongoDB using the current MongoDB driver 
(version 5).
  The NoSQLAppender Appender writes log events to a NoSQL database using an 
internal lightweight provider interface.
  
  .MongoDB Provider Parameters
@@@ -2075,12 -2070,12 +2076,12 @@@ You can define additional fields to lo
  ----
  
  [#log4j-mongodb4]
 -==== [[NoSQLAppenderMongoDB4]] NoSQL provider  for MongoDB 4 (deprecated)
 +===== [[NoSQLAppenderMongoDB4]] NoSQL provider  for MongoDB 4 (deprecated)
  
- The `log4j-mongodb4` module is deprecated in favor of 
link:#log4j-mongodb[NoSQL provider for MongoDB].
+ The `log4j-mongodb4` module is deprecated in favor of <<log4j-mongodb,NoSQL 
provider for MongoDB>>.
  
  This section details specializations of the
- link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the MongoDB 
driver version 4. The NoSQLAppender Appender writes log events to a NoSQL 
database using an internal lightweight provider interface.
+ <<NoSQLAppender>> provider for MongoDB using the MongoDB driver version 4. 
The NoSQLAppender Appender writes log events to a NoSQL database using an 
internal lightweight provider interface.
  
  .MongoDB Provider Parameters
  [cols="20%,20%,60%",options="header",]
@@@ -2165,9 -2160,9 +2166,9 @@@ You can define additional fields to lo
  ----
  
  [[NoSQLAppenderApacheCouchDB]]
 -== NoSQLAppender for Apache CouchDB
 +=== NoSQLAppender for Apache CouchDB
  
- This section details specializations of the 
link:#NoSQLAppender[NoSQLAppender] provider for CouchDB.
+ This section details specializations of the <<NoSQLAppender>> provider for 
CouchDB.
  The NoSQLAppender writes log events to a NoSQL database using an internal 
lightweight provider interface.
  
  [width="100%",options="header"]
@@@ -2236,10 -2231,10 +2237,10 @@@ Support for immediateFlush and bufferin
  The OutputStreamAppender uses an OutputStreamManager to handle the actual 
I/O, allowing the stream to be shared by Appenders in multiple configurations.
  
  [#RandomAccessFileAppender]
 -== RandomAccessFileAppender
 +=== RandomAccessFileAppender
  
  The RandomAccessFileAppender is similar to the standard
- link:#FileAppender[FileAppender] except it is always buffered (this cannot be 
switched off) and internally it uses a
+ <<FileAppender>> except it is always buffered (this cannot be switched off) 
and internally it uses a
  `ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`.
  We saw a 20-200% performance improvement compared to FileAppender with 
"bufferedIO=true" in our
  measurements.
@@@ -2667,7 -2659,8 +2665,8 @@@ When running in Google App Engine, the 
  `java.lang.management.ManagementFactory.getRuntimeMXBean().getStartTime()`
  and falls back to Log4J initialization time instead.)
  
+ [#sizebased-triggering-policy]
 -=== SizeBased Triggering Policy
 +==== SizeBased Triggering Policy
  
  The `SizeBasedTriggeringPolicy` causes a rollover once the file has reached 
the specified size.
  The size can be specified in bytes, with the suffix KB, MB, GB, or TB for 
example `20MB`.
@@@ -2678,7 -2671,8 +2677,8 @@@ When combined with a time-based trigger
  Otherwise, the target file will be overwritten on every rollover as the 
SizeBased Triggering Policy will not cause the timestamp value in the file name 
to change.
  When used without a time-based triggering policy the SizeBased Triggering 
Policy will cause the timestamp value to change.
  
+ [#timebased-triggering-policy]
 -=== TimeBased Triggering Policy
 +==== TimeBased Triggering Policy
  
  The `TimeBasedTriggeringPolicy` causes a rollover once the date/time pattern 
no longer applies to the active file.
  This policy accepts an
@@@ -3405,10 -3397,10 +3403,10 @@@ Below is a sample configuration that us
  ----
  
  [#RollingRandomAccessFileAppender]
 -== RollingRandomAccessFileAppender
 +=== RollingRandomAccessFileAppender
  
  The RollingRandomAccessFileAppender is similar to the standard
- link:#RollingFileAppender[RollingFileAppender] except it is always buffered 
(this cannot be switched off) and internally it uses a
+ <<RollingFileAppender>> except it is always buffered (this cannot be switched 
off) and internally it uses a
  `ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`.
  We saw a 20-200% performance improvement compared to RollingFileAppender with 
"bufferedIO=true" in our measurements.
  The
@@@ -3517,13 -3509,13 +3515,13 @@@ file attribute view
  
  |=======================================================================
  
 -=== Triggering Policies
 +==== Triggering Policies
  
- See xref:#TriggeringPolicies[RollingFileAppender Triggering Policies].
+ See <<TriggeringPolicies,RollingFileAppender Triggering Policies>>.
  
 -=== Rollover Strategies
 +==== Rollover Strategies
  
- See link:#RolloverStrategies[RollingFileAppender Rollover Strategies].
+ See <<RolloverStrategies,`RollingFileAppender` rollover strategies>>.
  
  Below is a sample configuration that uses a RollingRandomAccessFileAppender 
with both the time and size-based triggering policies will create up to 7 
archives on the same day (1-7) that are stored in a directory based on the 
current year and month, and will compress each archive using gzip:
  
@@@ -4468,45 -4460,3 +4466,45 @@@ Please consult the JeroMQ and ZeroMQ do
  |boolean
  |The ZMQ_XPUB_VERBOSE option. Defaults to false.
  |===
 +
 +[#extending]
 +== Extending
 +
 +Appenders are xref:manual/plugins.adoc[plugins] implementing 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[the 
`Appender` interface].
 +This section will guide you on how to create custom ones.
 +
 +[WARNING]
 +====
 +*Implementing a reliable and efficient appender is a difficult task!*
 +We strongly advise you to
 +
 +. Use existing appenders and/or managers whenever appropriate
 +. Share your use case and ask for feedback in a 
{logging-services-url}/support.html[user support channel]
 +====
 +
 +[#extending-plugins]
 +=== Plugin preliminaries
 +
 +include::partial$manual/plugin-preliminaries.adoc[]
 +
 +[#extending-appenders]
 +=== Extending appenders
 +
 +Appenders are xref:manual/plugins.adoc[plugins] implementing 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[the 
`Appender` interface].
 +We recommend users to extend from 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/AbstractAppender.html[`AbstractAppender`],
 which provides implementation convenience.
 +While annotating your appender with `@Plugin`, you need to make sure that
 +
 +* It has a unique `name` attribute across all available `Appender` plugins
 +* The `category` attribute is set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
 +* The `elementType` attribute is set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html#ELEMENT_TYPE[`Appender.ELEMENT_TYPE`]
 +
 +Most appender implementation use *managers*, which model an abstraction 
owning the resources, such as an `OutputStream` or a socket.
 +When a reconfiguration occurs a new appender will be created.
 +However, if nothing significant in the previous manager has changed, the new 
appender will simply reference it instead of creating a new one.
 +This ensures that events are not lost while a reconfiguration is taking place 
without requiring that logging pause while the reconfiguration takes place.
- You are strongly advised to study the manager concept in xref:#collection[the 
predefined appenders], and either use an existing manager, or create your own.
++You are strongly advised to study the manager concept in <<collection,the 
predefined appenders>>, and either use an existing manager, or create your own.
 +
 +You can check out following files for examples:
 +
- * 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java[`HttpAppender.java`]
 – xref:#HttpAppender[] sends log events over HTTP using 
`HttpURLConnectionManager`
- * 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java[`ConsoleAppender.java`]
 – xref:#ConsoleAppender[Console Appender] writes log events to either 
`System.out` or `System.err` using `OutputStreamManager`
++* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java[`HttpAppender.java`]
 – <<HttpAppender>> sends log events over HTTP using `HttpURLConnectionManager`
++* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java[`ConsoleAppender.java`]
 – <<ConsoleAppender>> writes log events to either `System.out` or `System.err` 
using `OutputStreamManager`
diff --cc src/site/antora/modules/ROOT/pages/manual/filters.adoc
index 88e10b79ac,baea1d507b..0d13dc97e3
--- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc
@@@ -1044,36 -1037,3 +1044,36 @@@ A sample configuration that only allow
    </Loggers>
  </Configuration>
  ----
 +
 +[#extending]
 +== Extending
 +
 +Filters are xref:manual/plugins.adoc[plugins] implementing 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.html[the 
`Filter` interface].
 +This section will guide you on how to create custom ones.
 +
 +[NOTE]
 +====
- While xref:#collection[the predefined filter collection] should address most 
common use cases, you might find yourself needing to implement a custom one.
++While <<collection,the predefined filter collection>> should address most 
common use cases, you might find yourself needing to implement a custom one.
 +If this is the case, we really appreciate it if you can *share your use case 
in a {logging-services-url}/support.html[user support channel]*.
 +====
 +
 +[#extending-plugins]
 +=== Plugin preliminaries
 +
 +include::partial$manual/plugin-preliminaries.adoc[]
 +
 +[#extending-filters]
 +=== Extending filters
 +
 +Filter are xref:manual/plugins.adoc[plugins] implementing 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.html[the 
`Filter` interface].
 +We recommend users to extend from 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/filter/AbstractFilter.html[`AbstractFilter`],
 which provides implementation convenience.
 +While annotating your filter with `@Plugin`, you need to make sure that
 +
 +* It has a unique `name` attribute across all available `Filter` plugins
 +* The `category` attribute is set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
 +* The `elementType` attribute is set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.html#ELEMENT_TYPE[`Filter.ELEMENT_TYPE`]
 +
 +You can check out following files for examples:
 +
- * 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MarkerFilter.java[`MarkerFilter.java`]
 – xref:#MarkerFilter[] matching on markers associated with the effective 
`LogEvent` in the context
- * 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java[`RegexFilter.java`]
 – xref:#RegexFilter[] matching on the message associated with the effective 
`LogEvent` in the context
++* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MarkerFilter.java[`MarkerFilter.java`]
 – <<MarkerFilter>> matching on markers associated with the effective 
`LogEvent` in the context
++* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java[`RegexFilter.java`]
 – <<RegexFilter>> matching on the message associated with the effective 
`LogEvent` in the context
diff --cc src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
index e776c37267,c8736c8ef1..03c12c8fb1
--- a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
@@@ -56,8 -56,8 +56,8 @@@ If not for yours, keep on reading
  
  In order to have a garbage-free Log4j Core, you need to
  
- * xref:#core-properties[configure it using properties],
- * and employ garbage-free xref:#Layouts[layouts], xref:Appenders[appenders], 
and xref:#Filters[filters].
+ * <<core-properties,configure it using properties>>,
 -* and employ garbage-free <<Layouts[layouts], xref:Appenders[appenders], and 
xref:#Filters,filters>>.
++* and employ garbage-free <<Layouts>>, <<Appenders>>, and <<Filters>>.
  
  [#core-properties]
  === Properties
diff --cc src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
index 8408762e53,016450092c..bd877a3aa1
--- a/src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
@@@ -16,7 -16,7 +16,7 @@@
  ////
  = JSON Template Layout
  
- `JsonTemplateLayout` is a customizable, xref:#performance[efficient], and 
xref:#faq-garbage-free[garbage-free] JSON generating layout.
 -`JsonTemplateLayout` is a customizable, <<performance,efficient>>, and 
xref:#faq-garbage-free,garbage-free>> JSON generating layout.
++`JsonTemplateLayout` is a customizable, <<performance,efficient>>, and 
<<faq-garbage-free,garbage-free>> JSON generating layout.
  It encodes ``LogEvent``s according to the structure described by the JSON 
template provided.
  In a nutshell, it shines with its
  
diff --cc src/site/antora/modules/ROOT/pages/manual/lookups.adoc
index 33e9749801,3b24c6ee4d..41c17fd577
--- a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc
@@@ -708,34 -698,3 +708,34 @@@ located then the corresponding value wi
    <File name="ApplicationLog" fileName="${web:rootDir}/app.log"/>
  </Appenders>
  ----
 +
 +[#extending]
 +== Extending
 +
 +Lookups are xref:manual/plugins.adoc[plugins] implementing 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[the
 `StrLookup` interface].
 +This section will guide you on how to create custom ones.
 +
 +[NOTE]
 +====
- While xref:#collection[the predefined lookup collection] should address most 
common use cases, you might find yourself needing to implement a custom one.
++While <<collection,the predefined lookup collection>> should address most 
common use cases, you might find yourself needing to implement a custom one.
 +If this is the case, we really appreciate it if you can *share your use case 
in a {logging-services-url}/support.html[user support channel]*.
 +====
 +
 +[#extending-plugins]
 +=== Plugin preliminaries
 +
 +include::partial$manual/plugin-preliminaries.adoc[]
 +
 +[#extending-lookups]
 +=== Extending lookups
 +
 +Lookups are xref:manual/plugins.adoc[plugins] implementing 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[the
 `StrLookup` interface].
 +While annotating your lookup with `@Plugin`, you need to make sure that
 +
 +* It has a unique `name` attribute across all available `StrLookup` plugins
 +* The `category` attribute is set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#CATEGORY[`StrLookup.CATEGORY`]
 +
 +You can check out following files for examples:
 +
- * 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DateLookup.java[`LowerLookup.java`]
 – xref:#LowerLookup[] lower-cases its input
- * 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EventLookup.java[`EventLookup.java`]
 – xref:#EventLookup[] extracts specified fields from the effective `LogEvent` 
in the context
++* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DateLookup.java[`LowerLookup.java`]
 – <<LowerLookup>> lower-cases its input
++* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EventLookup.java[`EventLookup.java`]
 – <<EventLookup>> extracts specified fields from the effective `LogEvent` in 
the context
diff --cc src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
index 97c7433800,fac5648b2a..3c8d838053
--- a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
@@@ -17,7 -17,7 +17,7 @@@
  
  = Pattern Layout
  
- `PatternLayout` is a customizable, xref:#performance[efficient], 
xref:#garbage-free[garbage-free], and human-readable string generating layout 
using a user-provided pattern.
 -`PatternLayout` is a customizable, <<performance[efficient], 
xref:#garbage-free,garbage-free>>, and human-readable string generating layout 
using a user-provided pattern.
++`PatternLayout` is a customizable, <<performance,efficient>>, 
<<garbage-free,garbage-free>>, and human-readable string generating layout 
using a user-provided pattern.
  It is analogous to `String#format()` with specialized directives on injecting 
certain properties of a `LogEvent`.
  
  [IMPORTANT]
@@@ -1596,89 -1596,89 +1596,89 @@@ Format modifiers to control such thing
  |Pattern
  |Comment
  
--|xref:#converter-logger[%c\{precision} +
--%logger\{precision}]
++|<<converter-logger,%c\{precision} +
++%logger\{precision}>>
  |
  
--|xref:#converter-date[%d +
--%date]
++|<<converter-date,%d +
++%date>>
  |Only the predefined date formats (`DEFAULT`, `ISO8601`, `UNIX`, 
`UNIX_MILLIS`, etc.) are garbage-free
  
--|xref:#converter-encode[%enc\{pattern} +
--%encode\{pattern}]
++|<<converter-encode,%enc\{pattern} +
++%encode\{pattern}>>
  |
  
--|xref:#converter-equals[%equals\{pattern}\{test}\{substitution} +
--%equalsIgnoreCase\{pattern}\{test}\{substitution}]
++|<<converter-equals,%equals\{pattern}\{test}\{substitution} +
++%equalsIgnoreCase\{pattern}\{test}\{substitution}>>
  |
  
- |xref:#converter-highlight[%highlight\{pattern}\{style}]
+ |<<converter-highlight,%highlight\{pattern}\{style}>>
  |Granted nested pattern is garbage-free
  
--|xref:#converter-map[%K\{key} +
++|<<converter-map,%K\{key} +
  %map\{key} +
--%MAP\{key}]
++%MAP\{key}>>
  |
  
--|xref:#converter-message[%m +
++|<<converter-message,%m +
  %msg +
--%message]
++%message>>
  |
  
- |xref:#converter-marker[%marker]
+ |<<converter-marker,%marker>>
  |
  
- |xref:#converter-marker[%markerSimpleName]
+ |<<converter-marker,%markerSimpleName>>
  |
  
--|xref:#converter-max-len[%maxLen +
--%maxLength]
++|<<converter-max-len,%maxLen +
++%maxLength>>
  |
  
  |%n
  |
  
--|xref:#converter-nano[%N +
--%nano]
++|<<converter-nano,%N +
++%nano>>
  |
  
--|xref:#converter-not-empty[%notEmpty\{pattern} +
++|<<converter-not-empty,%notEmpty\{pattern} +
  %varsNotEmpty\{pattern} +
--%variablesNotEmpty\{pattern}]
++%variablesNotEmpty\{pattern}>>
  |
  
--|xref:#converter-level[%p +
--%level]
++|<<converter-level,%p +
++%level>>
  |
  
--|xref:#converter-relative[%r +
--%relative]
++|<<converter-relative,%r +
++%relative>>
  |
  
--|xref:#converter-seq[%sn +
--%sequenceNumber]
++|<<converter-seq,%sn +
++%sequenceNumber>>
  |
  
- |xref:#converter-style[%style\{pattern}{ANSI style}]
+ |<<converter-style,%style\{pattern}{ANSI style}>>
  |
  
--|xref:#converter-thread-id[%T +
++|<<converter-thread-id,%T +
  %tid +
--%threadId]
++%threadId>>
  |
  
--|xref:#converter-thread-name[%t +
++|<<converter-thread-name,%t +
  %tn +
  %thread +
--%threadName]
++%threadName>>
  |
  
- |xref:#converter-thread-priority[%tp]
+ |<<converter-thread-priority,%tp>>
  |
  
- |xref:#converter-thread-context-map[%X{key[,key2...\]} +
 -|<<converter-thread-context-map[%X{key,,key2...\>>} +
++|<<converter-thread-context-map[%X{key,,key2...\} +
  %mdc{key[,key2...\]} +
--%MDC{key[,key2...\]}]
++%MDC{key[,key2...\]}>>
  |
  
  |literal text
diff --cc src/site/antora/modules/ROOT/pages/manual/plugins.adoc
index cbca9ff4ec,c793d404c4..f8beb69933
--- a/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/plugins.adoc
@@@ -14,202 -14,23 +14,202 @@@
      See the License for the specific language governing permissions and
      limitations under the License.
  ////
 +
  = Plugins
  
 -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 goal of Log4j 2 is to make 
extending it extremely easy through the use of plugins.
 +Log4j plugin system is the de facto extension mechanism embraced by various 
Log4j Core components.
 +Plugins make it possible for extensible components to _receive_ feature 
implementations without any explicit links in between.
 +It is analogous to a 
https://en.wikipedia.org/wiki/Dependency_injection[dependency injection] 
framework, but curated for Log4j-specific needs.
 +
 +[NOTE]
 +====
 +Log4j plugin system is implemented by Log4j Core, the logging implementation.
 +It is deliberately not a part of the Log4j API to keep the logging API 
footprint small.
 +====
 +
 +[TIP]
 +====
 +Did you know about *xref:plugin-reference.adoc[], the documentation extracted 
from the source code* of all predefined Log4j plugins?
 +Like Javadoc, but specialized for plugins!
 +====
 +
 +In this section we will give an overview of the Log4j plugin system by 
answering certain questions:
 +
 +. <<#declare-plugin,How can you declare a plugin?>>
 +. <<#core,How can you declare a plugin that needs to be represented in a 
Log4j configuration file?>>
 +. <<#plugin-registry,How can you register your plugin to Log4j?>>
 +. <<#plugin-discovery,How does Log4j discover plugins?>>
 +. <<#plugin-load,How can you load other plugins in a plugin?>>
 +
 +[#declare-plugin]
 +== Declaring plugins
 +
 +A class can be declared as a plugin by adding a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/Plugin.html[`@Plugin`]
 annotation, which is essentially composed of following attributes:
 +
 +`name`::
 +Denotes the name of the plugin and is recommended to be distinct among 
plugins sharing the same `category`.
 +`name` matching is case-insensitive.
 +
 +`category`::
 +A name used for grouping a set of plugins.
 +`name` matching is case-sensitive.
 +
 +`elementType`::
 +Name of the corresponding category of the 
xref:manual/configuration.adoc[Log4j configuration] file element this plugin 
belongs under.
 +You can omit this attribute if your plugin is not meant to be represented in 
a configuration file.
 +
 +For example, xref:manual/lookups.adoc#extending[lookups] only use the 
`category` attribute and set it to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#CATEGORY[`StrLookup.CATEGORY`]
 (`Lookup`).
 +On the other hand, xref:manual/appenders.adoc#extending[appenders] use both 
the `category` and `elementType` attributes and set them to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
 (`Core`) and 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html#ELEMENT_TYPE[`Appender.ELEMENT_TYPE`]
 (`appender`), respectively.
 +The reason appenders use an `elementType` and lookups don't is that appenders 
need to be referred to in an element in a Log4j configuration file (e.g., 
`log4j2.xml`) whereas lookups don't.
 +See <<core>> for details.
 +
 +For clarity's sake, see following examples:
 +
 +* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DateLookup.java[`LowerLookup.java`]
 (uses only `category`)
 +* 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/CsvParameterLayout.java[`CsvParameterLayout.java`]
 (uses both `category` and `elementType`)
 +
 +.Click to read more on *name collision* and *overriding an existing plugin*
 +[%collapsible]
 +====
 +The `name` attribute of plugins of a certain `category` is recommended to be 
distinct and this matching is case-insensitive.
 +In case of a name collision, a warning will be emitted, and the plugin 
<<plugin-discovery,discovery order>> will determine the effective plugin.
 +For example, to override the `File` plugin which is provided by the built-in 
xref:manual/appenders.adoc#FileAppender[File Appender], you would need to place 
your plugin in a JAR file in the classpath ahead of Log4j Core JAR.
 +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 
https://www.osgi.org/javadoc/r5/core/org/osgi/framework/BundleContext.html#getBundles()[`getBundles()`]
 and 
https://www.osgi.org/javadoc/r5/core/org/osgi/framework/SynchronousBundleListener.html[`SynchronousBundleListener`].
 +In short, name collisions are even more unpredictable in an OSGi environment.
 +====
 +
 +[#core]
 +== Declaring plugins represented in a configuration file
 +
 +If your plugin needs to be represented by an element in a configuration file 
(such as an xref:manual/appenders.adoc[appender], 
xref:manual/layouts.adoc[layout], xref:manual/api.adoc#loggers[logger], or 
xref:manual/filters.adoc[filter]), following requirements must be met:
 +
 +* The `category` attribute of the `@Plugin` annotation must be set to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
 (`Core`)
 +* The `elementType` attribute of the `@Plugin` annotation must be configured, 
if it belongs under a certain category of elements (appenders, layouts, etc.)
 +* It must have a xref:declare-plugin-factory[plugin factory]
 +
 +See 
{project-github-url}/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayout.java[`JsonTemplateLayout.java`]
 for following details:
 +
 +* Layout's `@Plugin` annotation sets `category` and `elementType` to 
`Node.CATEGORY` and 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html#ELEMENT_TYPE[`Layout.ELEMENT_TYPE`],
 respectively
 +* All plugin declarations are provided with a 
`@PluginBuilderFactory`-annotated static method
 +* ``EventTemplateAdditionalField`` class' `@Plugin` annotation doesn't have 
an `elementType` attribute, even though it maps to a configuration file element
 +
 +[#declare-plugin-factory]
 +=== Declaring plugin factories
 +
 +A *plugin factory* is responsible for
 +
 +* Creating an instance of the plugin
 +* Receiving values (`Configuration` instance, configuration attributes, etc.) 
available in the context
 +
 +Every plugin that needs to be represented by an element in a configuration 
file must declare a plugin factory using one of the following:
 +
 +a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginFactory.html[`@PluginFactory`]-annotated
 static method::
 +What is expected to be received is modelled as method arguments.
 +Intended for simple plugins that receive less than a handful of values.
 ++
 +See 
{project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/CsvParameterLayout.java[`CsvParameterLayout.java`]
 for an example on `@PluginFactory` usage.
 +
 +a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginBuilderFactory.html[`@PluginBuilderFactory`]-annotated
 static method of return type 
link:../javadoc/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Builder.java[`Builder<T>`]::
 +What is expected to be received is modelled as fields of a builder class.
 +Intended for more sophisticated wiring needs.
 ++
 +.Click for advantages of builder class over factory method
 +[%collapsible]
 +====
 +* Attribute names don't need to be specified, if they match the field name
 +* Default values can be specified in code rather than through an annotation.
 +This also allows a runtime-calculated default value, which isn't allowed in 
annotations.
 +* Default values are specified via code rather than relying on reflection and 
injection, so they work programmatically as well as in a configuration file.
 +* Adding new optional parameters doesn't require existing programmatic 
configuration to be refactored.
 +* Easier to write unit tests using builders rather than factory methods with 
optional parameters.
 +====
 ++
 +See 
{project-github-url}/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayout.java[`JsonTemplateLayout.java`]
 for an example on `@PluginBuilderFactory` usage.
 +
 +If a plugin class implements `Collection` or `Map`, then no factory method is 
used.
 +Instead, the class is instantiated using the default constructor, and all 
child configuration nodes are added to the `Collection` or `Map`.
 +
 +[#attribute-types]
 +==== Plugin factory attribute types
 +
 +To allow the current `Configuration` to populate the correct arguments for 
the `@PluginFactory`-annotated method (or fields for the builder class), every 
argument to the method must be annotated using one of the following attribute 
types.
 +
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginAliases.html[`@PluginAliases`]::
 +Identifies a list of aliases for a `@Plugin`, `@PluginAttribute`, or 
`@PluginBuilderAttribute`
  
 -In Log4j 2 a plugin is declared by adding a 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/Plugin.html[`@Plugin`]
 annotation to the class declaration. During initialization the 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html[`Configuration`]
 will invoke the 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/util/PluginManager.html[`PluginManager`]
 to load the built-in Log4j plugins as well as any custom plu [...]
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginAttribute.html[`@PluginAttribute`]::
 +Denotes a configuration element attribute.
 +The parameter must be convertible from a `String` using a `TypeConverter`.
 +Most built-in types are already supported, but custom `TypeConverter` plugins 
may also be provided for more type support.
 +Note that `PluginBuilderAttribute` can be used in builder class fields as an 
easier way to provide default values.
  
 -1. Serialized plugin listing files on the classpath. These files are 
generated automatically during the build (more details below).
 -2. (OSGi only) Serialized plugin listing files in each active OSGi bundle. A 
`BundleListener` is added on activation to continue checking new bundles after 
`log4j-core` has started.
 -3. **(Deprecated)** A comma-separated list of packages specified by the 
`log4j.plugin.packages` system property.
 -4. **(Deprecated)** Packages passed to the static `PluginManager.addPackages` 
method (before Log4j configuration occurs).
 -5. **(Deprecated)** The [packages](./configuration.html#ConfigurationSyntax) 
declared in your log4j2 configuration file.
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.html[`@PluginConfiguration`]::
 +The current `Configuration` object will be passed to the plugin as a 
parameter.
  
 -If multiple Plugins specify the same (case-insensitive) `name`, then the load 
order above determines which one will be used. For example, to override the 
`File` plugin which is provided by the built-in `FileAppender` class, you would 
need to place your plugin in a JAR file in the CLASSPATH ahead 
of`log4j-core.jar`. 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 [...]
 +[[PluginElement]] 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginElement.html[`@PluginElement`]::
 +The parameter may represent a complex object that itself has parameters that 
can be configured.
 +This also supports injecting an array of elements.
  
 -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 proce [...]
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginNode.html[`@PluginNode`]::
 +The current `Node` being parsed will be passed to the plugin as a parameter.
  
 -[source,xml]
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginValue.html[`@PluginValue`]::
 +The value of the current `Node` or its attribute named `value`.
 +
 +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.
 +For plugin builders, the names of the fields will be used by default if no 
name is specified in the annotation.
 +
 +[#type-converters]
 +=== Plugin factory attribute type converters
 +
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html[`TypeConverter`]s
 are a certain group of plugins for converting ``String``s read from 
configuration file elements into the types used in plugin factory attributes.
- Other plugins can already be injected via xref:#PluginElement[the 
`@PluginElement` annotation]; now, any type supported by ``TypeConverter``s can 
be used in a `@PluginAttribute`-annotated factory attribute.
++Other plugins can already be injected via <<PluginElement,the 
`@PluginElement` annotation>>; now, any type supported by ``TypeConverter``s 
can be used in a `@PluginAttribute`-annotated factory attribute.
 +
 +Conversion of enum types are supported on demand and do not require custom 
``TypeConverter``s.
 +A large number of built-in Java classes (`int`, `long`, `BigDecimal`, etc.) 
are already supported; see 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.html[`TypeConverters`]
 for a more exhaustive listing.
 +
 +You can create custom ``TypeConverter``s as follows:
 +
 +* Extend from 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html[the
 `TypeConverter` interface]
 +
 +* Set the `category` attribute of the `@Plugin` annotation to 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.html#CATEGORY[`TypeConverters.CATEGORY`]
 (`TypeConverter`).
 +Unlike other plugins, the plugin name of a `TypeConverter` is purely cosmetic.
 +
 +* Have a default constructor
 +
 +* Optionally, extend from `Comparable<TypeConverter<?>>`, which will be used 
for determining the order in case of multiple `TypeConverter` candidates for a 
certain type
 +
 +See 
{project-github-url}/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java[`TypeConverters.java`]
 for example implementations.
 +
 +[#constraint-validators]
 +==== Plugin factory attribute validators
 +
 +Plugin factory fields and parameters can be automatically validated at 
runtime using constraint validators inspired by https://beanvalidation.org[Bean 
Validation].
 +The following annotations are bundled in Log4j, but custom 
``ConstraintValidator`` can be created as well.
 +
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/validation/constraints/Required.html[`@Required`]::
 +This annotation validates that a value is non-empty.
 +This covers a check for null as well as several other scenarios: empty 
`CharSequence` objects, empty arrays, empty `Collection` instances, and empty 
`Map` instances.
 +
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/validation/constraints/ValidHost.html[`@ValidHost`]::
 +This annotation validates that a value corresponds to a valid host name.
 +This uses the same validation as 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/net/InetAddress.html#getByName-java.lang.String-[`InetAddress.getByName(String)`].
 +
 
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/validation/constraints/ValidPort.html[`@ValidPort`]::
 +This annotation validates that a value corresponds to a valid port number 
between 0 and 65535.
 +
 +[#plugin-registry]
 +== Registering plugins
 +
 +Registering plugins are done by placing a *Log4j plugin descriptor* (i.e., 
`Log4j2Plugins.dat`) into the classpath.
 +This file is generated using the 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.html[`PluginProcessor`]
 annotation processor at compile-time.
 +You need to configure your build tool as follows to employ `PluginProcessor` 
by the Java compiler:
 +
 +[tabs]
 +====
 +Maven::
 ++
 +[source,xml,subs="+attributes"]
  ----
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
diff --cc src/site/resources/.htaccess
index a96bb00fa1,ce7adc4556..bacc9bc0fc
--- a/src/site/resources/.htaccess
+++ b/src/site/resources/.htaccess
@@@ -33,33 -33,20 +33,24 @@@ RewriteRule "^(.+)$" "$1.html
  
  # The content moved between pages
  RewriteRule "^articles\.html$" "manual/index.html" [R=permanent]
+ RewriteRule "^log4j-1\.2-api(/index)?\.html$" "manual/migration.html" 
[R=permanent]
  RewriteRule "^log4j-api/apidocs(.*)$" "javadoc/log4j-api$1" [R=permanent]
- RewriteRule "^log4j-api/index\.html$" "manual/api.html" [R=permanent]
- RewriteRule "^log4j-api\.html$" "manual/api.html" [R=permanent]
+ RewriteRule "^log4j-api(/index)?\.html$" "manual/api.html" [R=permanent]
  RewriteRule "^log4j-core/apidocs(.*)$" "javadoc/log4j-core$1" [R=permanent]
- RewriteRule "^log4j-jcl/index\.html$" 
"manual/installation.html#impl-core-bridge-jcl" [R=permanent,NE]
- RewriteRule "^log4j-jcl\.html$" 
"manual/installation.html#impl-core-bridge-jcl" [R=permanent,NE]
- RewriteRule "^log4j-jmx-gui/index\.html$" "/log4j/jmx-gui/latest/index.html" 
[R=permanent]
- RewriteRule "^log4j-jmx-gui\.html$" "/log4j/jmx-gui/latest/index.html" 
[R=permanent]
- RewriteRule "^log4j-jpl/index\.html$" 
"manual/installation.html#impl-core-bridge-jpl" [R=permanent,NE]
- RewriteRule "^log4j-jpl\.html$" 
"manual/installation.html#impl-core-bridge-jpl" [R=permanent,NE]
- RewriteRule "^log4j-jul/index\.html$" 
"manual/installation.html#impl-core-bridge-jul" [R=permanent,NE]
- RewriteRule "^log4j-jul\.html$" 
"manual/installation.html#impl-core-bridge-jul" [R=permanent,NE]
- RewriteRule "^log4j-mongodb3\.html$" 
"manual/appenders.html#NoSQLAppenderMongoDB" [R=permanent,NE]
- RewriteRule "^log4j-mongodb3/index\.html$" 
"manual/appenders.html#NoSQLAppenderMongoDB" [R=permanent,NE]
- RewriteRule "^log4j-mongodb4\.html$" "manual/appenders.html#log4j-mongodb4" 
[R=permanent,NE]
- RewriteRule "^log4j-mongodb4/index\.html$" 
"manual/appenders.html#log4j-mongodb4" [R=permanent,NE]
- RewriteRule "^log4j-slf4j-impl/index\.html$" 
"manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE]
- RewriteRule "^log4j-slf4j-impl\.html$" 
"manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE]
- RewriteRule "^log4j-slf4j2-impl/index\.html$" 
"manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE]
- RewriteRule "^log4j-slf4j2-impl\.html$" 
"manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE]
+ RewriteRule "^log4j-jcl(/index)?\.html$" 
"manual/installation.html#impl-core-bridge-jcl" [R=permanent,NE]
+ RewriteRule "^log4j-jmx-gui(/index)?\.html$" 
"/log4j/jmx-gui/latest/index.html" [R=permanent]
+ RewriteRule "^log4j-jpl(/index)?\.html$" 
"manual/installation.html#impl-core-bridge-jpl" [R=permanent,NE]
+ RewriteRule "^log4j-jul(/index)?\.html$" 
"manual/installation.html#impl-core-bridge-jul" [R=permanent,NE]
+ RewriteRule "^log4j-mongodb3(/index)?\.html$" 
"manual/appenders.html#NoSQLAppenderMongoDB" [R=permanent,NE]
+ RewriteRule "^log4j-mongodb4(/index)?\.html$" 
"manual/appenders.html#log4j-mongodb4" [R=permanent,NE]
+ RewriteRule "^log4j-slf4j2?-impl(/index)?\.html$" 
"manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE]
  RewriteRule "^manual/api-separation\.html$" "manual/api.html" [R=permanent]
 +RewriteRule "^manual/extending\.html#Appenders$" 
"manual/appenders.html#extending" [R=permanent]
 +RewriteRule "^manual/extending\.html#Filters$" 
"manual/filters.html#extending" [R=permanent]
  RewriteRule "^manual/extending\.html#Layouts$" 
"manual/layouts.html#extending" [R=permanent]
 +RewriteRule "^manual/extending\.html#Lookups$" 
"manual/lookups.html#extending" [R=permanent]
  RewriteRule "^manual/extending\.html#PatternConverters$" 
"manual/pattern-layout.html#extending-converters" [R=permanent]
 +RewriteRule "^manual/extending\.html#Plugin_Builders$" 
"manual/plugins.html#declare-plugin-factory" [R=permanent]
  RewriteRule "^manual/layouts\.html#enable-jansi$" 
"manual/pattern-layout.html#jansi" [R=permanent]
  RewriteRule "^manual/layouts\.html#EndOfBatch$" 
"manual/pattern-layout.html#converter-end-of-batch" [R=permanent]
  RewriteRule "^manual/layouts\.html#LevelPatternSelector$" 
"manual/pattern-layout.html#plugin-element-LevelPatternSelector" [R=permanent]


Reply via email to