You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2024/08/06 10:28:26 UTC
(logging-log4j2) 01/01: Revamp message-queue appender documentation
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch doc/2.x/appenders-mq
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 7502316cb11914de7c6d8ad14803ab0a4f0d9fda
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Tue Aug 6 12:28:13 2024 +0200
Revamp message-queue appender documentation
This PR revamps the documentation of the remaining appenders, i.e. those logging to message-queue servers and the `Console` appender.
Closes #2528.
---
.github/dependabot.yaml | 8 +
log4j-flume-ng/pom.xml | 1 +
pom.xml | 21 +
src/site/antora/antora.tmpl.yml | 3 +
src/site/antora/antora.yml | 3 +
.../nosql-mongo.json => console-dev.json} | 10 +-
.../manual/appenders/console-dev.properties | 11 +
.../ROOT/examples/manual/appenders/console-dev.xml | 18 +
.../examples/manual/appenders/console-dev.yaml | 13 +
.../nosql-mongo.json => console-prod.json} | 11 +-
.../manual/appenders/console-prod.properties | 13 +
.../examples/manual/appenders/console-prod.xml | 19 +
.../examples/manual/appenders/console-prod.yaml | 13 +
.../manual/appenders/database/nosql-mongo.json | 27 +-
.../appenders/database/nosql-mongo.properties | 26 +-
.../manual/appenders/database/nosql-mongo.xml | 16 +
.../manual/appenders/database/nosql-mongo.yaml | 17 +
.../manual/appenders/message-queue/flume-avro.json | 34 +
.../appenders/message-queue/flume-avro.properties | 22 +
.../manual/appenders/message-queue/flume-avro.xml | 23 +
.../manual/appenders/message-queue/flume-avro.yaml | 22 +
.../appenders/message-queue/flume-embedded.json | 36 +
.../appenders/message-queue/flume-embedded.xml | 25 +
.../appenders/message-queue/flume-embedded.yaml | 22 +
.../appenders/message-queue/flume-persistent.json | 41 +
.../appenders/message-queue/flume-persistent.xml | 27 +
.../appenders/message-queue/flume-persistent.yaml | 26 +
.../manual/appenders/message-queue/jeromq.json | 30 +
.../appenders/message-queue/jeromq.properties | 18 +
.../manual/appenders/message-queue/jeromq.xml | 21 +
.../manual/appenders/message-queue/jeromq.yaml | 17 +
.../jms-message.json} | 12 +-
.../appenders/message-queue/jms-message.properties | 12 +
.../manual/appenders/message-queue/jms-message.xml | 21 +
.../appenders/message-queue/jms-message.yaml | 14 +
.../jms-simple.json} | 12 +-
.../appenders/message-queue/jms-simple.properties | 12 +
.../manual/appenders/message-queue/jms-simple.xml | 21 +
.../manual/appenders/message-queue/jms-simple.yaml | 14 +
.../manual/appenders/message-queue/kafka.json | 37 +
.../appenders/message-queue/kafka.properties | 25 +
.../manual/appenders/message-queue/kafka.xml | 31 +
.../manual/appenders/message-queue/kafka.yaml | 26 +
src/site/antora/modules/ROOT/pages/javadoc.adoc | 3 +
.../modules/ROOT/pages/manual/appenders.adoc | 975 +++++-----------
.../ROOT/pages/manual/appenders/database.adoc | 67 +-
.../ROOT/pages/manual/appenders/delegating.adoc | 14 +-
.../ROOT/pages/manual/appenders/message-queue.adoc | 1211 ++++++++++++++++++++
.../ROOT/pages/manual/appenders/network.adoc | 2 +-
.../antora/modules/ROOT/pages/manual/layouts.adoc | 2 +-
50 files changed, 2388 insertions(+), 717 deletions(-)
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml
index 225a80cda4..3d76d9a699 100644
--- a/.github/dependabot.yaml
+++ b/.github/dependabot.yaml
@@ -122,6 +122,10 @@ updates:
# H2 version 2.3.x requires Java 11
- dependency-name: "com.h2database:h2"
versions: [ "[2.3,)" ]
+ # The Console Appender only support JANSI 1.x for now
+ # see https://github.com/apache/logging-log4j2/issues/1736
+ - dependency-name: "org.fusesource.jansi:jansi"
+ update-types: [ "version-update:semver-major" ]
- package-ecosystem: github-actions
directory: "/"
@@ -164,6 +168,10 @@ updates:
# Don't upgrade to 3.x
- dependency-name: "org.apache.logging.log4j:log4j-api"
versions: [ "[3,)" ]
+ # The Console Appender only support JANSI 1.x for now
+ # see https://github.com/apache/logging-log4j2/issues/1736
+ - dependency-name: "org.fusesource.jansi:jansi"
+ update-types: [ "version-update:semver-major" ]
- package-ecosystem: github-actions
directory: "/"
diff --git a/log4j-flume-ng/pom.xml b/log4j-flume-ng/pom.xml
index 6af2f7c517..505f5969a6 100644
--- a/log4j-flume-ng/pom.xml
+++ b/log4j-flume-ng/pom.xml
@@ -32,6 +32,7 @@
<description>The Apache Log4j Flume Appender</description>
<properties>
+ <maven.javadoc.skip>false</maven.javadoc.skip>
<!--
~ OSGi and JPMS options
diff --git a/pom.xml b/pom.xml
index c77ea20046..bfad1de52e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -337,8 +337,11 @@
<site-conversant.version>1.2.21</site-conversant.version>
<site-disruptor.version>4.0.0</site-disruptor.version>
<site-jackson.version>2.17.2</site-jackson.version>
+ <site-jansi.version>1.18</site-jansi.version>
<site-javax-mail.version>1.6.2</site-javax-mail.version>
<site-jctools.version>4.0.5</site-jctools.version>
+ <site-jeromq.version>0.6.0</site-jeromq.version>
+ <site-kafka.version>3.8.0</site-kafka.version>
<site-log4j-api.version>2.23.1</site-log4j-api.version>
<site-log4j-core.version>2.23.1</site-log4j-core.version>
<site-log4j-layout-template-json.version>2.23.1</site-log4j-layout-template-json.version>
@@ -769,6 +772,12 @@
<type>pom</type>
</dependency>
+ <dependency>
+ <groupId>org.fusesource.jansi</groupId>
+ <artifactId>jansi</artifactId>
+ <version>${site-jansi.version}</version>
+ </dependency>
+
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
@@ -781,6 +790,18 @@
<version>${site-jctools.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.zeromq</groupId>
+ <artifactId>jeromq</artifactId>
+ <version>${site-jeromq.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.kafka</groupId>
+ <artifactId>kafka-clients</artifactId>
+ <version>${site-kafka.version}</version>
+ </dependency>
+
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
diff --git a/src/site/antora/antora.tmpl.yml b/src/site/antora/antora.tmpl.yml
index c7589bb6ce..2222b5031f 100644
--- a/src/site/antora/antora.tmpl.yml
+++ b/src/site/antora/antora.tmpl.yml
@@ -57,8 +57,11 @@ asciidoc:
conversant-version: "${site-conversant.version}"
disruptor-version: "${site-disruptor.version}"
jackson-version: "${site-jackson.version}"
+ jansi-version: "${site-jansi.version}"
javax-mail-version: "${site-javax-mail.version}"
jctools-version: "${site-jctools.version}"
+ jeromq-version: "${site-jeromq.version}"
+ kafka-version: "${site-kafka.version}"
log4j-api-version: "${log4j-api.version}"
log4j-core-version: "${site-log4j-core.version}"
log4j-layout-template-json-version: "${site-log4j-layout-template-json.version}"
diff --git a/src/site/antora/antora.yml b/src/site/antora/antora.yml
index d23c25ab4f..41c2da3aad 100644
--- a/src/site/antora/antora.yml
+++ b/src/site/antora/antora.yml
@@ -57,8 +57,11 @@ asciidoc:
conversant-version: "1.2.3-conversant"
disruptor-version: "1.2.3-disruptor"
jackson-version: "1.2.3-jackson"
+ jansi-version: "1.2.3-jansi"
javax-mail-version: "1.2.3-javax-mail"
jctools-version: "1.2.3-jctools"
+ jeromq-version: "1.2.3-jeromq"
+ kafka-version: "1.2.3-kafka"
log4j-api-version: "1.2.3-api"
log4j-core-version: "1.2.3-core"
log4j-layout-template-json-version: "1.2.3-layout-template-json"
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.json
similarity index 55%
copy from src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
copy to src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.json
index 4e42604efd..212f9eca04 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.json
@@ -2,10 +2,10 @@
"Configuration": {
"Appenders": {
// tag::appender[]
- "NoSql": {
- "name": "MONGO",
- "MongoDb": {
- "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs"
+ "Console": {
+ "name": "CONSOLE",
+ "PatternLayout": {
+ "pattern": "%d [%t] %p %c - %m%n"
}
}
// end::appender[]
@@ -14,7 +14,7 @@
"Root": {
"level": "INFO",
"AppenderRef": {
- "ref": "MONGO"
+ "ref": "CONSOLE"
}
}
}
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.properties
new file mode 100644
index 0000000000..747138b398
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.properties
@@ -0,0 +1,11 @@
+##
+# tag::appender[]
+appender.0.type = Console
+appender.0.name = CONSOLE
+
+appender.0.layout.type = PatternLayout
+appender.0.layout.pattern = %d [%t] %p %c - %m%n
+# end::appender[]
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = CONSOLE
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.xml
new file mode 100644
index 0000000000..6a843bbc1a
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.xml
@@ -0,0 +1,18 @@
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <Console name="CONSOLE">
+ <PatternLayout pattern="%d [%t] %p %c - %m%n"/>
+ </Console>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="CONSOLE"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.yaml
new file mode 100644
index 0000000000..5ca83f35da
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-dev.yaml
@@ -0,0 +1,13 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ Console:
+ name: "CONSOLE"
+ PatternLayout:
+ pattern: "%d [%t] %p %c - %m%n"
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "CONSOLE"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.json
similarity index 52%
copy from src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
copy to src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.json
index 4e42604efd..b8a319d7cb 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.json
@@ -2,11 +2,10 @@
"Configuration": {
"Appenders": {
// tag::appender[]
- "NoSql": {
- "name": "MONGO",
- "MongoDb": {
- "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs"
- }
+ "Console": {
+ "name": "CONSOLE",
+ "direct": true, // <1>
+ "JsonTemplateLayout": {} // <2>
}
// end::appender[]
},
@@ -14,7 +13,7 @@
"Root": {
"level": "INFO",
"AppenderRef": {
- "ref": "MONGO"
+ "ref": "CONSOLE"
}
}
}
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.properties
new file mode 100644
index 0000000000..430afa7c8b
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.properties
@@ -0,0 +1,13 @@
+##
+# tag::appender[]
+appender.0.type = Console
+appender.0.name = CONSOLE
+# <1>
+appender.0.direct = true
+
+# <2>
+appender.0.layout.type = JsonTemplateLayout
+# end::appender[]
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = CONSOLE
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.xml
new file mode 100644
index 0000000000..9783918b5a
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.xml
@@ -0,0 +1,19 @@
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <Console name="CONSOLE"
+ direct="true"> <!--1-->
+ <JsonTemplateLayout/> <!--2-->
+ </Console>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="CONSOLE"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.yaml
new file mode 100644
index 0000000000..605943f355
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/console-prod.yaml
@@ -0,0 +1,13 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ Console:
+ name: "CONSOLE"
+ direct: true # <1>
+ JsonTemplateLayout: {} # <2>
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "CONSOLE"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
index 4e42604efd..d06b3a190f 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
@@ -1,6 +1,11 @@
{
"Configuration": {
"Appenders": {
+ "File": {
+ "name": "FILE",
+ "fileName": "logs/mongo.log",
+ "JsonTemplateLayout": {}
+ },
// tag::appender[]
"NoSql": {
"name": "MONGO",
@@ -11,12 +16,32 @@
// end::appender[]
},
"Loggers": {
+ // tag::loggers[]
"Root": {
"level": "INFO",
"AppenderRef": {
"ref": "MONGO"
}
- }
+ },
+ "Logger": [
+ {
+ "name": "org.bson",
+ "level": "WARN",
+ "additivity": false, // <1>
+ "AppenderRef": {
+ "ref": "FILE"
+ }
+ },
+ {
+ "name": "com.mongodb",
+ "level": "WARN",
+ "additivity": false, // <1>
+ "AppenderRef": {
+ "ref": "FILE"
+ }
+ }
+ ]
+ // end::loggers[]
}
}
}
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties
index 9f313e56f2..6a1e188310 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.properties
@@ -15,12 +15,28 @@
# limitations under the License.
#
##
+appender.0.type = File
+appender.0.name = FILE
+appender.0.layout.type = JsonTemplateLayout
# tag::appender[]
-appender.0.type = NoSql
-appender.0.name = MONGO
-appender.0.provider.type = MongoDB
-appender.0.provider.connection = mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs
+appender.1.type = NoSql
+appender.1.name = MONGO
+appender.1.provider.type = MongoDB
+appender.1.provider.connection = mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs
# end::appender[]
-
+# tag::loggers[]
rootLogger.level = INFO
rootLogger.appenderRef.0.ref = MONGO
+
+logger.0.name = org.bson
+logger.0.level = WARN
+# <1>
+logger.0.additivity = false
+logger.0.appenderRef.0.ref = FILE
+
+logger.1.name = com.mongodb
+logger.1.level = WARN
+# <1>
+logger.1.additivity = false
+logger.1.appenderRef.0.ref = FILE
+# end::loggers[]
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml
index fe3a405996..31fe89f2f1 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.xml
@@ -21,6 +21,10 @@
https://logging.apache.org/xml/ns
https://logging.apache.org/xml/ns/log4j-config-2.xsd">
<Appenders>
+ <File name="FILE"
+ fileName="logs/mongo.log">
+ <JsonTemplateLayout/>
+ </File>
<!-- tag::appender[] -->
<NoSql name="MONGO">
<MongoDb connection="mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs"/>
@@ -28,8 +32,20 @@
<!-- end::appender[] -->
</Appenders>
<Loggers>
+ <!-- tag::loggers[] -->
<Root level="INFO">
<AppenderRef ref="MONGO"/>
</Root>
+ <Logger name="org.bson"
+ level="WARN"
+ additivity="false"> <!--1-->
+ <AppenderRef ref="FILE"/>
+ </Logger>
+ <Logger name="com.mongodb"
+ level="WARN"
+ additivity="false"> <!--1-->
+ <AppenderRef ref="FILE"/>
+ </Logger>
+ <!-- end::loggers[] -->
</Loggers>
</Configuration>
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml
index a3a596e618..f5bd4b6612 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.yaml
@@ -16,6 +16,10 @@
#
Configuration:
Appenders:
+ File:
+ name: "FILE"
+ fileName: "logs/mongo.log"
+ JsonTemplateLayout: {}
# tag::appender[]
NoSql:
name: "MONGO"
@@ -23,7 +27,20 @@ Configuration:
connection: "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs"
# end::appender[]
Loggers:
+ # tag::loggers[]
Root:
level: "INFO"
AppenderRef:
ref: "MONGO"
+ Logger:
+ - name: "org.bson"
+ level: "WARN"
+ additivity: false # <1>
+ AppenderRef:
+ ref: "FILE"
+ - name: "com.mongodb"
+ level: "WARN"
+ additivity: false # <1>
+ AppenderRef:
+ ref: "FILE"
+ # end::loggers[]
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.json
new file mode 100644
index 0000000000..ab49abee40
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.json
@@ -0,0 +1,34 @@
+{
+ "Configuration": {
+ "Appenders": {
+ // tag::appender[]
+ "Flume": {
+ "name": "FLUME",
+ "Rfc5424Layout": {
+ "enterpriseNumber": 18060,
+ "includeMDC": true,
+ "appName": "MyAPP"
+ },
+ "Agent": [
+ { // <1>
+ "host": "192.168.10.101",
+ "port": "8800"
+ },
+ { // <2>
+ "host": "192.168.10.102",
+ "port": "8800"
+ }
+ ]
+ }
+ // end::appender[]
+ },
+ "Loggers": {
+ "Root": {
+ "level": "INFO",
+ "AppenderRef": {
+ "ref": "FLUME"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.properties
new file mode 100644
index 0000000000..f3d6958a70
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.properties
@@ -0,0 +1,22 @@
+##
+# tag::appender[]
+appender.0.type = Flume
+appender.0.name = FLUME
+
+appender.0.layout.type = Rfc5424Layout
+appender.0.layout.enterpriseNumber = 18060
+appender.0.layout.includeMDC = true
+appender.0.layout.appName = MyApp
+
+# <1>
+appender.0.primary.type = Agent
+appender.0.primary.host = 192.168.10.101
+appender.0.primary.port = 8800
+# <2>
+appender.0.secondary.type = Agent
+appender.0.secondary.host = 192.168.10.102
+appender.0.secondary.port = 8800
+# end::appender[]
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = FLUME
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.xml
new file mode 100644
index 0000000000..c901427071
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <Flume name="FLUME">
+ <Rfc5424Layout enterpriseNumber="18060"
+ includeMDC="true"
+ appName="MyApp"/>
+ <Agent host="192.168.10.101" port="8800"/> <!--1-->
+ <Agent host="192.168.10.102" port="8800"/> <!--2-->
+ </Flume>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="FLUME"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.yaml
new file mode 100644
index 0000000000..2244b391f1
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-avro.yaml
@@ -0,0 +1,22 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ Flume:
+ name: "FLUME"
+ Rfc5424Layout:
+ enterpriseNumber: 18060
+ includeMDC: true
+ appName: MyApp
+ Agent:
+ # <1>
+ - host: "192.168.10.101"
+ port: 8800
+ # <2>
+ - host: "192.168.10.102"
+ port: 8800
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "FLUME"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.json
new file mode 100644
index 0000000000..e55d3364a0
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.json
@@ -0,0 +1,36 @@
+{
+ "Configuration": {
+ "Appenders": {
+ // tag::appender[]
+ "Flume": {
+ "name": "FLUME",
+ "type": "EMBEDDED",
+ "compress": true,
+ "Rfc5424Layout": {
+ "enterpriseNumber": 18060,
+ "includeMDC": true,
+ "appName": "MyAPP"
+ },
+ "Agent": [
+ {
+ "host": "192.168.10.101",
+ "port": "8800"
+ },
+ {
+ "host": "192.168.10.102",
+ "port": "8800"
+ }
+ ]
+ }
+ // end::appender[]
+ },
+ "Loggers": {
+ "Root": {
+ "level": "INFO",
+ "AppenderRef": {
+ "ref": "FLUME"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.xml
new file mode 100644
index 0000000000..1197e20629
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <Flume name="FLUME"
+ type="EMBEDDED"
+ compress="true">
+ <Rfc5424Layout enterpriseNumber="18060"
+ includeMDC="true"
+ appName="MyApp"/>
+ <Agent host="192.168.10.101" port="8800"/>
+ <Agent host="192.168.10.102" port="8800"/>
+ </Flume>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="FLUME"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.yaml
new file mode 100644
index 0000000000..96e753c4b6
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-embedded.yaml
@@ -0,0 +1,22 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ Flume:
+ name: "FLUME"
+ type: "EMBEDDED"
+ compress: true
+ Rfc5424Layout:
+ enterpriseNumber: 18060
+ includeMDC: true
+ appName: MyApp
+ Agent:
+ - host: "192.168.10.101"
+ port: 8800
+ - host: "192.168.10.102"
+ port: 8800
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "FLUME"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.json
new file mode 100644
index 0000000000..56677809b1
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.json
@@ -0,0 +1,41 @@
+{
+ "Configuration": {
+ "Appenders": {
+ // tag::appender[]
+ "Flume": {
+ "name": "FLUME",
+ "type": "PERSISTENT",
+ "compress": true,
+ "dataDir": "./logData",
+ "Rfc5424Layout": {
+ "enterpriseNumber": 18060,
+ "includeMDC": true,
+ "appName": "MyAPP"
+ },
+ "Property": {
+ "name": "keyProvider",
+ "value": "org.example.MySecretProvider"
+ },
+ "Agent": [
+ {
+ "host": "192.168.10.101",
+ "port": "8800"
+ },
+ {
+ "host": "192.168.10.102",
+ "port": "8800"
+ }
+ ]
+ }
+ // end::appender[]
+ },
+ "Loggers": {
+ "Root": {
+ "level": "INFO",
+ "AppenderRef": {
+ "ref": "FLUME"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.xml
new file mode 100644
index 0000000000..e406073466
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <Flume name="FLUME"
+ type="PERSISTENT"
+ compress="true"
+ dataDir="./logData">
+ <Rfc5424Layout enterpriseNumber="18060"
+ includeMDC="true"
+ appName="MyApp"/>
+ <Property name="keyProvider" value="org.example.MySecretProvider"/>
+ <Agent host="192.168.10.101" port="8800"/>
+ <Agent host="192.168.10.102" port="8800"/>
+ </Flume>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="FLUME"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.yaml
new file mode 100644
index 0000000000..5bcc5854d2
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/flume-persistent.yaml
@@ -0,0 +1,26 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ Flume:
+ name: "FLUME"
+ type: "PERSISTENT"
+ compress: true
+ dataDir: "./logData"
+ Rfc5424Layout:
+ enterpriseNumber: 18060
+ includeMDC: true
+ appName: MyApp
+ Property:
+ name: "keyProvider"
+ value: "org.example.MySecretProvider"
+ Agent:
+ - host: "192.168.10.101"
+ port: 8800
+ - host: "192.168.10.102"
+ port: 8800
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "FLUME"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.json
new file mode 100644
index 0000000000..30d2e79099
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.json
@@ -0,0 +1,30 @@
+{
+ "Configuration": {
+ "Appenders": {
+ // tag::appender[]
+ "JeroMQ": {
+ "name": "JEROMQ",
+ "JsonTemplateLayout": {},
+ "Property": [
+ {
+ "name": "endpoint",
+ "value": "tcp://*:5556"
+ },
+ {
+ "name": "endpoint",
+ "value": "ipc://info-topic"
+ }
+ ]
+ }
+ // end::appender[]
+ },
+ "Loggers": {
+ "Root": {
+ "level": "INFO",
+ "AppenderRef": {
+ "ref": "JEROMQ"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.properties
new file mode 100644
index 0000000000..1265d1746d
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.properties
@@ -0,0 +1,18 @@
+##
+# tag::appender[]
+appender.0.type = JeroMQ
+appender.0.name = JEROMQ
+
+appender.0.layout.type = JsonTemplateLayout
+
+appender.0.endpoint[0].type = Property
+appender.0.endpoint[0].name = endpoint
+appender.0.endpoint[0].value = tcp://*:5556
+
+appender.0.endpoint[1].type = Property
+appender.0.endpoint[1].name = endpoint
+appender.0.endpoint[1].value = ipc://info-topic
+# end::appender[]
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = JEROMQ
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.xml
new file mode 100644
index 0000000000..f03ba60588
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <JeroMQ name="JEROMQ">
+ <JsonTemplateLayout/>
+ <Property name="endpoint" value="tcp://*:5556"/>
+ <Property name="endpoint" value="ipc://info-topic"/>
+ </JeroMQ>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="JEROMQ"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.yaml
new file mode 100644
index 0000000000..c359a2630a
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jeromq.yaml
@@ -0,0 +1,17 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ JeroMQ:
+ name: "JEROMQ"
+ JsonTemplateLayout: {}
+ Property:
+ - name: "endpoint"
+ value: "tcp://*:5556"
+ - name: "endpoint"
+ value: "ipc://info-topic"
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "JEROMQ"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.json
similarity index 52%
copy from src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
copy to src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.json
index 4e42604efd..c755c25ffd 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.json
@@ -2,11 +2,11 @@
"Configuration": {
"Appenders": {
// tag::appender[]
- "NoSql": {
- "name": "MONGO",
- "MongoDb": {
- "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs"
- }
+ "JMS": {
+ "name": "JMS",
+ "factoryBindingName": "jms/ConnectionFactory",
+ "destinationBindingName": "jms/Queue",
+ "MessageLayout": {}
}
// end::appender[]
},
@@ -14,7 +14,7 @@
"Root": {
"level": "INFO",
"AppenderRef": {
- "ref": "MONGO"
+ "ref": "JMS"
}
}
}
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.properties
new file mode 100644
index 0000000000..b5796d97e1
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.properties
@@ -0,0 +1,12 @@
+##
+# tag::appender[]
+appender.0.type = JMS
+appender.0.name = JMS
+appender.0.factoryBindingName = jms/ConnectionFactory
+appender.0.destinationBindingName = jms/Queue
+
+appender.0.layout.type = MessageLayout
+# end::appender[]
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = JMS
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.xml
new file mode 100644
index 0000000000..0b437847ce
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <JMS name="JMS"
+ factoryBindingName="jms/ConnectionFactory"
+ destinationBindingName="jms/Queue">
+ <MessageLayout/>
+ </JMS>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="JMS"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.yaml
new file mode 100644
index 0000000000..ba68cc78e3
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-message.yaml
@@ -0,0 +1,14 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ JMS:
+ name: "JMS"
+ factoryBindingName: "jms/ConnectionFactory"
+ destinationBindingName: "jms/Queue"
+ MessageLayout: {}
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "JMS"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.json
similarity index 52%
copy from src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
copy to src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.json
index 4e42604efd..5d412d113e 100644
--- a/src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo.json
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.json
@@ -2,11 +2,11 @@
"Configuration": {
"Appenders": {
// tag::appender[]
- "NoSql": {
- "name": "MONGO",
- "MongoDb": {
- "connection": "mongodb://${env:DB_USER}:${env:DB_PASS}@localhost:27017/logging.logs"
- }
+ "JMS": {
+ "name": "JMS",
+ "factoryBindingName": "jms/ConnectionFactory",
+ "destinationBindingName": "jms/Queue",
+ "JsonTemplateLayout": {}
}
// end::appender[]
},
@@ -14,7 +14,7 @@
"Root": {
"level": "INFO",
"AppenderRef": {
- "ref": "MONGO"
+ "ref": "JMS"
}
}
}
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.properties
new file mode 100644
index 0000000000..9196ca87cb
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.properties
@@ -0,0 +1,12 @@
+##
+# tag::appender[]
+appender.0.type = JMS
+appender.0.name = JMS
+appender.0.factoryBindingName = jms/ConnectionFactory
+appender.0.destinationBindingName = jms/Queue
+
+appender.0.layout.type = JsonTemplateLayout
+# end::appender[]
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = JMS
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.xml
new file mode 100644
index 0000000000..b005b84421
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <!-- tag::appender[] -->
+ <JMS name="JMS"
+ factoryBindingName="jms/ConnectionFactory"
+ destinationBindingName="jms/Queue">
+ <JsonTemplateLayout/>
+ </JMS>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <Root level="INFO">
+ <AppenderRef ref="JMS"/>
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.yaml
new file mode 100644
index 0000000000..d0fda10333
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/jms-simple.yaml
@@ -0,0 +1,14 @@
+Configuration:
+ Appenders:
+ # tag::appender[]
+ JMS:
+ name: "JMS"
+ factoryBindingName: "jms/ConnectionFactory"
+ destinationBindingName: "jms/Queue"
+ JsonTemplateLayout: {}
+ # end::appender[]
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "JMS"
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.json b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.json
new file mode 100644
index 0000000000..4663576c2f
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.json
@@ -0,0 +1,37 @@
+{
+ "Configuration": {
+ "Appenders": {
+ "File": {
+ "name": "FILE",
+ "fileName": "logs/kafka.log",
+ "JsonTemplateLayout": {}
+ },
+ // tag::appender[]
+ "Kafka": {
+ "name": "KAFKA",
+ "topic": "logs",
+ "key": "$${web:contextName}", // <1>
+ "JsonTemplateLayout": {}
+ }
+ // end::appender[]
+ },
+ "Loggers": {
+ // tag::loggers[]
+ "Root": {
+ "level": "INFO",
+ "AppenderRef": {
+ "ref": "KAFKA"
+ }
+ },
+ "Logger": {
+ "name": "org.apache.kafka",
+ "level": "WARN",
+ "additivity": false, // <1>
+ "AppenderRef": {
+ "ref": "FILE"
+ }
+ }
+ // end::loggers[]
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.properties b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.properties
new file mode 100644
index 0000000000..6482806cf3
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.properties
@@ -0,0 +1,25 @@
+##
+appender.0.type = File
+appender.0.name = FILE
+appender.0.fileName = logs/kafka.log
+appender.0.layout.type = JsonTemplateLayout
+
+# tag::appender[]
+appender.1.type = Kafka
+appender.1.name = KAFKA
+appender.1.topic = logs
+# <1>
+appender.1.key = $${web:contextName}
+
+appender.1.layout.type = JsonTemplateLayout
+# end::appender[]
+# tag::loggers[]
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = KAFKA
+
+logger.0.name = org.apache.kafka
+logger.0.level = WARN
+# <1>
+logger.0.additivity = false
+logger.0.appenderRef.0.ref = FILE
+# end::loggers[]
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.xml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.xml
new file mode 100644
index 0000000000..0b2fbc8111
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.xml
@@ -0,0 +1,31 @@
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <Appenders>
+ <File name="FILE"
+ fileName="logs/kafka.log">
+ <JsonTemplateLayout/>
+ </File>
+ <!-- tag::appender[] -->
+ <Kafka name="KAFKA"
+ topic="logs"
+ key="$${web:contextName}"> <!--1-->
+ <JsonTemplateLayout/>
+ </Kafka>
+ <!-- end::appender[] -->
+ </Appenders>
+ <Loggers>
+ <!-- tag::loggers[] -->
+ <Root level="INFO">
+ <AppenderRef ref="KAFKA"/>
+ </Root>
+ <Logger name="org.apache.kafka"
+ level="WARN"
+ additivity="false"> <!--1-->
+ <AppenderRef ref="FILE"/>
+ </Logger>
+ <!-- end::loggers[] -->
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.yaml b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.yaml
new file mode 100644
index 0000000000..bc07e9b742
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/appenders/message-queue/kafka.yaml
@@ -0,0 +1,26 @@
+Configuration:
+ Appenders:
+ File:
+ name: "FILE"
+ fileName: "logs/kafka.log"
+ JsonTemplateLayout: {}
+ # tag::appender[]
+ Kafka:
+ name: "KAFKA"
+ topic: "logs"
+ key: "$${web:contextName}" # <1>
+ JsonTemplateLayout: {}
+ # end::appender[]
+ Loggers:
+ # tag::loggers[]
+ Root:
+ level: "INFO"
+ AppenderRef:
+ ref: "KAFKA"
+ Logger:
+ name: "org.apache.kafka"
+ level: "WARN"
+ additivity: false # <1>
+ AppenderRef:
+ ref: "FILE"
+ # end::loggers[]
\ No newline at end of file
diff --git a/src/site/antora/modules/ROOT/pages/javadoc.adoc b/src/site/antora/modules/ROOT/pages/javadoc.adoc
index 173a814df5..2c35ccb2ce 100644
--- a/src/site/antora/modules/ROOT/pages/javadoc.adoc
+++ b/src/site/antora/modules/ROOT/pages/javadoc.adoc
@@ -30,6 +30,9 @@ The table below contains links to the Javadoc API Documentation for the componen
| link:javadoc/log4j-jakarta-web/index.html[Log4j Web]
| Tools to use Log4j Core in Jakarta EE applications.
+| link:javadoc/log4j-flume-ng/index.html[Log4j Flume]
+| Tools to use Log4j Core with Apache Flume.
+
| link:javadoc/log4j-jpa/index.html[Log4j JPA]
| Tools to use Log4j Core with the Java Persistence API.
|===
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
index 1d1e84e644..e26217e440 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
@@ -16,6 +16,7 @@
////
= Appenders
+:open-book: 📖
Appenders are responsible for delivering log events to their destination.
Every Appender must implement the
@@ -122,7 +123,7 @@ If you are using
xref:manual/async.adoc[asynchronous loggers]
or
xref:manual/appenders/delegating.adoc#AsyncAppender[appenders], you can set this attribute to `false`.
-Log4j Core will still flush the internal buffer, whenever the log event queue becomes empty.
+Log4j Core will still flush the internal buffer whenever the log event queue becomes empty.
====
[#exception-handling]
@@ -160,18 +161,18 @@ The following configuration attributes are also evaluated at runtime, so can con
|===
| Component | Parameter | Event type | Evaluation context
-| <<HttpAppender,HTTP Appender>>
-| <<HttpAppender-element-headers,`Property/value`>>
+| xref:manual/appenders/network.adoc#HttpAppender[HTTP Appender]
+| xref:manual/appenders/network.adoc#HttpAppender-element-Property[`Property/value`]
| Log event
| xref:manual/lookups.adoc#global-context[_global_]
-| <<KafkaAppender,Kafka Appender>>
-| <<KafkaAppender-attr-key,`key`>>
+| xref:manual/appenders/message-queue.adoc#KafkaAppender[Kafka Appender]
+| xref:manual/appenders/message-queue.adoc#KafkaAppender-attr-key[`key`]
| Log event
| xref:manual/lookups.adoc#global-context[_global_]
-| <<NoSQLAppender,NoSQL Appender>>
-| <<NoSqlAppender-element-keyValuePairs,`KeyValuePair/value`>>
+| xref:manual/appenders/database.adoc#NoSqlAppender[NoSQL Appender]
+| xref:manual/appenders/database.adoc#NoSqlAppender-element-KeyValuePair[`KeyValuePair/value`]
| Log event
| xref:manual/lookups.adoc#global-context[_global_]
@@ -212,603 +213,360 @@ See xref:manual/configuration.adoc#lazy-property-substitution[runtime property s
Log4j bundles several predefined appenders to assist in several common deployment use cases.
They are documented in separate pages based on their target resource:
-[#file-appenders]
-=== File appenders
-
-File appenders write logs to the filesystem.
-They can be further split into:
-
-Single file appenders:::
-See xref:manual/appenders/file.adoc[] for details.
+[#ConsoleAppender]
+=== Console Appender
-Rolling file appenders:::
-See xref:manual/appenders/rolling-file.adoc[] for details.
-
-[#database-appenders]
-=== Database appenders
-
-The appenders write log events directly to a database.
+As one might expect, the Console Appender writes its output to either the standard output or standard error output.
+The appender supports four different ways to access the output streams:
-xref:manual/appenders/database.adoc#CassandraAppender[Cassandra appender]::
-Sends log events to
-https://cassandra.apache.org/_/index.html[Apache Cassandra]
-
-xref:manual/appenders/database.adoc#JdbcAppender[JDBC appender]::
-Sends log events to a JDBC driver
-
-xref:manual/appenders/database.adoc#JpaAppender[JPA appender]::
-Uses Jakarta Persistence API to deliver log events to a database
-
-xref:manual/appenders/database.adoc#NoSqlAppender[NoSQL appender]::
-Store log events to a document-oriented database
-
-See xref:manual/appenders/database.adoc[] for details.
+`direct`::
+This mode gives the best performance.
+It can be enabled by setting the <<ConsoleAppender-attr-direct,`direct`>> attribute to `true`.
-[#network-appenders]
-=== Network appenders
-
-These appenders use simple network protocols to transmit log events to a remote host.
-The supported network protocols are:
-
-`UDP`::
-`TCP`::
-These are handled by the xref:manual/appenders/network.adoc#SocketAppender[Socket Appender].
-
-`HTTP`::
-This is handled by the xref:manual/appenders/network.adoc#HttpAppender[HTTP Appender].
-
-`SMTP`::
-This is handled by the xref:manual/appenders/network.adoc#HttpAppender[SMTP Appender].
-
-See xref:manual/appenders/network.adoc[] for details.
-
-[#delegating-appenders]
-=== Delegating appenders
-
-Delegating appenders are intended to decorate other appenders:
-
-xref:manual/appenders/delegating.adoc#AsyncAppender[Asynchronous appender]::
-Perform all I/O on a dedicated thread
-
-xref:manual/appenders/delegating.adoc#FailoverAppender[Failover appender]::
-Provide a backup appender in case an appender fails
+`default`::
+By default, the Console appender uses the values of `System.out` or `System.err` present at **configuration time**.
+Any changes to those streams at runtime will be ignored.
-xref:manual/appenders/delegating.adoc#RewriteAppender[Rewrite appender]::
-Modify log events prior to delivering them to the target
+`follow`::
+This mode always uses the **current** value of the `System.out` and `System.err` streams.
+It can be enabled by setting the <<ConsoleAppender-attr-follow,`follow`>> attribute to `true`.
++
+[TIP]
+====
+This setting might be useful in multi-application environments.
+Some application servers modify `System.out` and `System.err` to always point to the currently running application.
+====
-xref:manual/appenders/delegating.adoc#RoutingAppender[Routing appender]::
-Dynamically choose a different appender for each log event
+`JANSI`::
+If the application is running on Windows and the
+https://fusesource.github.io/jansi/[JANSI library]
+is available, the Console appender will use JANSI to emulate ANSI sequence support.
+This mode can be disabled by setting the
+xref:manual/systemproperties.adoc#log4j2.skipJansi[`log4j2.skipJansi`]
+configuration attribute to `true`.
++
+Additional runtime dependencies are required to use JANSI:
++
+[tabs]
+====
+Maven::
++
+[source,xml,subs="+attributes"]
+----
+<dependency>
+ <groupId>org.fusesource.jansi</groupId>
+ <artifactId>jansi</artifactId>
+ <version>{jansi-version}</version>
+</dependency>
-See xref:manual/appenders/delegating.adoc[] for details.
+----
-[id=consoleappender]
-=== [[ConsoleAppender]] ConsoleAppender
-
-As one might expect, the ConsoleAppender writes its output to either
-`System.out` or `System.err` with `System.out` being the default target.
-A Layout must be provided to format the LogEvent.
-
-.ConsoleAppender Parameters
-[cols="20%,20%,60%",options="header",]
-|=======================================================================
-|Parameter Name |Type |Description
-|filter |Filter |A Filter to determine if the event should be handled by
-this Appender. More than one Filter may be used by using a
-CompositeFilter.
-
-|layout |Layout |The Layout to use to format the LogEvent. If no layout
-is supplied the default pattern layout of "%m%n" will be used.
-
-|follow |boolean |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`.
-
-|direct |boolean |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 a file or other process. Cannot be used with
-Jansi on Windows. Cannot be used with `follow`. The output will not respect
-`java.lang.System.setOut()/.setErr()` and may get intertwined with other
-output to `java.lang.System.out/.err` in a multi-threaded application.
-_New since 2.6.2. Be aware that this is a new addition, and it has only
-been tested with Oracle JVM on Linux and Windows so far._
-
-|name |String |The name of the Appender.
-
-|ignoreExceptions |boolean |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>>.
-
-|target |String |Either "SYSTEM_OUT" or "SYSTEM_ERR". The default is
-"SYSTEM_OUT".
-|=======================================================================
-
-A typical Console configuration might look like:
-
-[source,xml,prettyprint,linenums]
+Gradle::
++
+[source,groovy,subs="+attributes"]
----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
- <Appenders>
- <Console name="STDOUT" target="SYSTEM_OUT">
- <PatternLayout pattern="%m%n"/>
- </Console>
- </Appenders>
- <Loggers>
- <Root level="error">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration>
+runtimeOnly 'org.fusesource.jansi:jansi:{jansi-version}'
----
-[#FlumeAppender]
-=== FlumeAppender
-
-_This is an optional component supplied in a separate jar._
+====
-https://flume.apache.org/index.html[Apache Flume] is a distributed, reliable, and available system for efficiently collecting, aggregating, and moving large amounts of log data from many different sources to a centralized data store.
-The FlumeAppender takes LogEvents and sends them to a Flume agent as serialized Avro events for consumption.
+[#ConsoleAppender-attributes]
+.Console Appender configuration attributes
+[cols="1m,1,1,5"]
+|===
+| Attribute | Type | Default value | Description
-The Flume Appender supports three modes of operation.
+4+h| Required
-1. It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured with an Avro Source.
-2. It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing.
-3. It can persist events to a local BerkeleyDB data store and then asynchronously send the events to Flume, similar to the embedded Flume Agent but without most of the Flume dependencies.
+| [[ConsoleAppender-attr-name]]name
+| `String`
+|
+| The name of the appender.
-Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel and then control will be immediately returned to the application.
-All interaction with remote agents will occur asynchronously.
-Setting the "type" attribute to "Embedded" will force the use of the embedded agent.
-In addition, configuring agent properties in the appender configuration will also cause the embedded agent to be used.
+4+h| Optional
-.FlumeAppender Parameters
-[width="100%",cols="20%,20%,60%",options="header",]
-|=======================================================================
-|Parameter Name |Type |Description
-|agents |Agent[] |An array of Agents to which the logging events should
-be sent. If more than one agent is specified the first Agent will be the
-primary and subsequent Agents will be used in the order specified as
-secondaries should the primary Agent fail. Each Agent definition
-supplies the Agent's host and port. The specification of agents and
-properties are mutually exclusive. If both are configured an error will
-result.
+| [[ConsoleAppender-attr-bufferSize]]bufferSize
+| `int`
+| xref:manual/systemproperties.adoc#log4j2.encoderByteBufferSize[`8192`]
+a|
+The size of the
+https://docs.oracle.com/javase/{java-target-version}/docs/api/java/nio/ByteBuffer.html[`ByteBuffer`]
+internally used by the appender.
-|agentRetries |integer |The number of times the agent should be retried
-before failing to a secondary. This parameter is ignored when
-`type="persistent"` is specified (agents are tried once before failing to
-the next).
+See <<buffering,Buffering>> for more details.
-|batchSize |integer |Specifies the number of events that should be sent
-as a batch. The default is 1. _This parameter only applies to the Flume
-Appender._
+| [[ConsoleAppender-attr-direct]]direct
+| `boolean`
+| `false`
+a|
+If set to `true`, log events will be written directly to either
+https://docs.oracle.com/javase/8/docs/api/java/io/FileDescriptor.html#out[`FileDescriptor.out`]
+or
+https://docs.oracle.com/javase/8/docs/api/java/io/FileDescriptor.html#err[`FileDescriptor.err`].
-|compress |boolean |When set to true the message body will be compressed
-using gzip
+This setting bypasses the buffering of `System.out` and `System.err` and might provide a performance comparable to a xref:manual/appenders/file.adoc[file appender].
-|connectTimeoutMillis |integer |The number of milliseconds Flume will
-wait before timing out the connection.
+[CAUTION]
+====
-|dataDir |String |Directory where the Flume write-ahead log should be
-written. Valid only when embedded is set to true and Agent elements are
-used instead of Property elements.
+If other logging backends or the application itself uses `System.out/System.err`, setting this to `true` might cause interleaved output.
-|filter |Filter |A Filter to determine if the event should be handled by
-this Appender. More than one Filter may be used by using a
-CompositeFilter.
+====
-|eventPrefix |String |The character string to prepend to each event
-attribute to distinguish it from MDC attributes. The default is
-an empty string.
+This setting is incompatible with the
+<<ConsoleAppender-attr-follow,`follow` attribute>>
+and
+xref:manual/systemproperties.adoc#log4j2.skipJansi[JANSI support].
+
+| [[ConsoleAppender-attr-follow]]
+follow
+| `boolean`
+| `false`
+|
+If set to `true`, the appender will honor reassignments of `System.out` (resp. `System.err`) via
+https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#setOut-java.io.PrintStream-[`System.setOut`]
+(resp.
+https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#setOut-java.io.PrintStream-[`System.setErr`]).
+
+Otherwise, the value of `System.out` (resp. `System.err`) at configuration time will be used.
+
+This setting is incompatible with the
+<<ConsoleAppender-attr-direct,`direct` attribute>>
+and
+xref:manual/systemproperties.adoc#log4j2.skipJansi[JANSI support].
+
+| [[ConsoleAppender-attr-ignoreExceptions]]
+ignoreExceptions
+| `boolean`
+| `true`
+| If `false`, logging exception will be forwarded to the caller of the logging statement.
+Otherwise, they will be ignored.
+
+Logging exceptions are always also logged to xref:manual/status-logger.adoc[]
+
+| [[ConsoleAppender-attr-immediateFlush]]
+immediateFlush
+| `boolean`
+| `true`
+|
+If set to `true`, the appender will flush its internal buffer and the buffer of the `System.out/System.err` stream after each log event.
+
+See xref:manual/appenders.adoc#buffering[Buffering] for more details.
+
+| [[ConsoleAppender-attr-target]]
+target
+| link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/ConsoleAppender.Target.html[`Target`]
+| link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/ConsoleAppender.Target.html#SYSTEM_OUT[`SYSTEM_OUT`]
+a|
+It specifies which standard output stream to use:
+
+`SYSTEM_OUT`::
+It uses the standard output.
+
+`SYSTEM_ERR`::
+It uses the standard error output.
-|flumeEventFactory |FlumeEventFactory |Factory that generates the Flume
-events from Log4j events. The default factory is the FlumeAvroAppender
-itself.
+|===
-|layout |Layout |The Layout to use to format the LogEvent. If no layout
-is specified RFC5424Layout will be used.
+[#ConsoleAppender-elements]
+.Common nested elements
+[cols="1m,1,4"]
+|===
-|lockTimeoutRetries |integer |The number of times to retry if a
-LockConflictException occurs while writing to Berkeley DB. The default
-is 5.
+| Type | Multiplicity | Description
-|maxDelayMillis |integer |The maximum number of milliseconds to wait for
-batchSize events before publishing the batch.
+| [[ConsoleAppender-element-Filter]]
+xref:manual/filters.adoc[`Filter`]
+| zero or one
+|
+Allows filtering log events just before they are formatted and sent.
-|mdcExcludes |String |A comma-separated list of mdc keys that should be
-excluded from the FlumeEvent. This is mutually exclusive with the
-mdcIncludes attribute.
+See also xref:manual/filters.adoc#appender-stage[appender filtering stage].
-|mdcIncludes |String |A comma-separated list of mdc keys that should be
-included in the FlumeEvent. Any keys in the MDC not found in the list
-will be excluded. This option is mutually exclusive with the mdcExcludes
-attribute.
+| [[ConsoleAppender-element-Layout]]
+xref:manual/layouts.adoc[`Layout`]
+| zero or one
+|
+Formats log events.
-|mdcRequired |String |A comma-separated list of `mdc` keys that must be
-present in the MDC. If a key is not present a LoggingException will be
-thrown.
+See xref:manual/layouts.adoc[] for more information.
-|mdcPrefix |String |A string that should be prepended to each MDC key to distinguish it from event attributes. The default string is
-"mdc:".
+|===
-|name |String |The name of the Appender.
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-ConsoleAppender[{open-book} Plugin reference for `Console`]
-|properties |Property[] a|
-One or more Property elements that are used to configure the Flume
-Agent. The properties must be configured without the agent name (the
-appender name is used for this) and no sources can be configured.
-Interceptors can be specified for the source using
-"sources.log4j-source.interceptors". All other Flume configuration
-properties are allowed. Specifying both Agent and Property elements will
-result in an error.
+[#ConsoleAppender-examples]
+==== Configuration examples
-When used to configure in Persistent mode the valid properties are:
+A typical configuration in a **development** environment might look like:
-1. `keyProvider` to specify the name of the plugin to provide the
-secret key for encryption.
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-dev.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/console-dev.xml[tag=appender]
+----
-|requestTimeoutMillis |integer |The number of milliseconds Flume will
-wait before timing out the request.
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-dev.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/console-dev.json[tag=appender]
+----
-|ignoreExceptions |boolean |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>>.
-
-|type |enumeration |One of "Avro", "Embedded", or "Persistent" to
-indicate which variation of the Appender is desired.
-|=======================================================================
-
-A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body and formats the body using the RFC5424Layout:
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-dev.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/console-dev.yaml[tag=appender]
+----
-[source,xml]
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-dev.properties[`log4j2.properties`]
+[source,properties,indent=0]
----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
- <Appenders>
- <Flume name="eventLogger" compress="true">
- <Agent host="192.168.10.101" port="8800"/>
- <Agent host="192.168.10.102" port="8800"/>
- <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
- </Flume>
- </Appenders>
- <Loggers>
- <Root level="error">
- <AppenderRef ref="eventLogger"/>
- </Root>
- </Loggers>
-</Configuration>
+include::example$manual/appenders/console-dev.properties[tag=appender]
----
+====
-A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body, formats the body using the RFC5424Layout, and persists encrypted events to disk:
+A typical configuration for a **production** environment might look like
-[source,xml]
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-prod.xml[`log4j2.xml`]
+[source,xml,indent=0]
----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
- <Appenders>
- <Flume name="eventLogger" compress="true" type="persistent" dataDir="./logData">
- <Agent host="192.168.10.101" port="8800"/>
- <Agent host="192.168.10.102" port="8800"/>
- <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
- <Property name="keyProvider">MySecretProvider</Property>
- </Flume>
- </Appenders>
- <Loggers>
- <Root level="error">
- <AppenderRef ref="eventLogger"/>
- </Root>
- </Loggers>
-</Configuration>
+include::example$manual/appenders/console-prod.xml[tag=appender]
----
-A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body, and formats the body using RFC5424Layout and passes the events to an embedded Flume Agent.
-
-[source,xml]
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-prod.json[`log4j2.json`]
+[source,json,indent=0]
----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
- <Appenders>
- <Flume name="eventLogger" compress="true" type="Embedded">
- <Agent host="192.168.10.101" port="8800"/>
- <Agent host="192.168.10.102" port="8800"/>
- <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
- </Flume>
- <Console name="STDOUT">
- <PatternLayout pattern="%d [%p] %c %m%n"/>
- </Console>
- </Appenders>
- <Loggers>
- <Logger name="EventLogger" level="info">
- <AppenderRef ref="eventLogger"/>
- </Logger>
- <Root level="warn">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration>
+include::example$manual/appenders/console-prod.json[tag=appender]
----
-A sample FlumeAppender configuration that is configured with a primary and a secondary agent using Flume configuration properties compresses the body, formats the body using RFC5424Layout and passes the events to an embedded Flume Agent.
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-prod.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/console-prod.yaml[tag=appender]
+----
-[source,xml]
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/console-prod.properties[`log4j2.properties`]
+[source,properties,indent=0]
----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="error" name="MyApp">
- <Appenders>
- <Flume name="eventLogger" compress="true" type="Embedded">
- <Property name="channels">file</Property>
- <Property name="channels.file.type">file</Property>
- <Property name="channels.file.checkpointDir">target/file-channel/checkpoint</Property>
- <Property name="channels.file.dataDirs">target/file-channel/data</Property>
- <Property name="sinks">agent1 agent2</Property>
- <Property name="sinks.agent1.channel">file</Property>
- <Property name="sinks.agent1.type">avro</Property>
- <Property name="sinks.agent1.hostname">192.168.10.101</Property>
- <Property name="sinks.agent1.port">8800</Property>
- <Property name="sinks.agent1.batch-size">100</Property>
- <Property name="sinks.agent2.channel">file</Property>
- <Property name="sinks.agent2.type">avro</Property>
- <Property name="sinks.agent2.hostname">192.168.10.102</Property>
- <Property name="sinks.agent2.port">8800</Property>
- <Property name="sinks.agent2.batch-size">100</Property>
- <Property name="sinkgroups">group1</Property>
- <Property name="sinkgroups.group1.sinks">agent1 agent2</Property>
- <Property name="sinkgroups.group1.processor.type">failover</Property>
- <Property name="sinkgroups.group1.processor.priority.agent1">10</Property>
- <Property name="sinkgroups.group1.processor.priority.agent2">5</Property>
- <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
- </Flume>
- <Console name="STDOUT">
- <PatternLayout pattern="%d [%p] %c %m%n"/>
- </Console>
- </Appenders>
- <Loggers>
- <Logger name="EventLogger" level="info">
- <AppenderRef ref="eventLogger"/>
- </Logger>
- <Root level="warn">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration>
+include::example$manual/appenders/console-prod.properties[tag=appender]
----
+====
-[#jms-appender]
-=== [[JMSAppender]]JMS Appender
+<1> Improve performance by setting <<ConsoleAppender-attr-direct,`direct`>> to `true`.
+<2> Use a structured layout.
+Additional dependencies are required, see xref:manual/json-template-layout.adoc[].
-The JMS Appender sends the formatted log event to a JMS Destination.
+[#file-appenders]
+=== File appenders
-The JMS Appender requires JNDI support so as of release 2.17.0, this appender will not function unless `log4j2.enableJndiJms=true` is configured as a system property or environment variable.
-See the https://logging.apache.org/log4j/2.x/manual/configuration.html#enableJndiJms[enableJndiJms] system property.
+File appenders write logs to the filesystem.
+They can be further split into:
-Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender.
-Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics.
-However, configurations written for 2.0 that use the `<JMSQueue/>` or `<JMSTopic/>` elements will continue to work with the new `<JMS/>` configuration element.
+Single file appenders:::
+See xref:manual/appenders/file.adoc[] for details.
-.JMS Appender Parameters
-[cols="1,1,1,3",options="header"]
-|===
-| Parameter Name | Type | Default | Description
-
-| factoryBindingName
-| String
-| _Required_
-| The name to locate in the Context that provides the
-https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/connectionfactory[ConnectionFactory].
-This can be any subinterface of `ConnectionFactory` as well.
-
-| factoryName
-| String
-| _Required_
-| The fully qualified class name that should be used to define the Initial Context Factory as defined in https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[`INITIAL_CONTEXT_FACTORY`]. If a `factoryName` is specified without a `providerURL`, a warning message will be logged as this is likely to cause problems.
-
-| filter
-| Filter
-| null
-| A Filter to determine if the event should be handled by this Appender. More than one Filter may be used by using a CompositeFilter.
-
-| layout
-| Layout
-| _Required_
-| The Layout to use to format the LogEvent. _New since 2.9, in previous versions SerializedLayout was default._
-
-| name
-| String
-| _Required_
-| The name of the Appender.
-
-| password
-| String
-| null
-| The password to use to create the JMS connection.
-
-| providerURL
-| String
-| _Required_
-| The URL of the provider to use as defined by https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#PROVIDER_URL[PROVIDER_URL]. From Log4j 2.17, only the `java:` protocol is supported.
-
-| destinationBindingName
-| String
-| _Required_
-| The name to use to locate the
-https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/destination[Destination].
-This can be a `Queue` or `Topic`, and as such, the attribute names `queueBindingName` and `topicBindingName` are aliases to maintain compatibility with the Log4j 2.0 JMS appenders.
-
-| securityPrincipalName
-| String
-| null
-| The name of the identity of the Principal as specified by https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[SECURITY_PRINCIPAL]. If a securityPrincipalName is specified without `securityCredentials`, a warning message will be logged as this is likely to cause problems.
-
-| securityCredentials
-| String
-| null
-| The security credentials for the principal as specified by https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS[SECURITY_CREDENTIALS].
-
-| ignoreExceptions
-| boolean
-| true
-| When `true`, exceptions caught while appending events are internally logged and then ignored. When `false` exceptions are propagated to the caller. You must set this to `false` when wrapping this Appender in a FailoverAppender.
-
-| immediateFail
-| boolean
-| false
-| When set to true, log events will not wait to try to reconnect and will fail immediately if the JMS resources are not available. New in 2.9.
-
-| reconnectIntervalMillis
-| long
-| 5000
-| If set to a value greater than 0, after an error, the JMSManager will attempt to reconnect to the broker after waiting the specified number of milliseconds. If the reconnect fails then an exception will be thrown (which can be caught by the application if `ignoreExceptions` is set to `false`). New in 2.9.
-
-| urlPkgPrefixes
-| String
-| null
-| A colon-separated list of package prefixes for the class name of the factory class that will create a URL context factory as defined by https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#URL_PKG_PREFIXES[URL_PKG_PREFIXES].
-
-| userName
-| String
-| null
-| The user ID used to create the JMS connection.
-|===
+Rolling file appenders:::
+See xref:manual/appenders/rolling-file.adoc[] for details.
-Here is a sample JMS Appender configuration:
+[#database-appenders]
+=== Database appenders
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
- <Appenders>
- <JMS name="jmsQueue" destinationBindingName="MyQueue"
- factoryBindingName="MyQueueConnectionFactory">
- <JsonLayout properties="true"/>
- </JMS>
- </Appenders>
- <Loggers>
- <Root level="error">
- <AppenderRef ref="jmsQueue"/>
- </Root>
- </Loggers>
-</Configuration>
-----
+The appenders write log events directly to a database.
-To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the layout of the appender to `MessageLayout` with `<MessageLayout />` (Since 2.9.):
+xref:manual/appenders/database.adoc#CassandraAppender[Cassandra appender]::
+Sends log events to
+https://cassandra.apache.org/_/index.html[Apache Cassandra]
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
- <Appenders>
- <JMS name="jmsQueue" destinationBindingName="MyQueue"
- factoryBindingName="MyQueueConnectionFactory">
- <MessageLayout />
- </JMS>
- </Appenders>
- <Loggers>
- <Root level="error">
- <AppenderRef ref="jmsQueue"/>
- </Root>
- </Loggers>
-</Configuration>
-----
+xref:manual/appenders/database.adoc#JdbcAppender[JDBC appender]::
+Sends log events to a JDBC driver
-[[KafkaAppender]]
-=== KafkaAppender
+xref:manual/appenders/database.adoc#JpaAppender[JPA appender]::
+Uses Jakarta Persistence API to deliver log events to a database
-The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic.
-Each log event is sent as a Kafka record.
+xref:manual/appenders/database.adoc#NoSqlAppender[NoSQL appender]::
+Store log events to a document-oriented database
-[cols="1m,1m,5"]
-|===
-|Parameter Name |Type |Description
-
-|topic
-|String
-|The Kafka topic to use. Required.
-
-|[[KafkaAppender-attr-key]]key
-|String
-|The key that will be sent to Kafka with every message.
-
-Supports
-xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution]
-and is evaluated in the
-xref:manual/lookups.adoc#event-context[_context of the current event_].
-
-|filter
-|Filter
-|A Filter to determine if the event should be handled by this Appender. More than one Filter may be used by using a CompositeFilter.
-
-|layout
-|Layout
-|The Layout to use to format the LogEvent. Required, there is no default. _New since 2.9, in previous versions `<PatternLayout pattern="%m"/>` was default._
-
-|name
-|String
-|The name of the Appender. Required.
-
-|ignoreExceptions
-|boolean
-|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>>.
-
-|syncSend
-|boolean
-|The default is `true`, causing sends to block until the record has been acknowledged by the Kafka server. When set to `false`, sends a return immediately, allowing for lower latency and significantly higher throughput. _New since 2.8. Be aware that this is a new addition, and it has not been extensively tested.
-Any failure sending to Kafka will be reported as an error to xref:manual/status-logger.adoc[] and the log event will be dropped (the ignoreExceptions parameter will not be effective).
-Log events may arrive out of order on the Kafka server._
-
-|properties
-|Property[]
-|You can set properties in https://kafka.apache.org/documentation.html#producerconfigs[Kafka producer properties]. You need to set the `bootstrap.servers` property, there are sensible default values for the others. Do not set the `value.serializer` nor `key.serializer` properties.
-|===
+See xref:manual/appenders/database.adoc[] for details.
-Here is a sample KafkaAppender configuration snippet:
+[#network-appenders]
+=== Network appenders
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration>
- <!-- ... -->
- <Appenders>
- <Kafka name="Kafka" topic="log-test">
- <PatternLayout pattern="%date %message"/>
- <Property name="bootstrap.servers">localhost:9092</Property>
- </Kafka>
- </Appenders>
- <!-- ... -->
-</Configuration>
-----
+These appenders use simple network protocols to transmit log events to a remote host.
+The supported network protocols are:
+
+`UDP`::
+`TCP`::
+These are handled by the xref:manual/appenders/network.adoc#SocketAppender[Socket Appender].
+
+`HTTP`::
+This is handled by the xref:manual/appenders/network.adoc#HttpAppender[HTTP Appender].
+
+`SMTP`::
+This is handled by the xref:manual/appenders/network.adoc#HttpAppender[SMTP Appender].
-This appender is synchronous by default and will block until the record has been acknowledged by the Kafka server, timeout for this can be set with the `timeout.ms` property (defaults to 30 seconds).
-Wrap with https://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender[Async appender] and/or set syncSend to `false` to log asynchronously.
+See xref:manual/appenders/network.adoc[] for details.
-This appender requires the https://kafka.apache.org/[Kafka client library].
-Note that you need to use a version of the Kafka client library matching the Kafka server used.
+[#message-queue-appenders]
+=== Message queue appenders
-_Note:_ Make sure to not let `org.apache.kafka` log to a Kafka appender on DEBUG level, since that will cause recursive logging:
+Message queue appenders forward log events to a message broker to provide guaranteed delivery over the network.
+The following systems are supported:
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration>
- <!-- ... -->
- <Loggers>
- <Root level="DEBUG">
- <AppenderRef ref="Kafka"/>
- </Root>
- <Logger name="org.apache.kafka" level="INFO" /> <!-- avoid recursive logging -->
- </Loggers>
- <!-- ... -->
-</Configuration>
-----
+xref:manual/appenders/message-queue.adoc#FlumeAppender[Flume appender]::
+Forwards log events to an
+https://flume.apache.org/[Apache Flume] server.
+
+xref:manual/appenders/message-queue.adoc#JmsAppender[JMS appender]::
+Forwards log events to a
+https://jakarta.ee/specifications/messaging/2.0/[Jakarta Message 2.0] broker.
+
+xref:manual/appenders/message-queue.adoc#KafkaAppender[Kafka appender]::
+Forwards log events to an
+https://kafka.apache.org/[Apache Kafka] server.
-[#servlet-appender]
-=== Servlet appender
+xref:manual/appenders/message-queue.adoc#JeroMqAppender[ZeroMQ/JeroMQ appender]::
+Forwards log events to a
+https://zeromq.org/[ZeroMQ] broker.
-The servlet appender allows users to forward all logging calls to the
+See xref:manual/appenders/message-queue.adoc[] for details.
+
+[#ServletAppender]
+=== Servlet Appender
+
+The Servlet appender allows users to forward all logging calls to the
https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/servlet/servletcontext#log(java.lang.String,java.lang.Throwable)[`ServletContext.log()`]
methods.
+
+[CAUTION]
+====
+The `ServletContext.log(String, Throwable)` method predates modern logging APIs.
+By using Servlet appender, you typically will not be able to differentiate log events by log level or logger name.
+====
+
+The Servlet Appender has no configuration attributes.
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-jakarta-web_org-apache-logging-log4j-web-appender-ServletAppender[{open-book} Plugin reference for `Servlet`]
+
You can use it by declaring an appender of type `Servlet` in your configuration file:
[tabs]
@@ -853,145 +611,24 @@ include::partial$manual/dependencies-log4j-jakarta-web.adoc[]
See xref:jakarta.adoc[] for more information.
-[CAUTION]
-====
-The `ServletContext.log(String, Throwable)` method predates modern logging APIs.
-By using Servlet appender you typically will not be able to differentiate log events by log level or logger name.
-====
-
-
-[[JeroMQAppender]]
-=== ZeroMQ/JeroMQ Appender
-
-The ZeroMQ appender uses the https://github.com/zeromq/jeromq[JeroMQ] library to send log events to one or more ZeroMQ endpoints.
-
-This is a simple JeroMQ configuration:
-
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration name="JeroMQAppenderTest" status="TRACE">
- <Appenders>
- <JeroMQ name="JeroMQAppender">
- <Property name="endpoint">tcp://*:5556</Property>
- <Property name="endpoint">ipc://info-topic</Property>
- </JeroMQ>
- </Appenders>
- <Loggers>
- <Root level="info">
- <AppenderRef ref="JeroMQAppender"/>
- </Root>
- </Loggers>
-</Configuration>
-----
-
-The table below describes all options.
-Please consult the JeroMQ and ZeroMQ documentation for details.
-
-[width="100%",options="header"]
-|===
-|Parameter Name |Type |Description
-
-|name
-|String
-|The name of the Appender. Required.
-
-|Layout
-|layout
-|The Layout to use to format the LogEvent. If no layout is supplied the default pattern layout of "%m%n" will be used.
-
-|Filters
-|Filter
-|The Filter(s) of the Appender.
-
-|Properties
-|Property[]
-|One or more Property elements, named `endpoint`.
-
-|ignoreExceptions
-|boolean
-|If true, exceptions will be logged and suppressed. If false errors will be logged and then passed to the application.
-
-|affinity
-|long
-|The ZMQ_AFFINITY option. Defaults to 0.
-
-|backlog
-|long
-|The ZMQ_BACKLOG option. Defaults to 100.
-
-|delayAttachOnConnect
-|boolean
-|The ZMQ_DELAY_ATTACH_ON_CONNECT option. Defaults to false.
-
-|identity
-|byte[]
-|The ZMQ_IDENTITY option. Defaults to none.
-
-|ipv4Only
-|boolean
-|The ZMQ_IPV4ONLY option. Defaults to true.
-
-|linger
-|long
-|The ZMQ_LINGER option. Defaults to -1.
-
-|maxMsgSize
-|long
-|The ZMQ_MAXMSGSIZE option. Defaults to -1.
-
-|rcvHwm
-|long
-|The ZMQ_RCVHWM option. Defaults to 1000.
-
-|receiveBufferSize
-|long
-|The ZMQ_RCVBUF option. Defaults to 0.
-
-|receiveTimeOut
-|int
-|The ZMQ_RCVTIMEO option. Defaults to -1.
-
-|reconnectIVL
-|long
-|The ZMQ_RECONNECT_IVL option. Defaults to 100.
-
-|reconnectIVLMax
-|long
-|The ZMQ_RECONNECT_IVL_MAX option. Defaults to 0.
-
-|sendBufferSize
-|long
-|The ZMQ_SNDBUF option. Defaults to 0.
-
-|sendTimeOut
-|int
-|The ZMQ_SNDTIMEO option. Defaults to -1.
+[#delegating-appenders]
+=== Delegating appenders
-|sndHwm
-|long
-|The ZMQ_SNDHWM option. Defaults to 1000.
+Delegating appenders are intended to decorate other appenders:
-|tcpKeepAlive
-|int
-|The ZMQ_TCP_KEEPALIVE option. Defaults to -1.
+xref:manual/appenders/delegating.adoc#AsyncAppender[Asynchronous appender]::
+Perform all I/O on a dedicated thread
-|tcpKeepAliveCount
-|long
-|The ZMQ_TCP_KEEPALIVE_CNT option. Defaults to -1.
+xref:manual/appenders/delegating.adoc#FailoverAppender[Failover appender]::
+Provide a backup appender in case an appender fails
-|tcpKeepAliveIdle
-|long
-|The ZMQ_TCP_KEEPALIVE_IDLE option. Defaults to -1.
+xref:manual/appenders/delegating.adoc#RewriteAppender[Rewrite appender]::
+Modify log events prior to delivering them to the target
-|tcpKeepAliveInterval
-|long
-|The ZMQ_TCP_KEEPALIVE_INTVL option. Defaults to -1.
+xref:manual/appenders/delegating.adoc#RoutingAppender[Routing appender]::
+Dynamically choose a different appender for each log event
-|xpubVerbose
-|boolean
-|The ZMQ_XPUB_VERBOSE option. Defaults to false.
-|===
+See xref:manual/appenders/delegating.adoc[] for details.
[#extending]
== Extending
@@ -1001,7 +638,7 @@ This section will guide you on how to create custom ones.
[WARNING]
====
-*Implementing a reliable and efficient appender is a difficult task!*
+*Implementing a reliable and efficient appender is a challenging task!*
We strongly advise you to
. Use existing appenders and/or managers whenever appropriate
@@ -1024,12 +661,12 @@ While annotating your appender with `@Plugin`, you need to make sure that
* The `category` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`]
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.
+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 <<collection,the predefined appenders>>, and either use an existing manager, or create your own.
-You can check out following files for examples:
+You can check out the following files for examples:
-* {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/HttpAppender.java[`HttpAppender.java`] – xref:manual/appenders/network.adoc#HttpAppender[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 --git a/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc
index a6359c6447..922be024bc 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc
@@ -27,7 +27,7 @@ Log4j Core provides multiple appenders to send log events directly to your datab
=== Column mapping
Since relational databases and some NoSQL databases split data into columns, Log4j Core provides a reusable
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/db/ColumnMapping.html[`ColumnMapping`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/appender/db/ColumnMapping.html[`ColumnMapping`]
configuration element to allow specifying the content of each column.
The Column Mapping element supports the following configuration properties:
@@ -69,7 +69,7 @@ For any other value:
. The log event will be formatted using the <<ColumnMapping-element-Layout,nested `Layout`>>.
. The resulting `String` will be converted to the specified type using a
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html[`TypeConverter`].
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html[`TypeConverter`].
See the
xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverter[plugin reference]
for a list of available type converters.
@@ -123,7 +123,7 @@ This attribute is used only if:
* The <<ColumnMapping-element-Layout,nested `Layout` element>>
is a
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/layout/MessageLayout.html[`MessageLayout`].
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/layout/MessageLayout.html[`MessageLayout`].
* The message being logged is a `MapMessage`
|===
@@ -519,7 +519,7 @@ See <<ConnectionSource>> for more details.
| zero or one
|
An optional
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html[`Layout<? extends Message>`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html[`Layout<? extends Message>`]
implementation that formats a log event as
xref:manual/messages.adoc[log `Message`].
@@ -535,7 +535,7 @@ xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-loggin
=== Connection Sources
When configuring the JDBC Appender, you must specify an implementation of
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.html[`ConnectionSource`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.html[`ConnectionSource`]
that the appender will use to get
https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html[`Connection`] objects.
@@ -860,14 +860,19 @@ See <<JpaAppender-persistence>> below.
* configure the JPA Appender.
See <<JpaAppender-configuration>> below.
+[IMPORTANT]
+====
+Due to breaking changes in the underlying API, the JPA Appender cannot be used with Jakarta Persistence API 3.0 or later.
+====
+
[#JpaAppender-persistence]
=== Persistence configuration
To store log events using JPA, you need to implement a JPA Entity that extends the
-link:../javadoc/log4j-jpa/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.html[`AbstractLogEventWrapperEntity`]
+link:../../javadoc/log4j-jpa/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.html[`AbstractLogEventWrapperEntity`]
class.
To help you with the implementation, Log4j provides a
-link:../javadoc/log4j-jpa/org/apache/logging/log4j/core/appender/db/jpa/BasicLogEventEntity.html[`BasicLogEventEntity`]
+link:../../javadoc/log4j-jpa/org/apache/logging/log4j/core/appender/db/jpa/BasicLogEventEntity.html[`BasicLogEventEntity`]
class that only lacks an identity field.
A simple `AbstractLogEventWrapperEntity` implementation might look like:
@@ -927,7 +932,7 @@ The JPA appender supports these configuration options:
| The fully qualified name of the entity class to use.
The type must extend
-link:../javadoc/log4j-jpa/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.html[`AbstractLogEventWrapperEntity`].
+link:../../javadoc/log4j-jpa/org/apache/logging/log4j/core/appender/db/jpa/AbstractLogEventWrapperEntity.html[`AbstractLogEventWrapperEntity`].
4+h| Optional
@@ -1092,7 +1097,7 @@ xref:manual/lookups.adoc#event-context[current event as context].
| zero or one
|
An optional
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html[`Layout<? extends MapMessage>`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html[`Layout<? extends MapMessage>`]
implementation that formats a log event as
xref:manual/messages.adoc#MapMessage[`MapMessage`].
@@ -1126,7 +1131,7 @@ include::example$manual/appenders/database/nosql-log-event.json[]
The NoSQL Appender only handles the conversion of log events into NoSQL documents, and it delegates database-specific tasks to a NoSQL provider.
NoSQL providers are Log4j plugins that implement the
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/nosql/NoSqlProvider.html[`NoSqlProvider`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/appender/nosql/NoSqlProvider.html[`NoSqlProvider`]
interface.
Log4j Core currently provides the following providers:
@@ -1501,6 +1506,48 @@ include::example$manual/appenders/database/nosql-mongo.properties[tag=appender]
----
====
+[NOTE]
+=====
+Make sure to not let `org.bson`, `com.mongodb` log to a MongoDB database on a `DEBUG` level, since that will cause recursive logging:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/database/nosql-mongo.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/database/nosql-mongo.xml[tag=loggers]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/database/nosql-mongo.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/database/nosql-mongo.json[tag=loggers]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/database/nosql-mongo.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/database/nosql-mongo.yaml[tag=loggers]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/database/nosql-mongo.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/database/nosql-mongo.properties[tag=loggers]
+----
+====
+
+<1> Remember to set the xref:manual/configuration.adoc#logger-attributes-additivity[`additivity`] configuration attribute to `false`.
+=====
+
A similar configuration for an Apache CouchDB database looks like:
[tabs]
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders/delegating.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/delegating.adoc
index b04af5edd7..2a500dfb0f 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders/delegating.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders/delegating.adoc
@@ -211,7 +211,7 @@ include::example$manual/appenders/delegating/async.properties[tag=appenders]
=== Queue full policy
When the queue is full the `Async` Appender uses an
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html[`AsyncQueueFullPolicy`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html[`AsyncQueueFullPolicy`]
to decide whether to:
* drop the log event.
@@ -226,7 +226,7 @@ See xref:manual/systemproperties.adoc#properties-async[Async components] for mor
=== Blocking Queue Factories
The `Async` appender allows you to customize the blocking queue used by specifying a nested
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/BlockingQueueFactory.html[`BlockingQueueFactory`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/async/BlockingQueueFactory.html[`BlockingQueueFactory`]
element.
You can specify the size of the queue using the <<AsyncAppender-attr-bufferSize,`bufferSize`>> configuration attribute.
@@ -536,7 +536,7 @@ xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-loggin
=== Rewrite Policies
A rewrite policy is a Log4j plugin that implements the
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/rewrite/RewritePolicy.html[`RewritePolicy`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/appender/rewrite/RewritePolicy.html[`RewritePolicy`]
interface.
Rewrite policies allow to apply arbitrary modifications to log events.
@@ -558,7 +558,7 @@ It allows adding or updating the keys of the `MapMessage`.
| Attribute | Type | Default value | Description
| [[MapRewritePolicy-attr-mode]]mode
-| link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.Mode.html[`MapRewritePolicy.Mode`]
+| link:../../javadoc/log4j-core/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.Mode.html[`MapRewritePolicy.Mode`]
| link:../https://logging.apache.org/log4j/2.x/javadoc/log4j-core/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicy.Mode.html#Add[`Add`]
a|
It determines which map entries to modify:
@@ -854,7 +854,7 @@ This is the same map, which is passed to the <<RoutingAppender-element-AbstractS
`logEvent`::
The
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[`LogEvent`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[`LogEvent`]
being processed.
`configuration`::
@@ -962,7 +962,7 @@ If your default <<Route,`Route` element>> contains an <<Route-element-Appender,a
These appenders might be useful only for a short period of time, but will consume system resources unless they are stopped.
The purge policy is a Log4j plugin that implements the
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/routing/PurgePolicy.html[`PurgePolicy`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/appender/routing/PurgePolicy.html[`PurgePolicy`]
interface and handles the lifecycle of automatically instantiated appenders.
xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-routing-PurgePolicy[{open-book} Plugin reference for `PurgePolicy`]
@@ -1149,7 +1149,7 @@ include::example$manual/appenders/delegating/routing-script.properties[tag=appen
<1> The <<RoutingAppender-element-AbstractScript,`Routing` script>> performs the initialization of state variables.
<2> The <<Routes-element-AbstractScript,`Routes` script>> returns the name of the server to use.
It also exports the value as `server` entry in
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html#getProperties()[`Configuration.getProperties()`].
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html#getProperties()[`Configuration.getProperties()`].
<3> The exported value can be used as `+${server}+` in the appender definition.
[#ScriptAppenderSelector]
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders/message-queue.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/message-queue.adoc
new file mode 100644
index 0000000000..c4a128aac4
--- /dev/null
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders/message-queue.adoc
@@ -0,0 +1,1211 @@
+////
+ 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.
+////
+
+= Message Queue Appenders
+:open-book: 📖
+
+[#FlumeAppender]
+== Flume Appender
+
+https://flume.apache.org/index.html[Apache Flume] is a distributed, reliable, and available system for efficiently collecting, aggregating, and moving large amounts of log data from many different sources to a centralized data store.
+The Flume Appender takes log events and sends them to a Flume agent as serialized Avro events for consumption.
+
+The Flume Appender supports three modes of operation.
+
+[#FlumeAppender-mode-AVRO]
+`AVRO`::
+It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured with an Avro Source.
+
+[#FlumeAppender-mode-EMBEDDED]
+`EMBEDDED`::
+It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing.
+
+[#FlumeAppender-mode-PERSISTENT]
+`PERSISTENT`::
+It can persist events to a local BerkeleyDB data store and then asynchronously send the events to Flume, similar to the embedded Flume Agent but without most of the Flume dependencies.
+
+Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel, and then control will be immediately returned to the application.
+All interaction with remote agents will occur asynchronously.
+Setting the <<FlumeAppender-attr-type,`type` attribute>> to `EMBEDDED` will force the use of the embedded agent.
+In addition, configuring agent properties in the appender configuration will also cause the embedded agent to be used.
+
+[#FlumeAppender-attributes]
+.Flume Appender configuration attributes
+[cols="1m,1,1,5"]
+|===
+| Attribute | Type | Default value | Description
+
+4+h| Required
+
+| [[FlumeAppender-attr-name]]name
+| `String`
+|
+| The name of the appender.
+
+4+h| Optional
+
+| [[FlumeAppender-attr-type]]type
+| _enumeration_
+| `AVRO`
+|
+One of
+<<FlumeAppender-mode-AVRO,AVRO>>,
+<<FlumeAppender-mode-EMBEDDED,EMBEDDED>>
+or
+<<FlumeAppender-mode-PERSISTENT,PERSISTENT>>
+to indicate which variation of the Appender is desired.
+
+| [[FlumeAppender-attr-ignoreExceptions]]ignoreExceptions
+| `boolean`
+| `true`
+| If `false`, logging exception will be forwarded to the caller of the logging statement.
+Otherwise, they will be ignored.
+
+Logging exceptions are always also logged to xref:manual/status-logger.adoc[]
+
+| [[FlumeAppender-attr-connectTimeoutMillis]]connectTimeoutMillis
+| `int`
+| `0`
+|
+The connect timeout in milliseconds.
+If `0` the timeout is infinite.
+
+| [[FlumeAppender-attr-requestTimeoutMillis]]requestTimeoutMillis
+| `int`
+| `0`
+|The request timeout in milliseconds.
+If `0` the timeout is infinite.
+
+| [[FlumeAppender-attr-agentRetries]]agentRetries
+| `int`
+| `0`
+|
+The number of times the agent should be retried before failing to a secondary.
+This parameter is ignored when `type="persistent"` is specified (agents are tried once before failing to
+the next).
+
+| [[FlumeAppender-attr-batchSize]]batchSize
+| `int`
+| `1`
+|
+It specifies the number of events that should be sent as a batch.
+
+| [[FlumeAppender-attr-compress]]compress
+| `boolean`
+| `false`
+|
+When set to `true` the message body will be compressed using gzip.
+
+| [[FlumeAppender-attr-dataDir]]dataDir
+| https://docs.oracle.com/javase/{java-target-version}/docs/api/java/nio/file/Path.html[`Path`]
+|
+|
+Directory where the Flume write-ahead log should be written.
+Valid only when embedded is set to true and Agent elements are used instead of Property elements.
+
+| [[FlumeAppender-attr-eventPrefix]]eventPrefix
+| `String`
+| `""`
+|
+The character string to prepend to each event attribute to distinguish it from MDC attributes.
+
+| [[FlumeAppender-attr-lockTimeoutRetries]]lockTimeoutRetries
+| `int`
+| `5`
+|
+The number of times to retry if a LockConflictException occurs while writing to Berkeley DB.
+
+| [[FlumeAppender-attr-maxDelayMillis]]maxDelayMillis
+| `int`
+| `60000`
+|
+The maximum number of milliseconds to wait for <<FlumeAppender-attr-batchSize,batchSize>> events before publishing the batch.
+
+| [[FlumeAppender-attr-mdcExcludes]]mdcExcludes
+| `String[]`
+|
+|A comma-separated list of mdc keys that should be excluded from the FlumeEvent.
+
+This is mutually exclusive with the <<FlumeAppender-attr-mdcIncludes,mdcIncludes>> attribute.
+
+| [[FlumeAppender-attr-mdcIncludes]]mdcIncludes
+| `String[]`
+|
+|
+A comma-separated list of mdc keys that should be included in the `FlumeEvent`.
+Any keys in the MDC not found in the list will be excluded.
+
+This option is mutually exclusive with the <<FlumeAppender-attr-mdcExcludes,mdcExcludes>> attribute.
+
+| [[FlumeAppender-attr-mdcRequired]]mdcRequired
+| `String[]`
+|
+|
+A comma-separated list of `mdc` keys that must be present in the MDC.
+If a key is not present, a LoggingException will be thrown.
+
+| [[FlumeAppender-attr-mdcPrefix]]mdcPrefix
+| `String`
+| `mdc:`
+|
+A string that should be prepended to each MDC key to distinguish it from event attributes.
+
+|===
+
+[#FlumeAppender-elements]
+.Flume Appender nested elements
+[cols="1m,1,4"]
+|===
+| Type | Multiplicity | Description
+
+| [[FlumeAppender-element-Agent]]<<Agent,`Agent`>>
+| zero or more
+|
+An array of Agents to which the logging events should be sent.
+If more than one agent is specified, the first Agent will be the primary and subsequent Agents will be used in the order specified as secondaries should the primary Agent fail.
+Each Agent definition supplies the Agent's host and port.
+
+The specification of agents and <<FlumeAppender-element-Property,properties>> are mutually exclusive.
+
+| [[FlumeAppender-element-Filter]]xref:manual/filters.adoc[`Filter`]
+| zero or one
+|
+Allows filtering log events just before they are formatted and sent.
+
+See also xref:manual/filters.adoc#appender-stage[appender filtering stage].
+
+| [[FlumeAppender-element-FlumeEventFactory]]<<FlumeEventFactory,`FlumeEventFactory`>>
+| zero or one
+|
+Factory that generates the Flume events from Log4j events.
+
+The default factory is the appender itself.
+
+| [[FlumeAppender-element-Layout]]xref:manual/layouts.adoc[`Layout`]
+| zero or one
+|
+Formats log events.
+If not provided, xref:manual/layouts.adoc#RFC5424Layout[Rfc5424 Layout] is used.
+
+See xref:manual/layouts.adoc[] for more information.
+
+| [[FlumeAppender-element-Property]]xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Property[`Property`]
+| zero or more
+|
+One or more Property elements that are used to configure the Flume Agent.
+The properties must be configured without the agent name, the appender name is used for this, and no sources can be configured.
+Interceptors can be specified for the source using "sources.log4j-source.interceptors".
+All other Flume configuration properties are allowed.
+Specifying both Agent and Property elements will result in an error.
+
+When used to configure in Persistent mode, the valid properties are:
+
+1. `keyProvider` to specify the name of the plugin to provide the
+secret key for encryption.
+
+The specification of <<FlumeAppender-element-Agent,agents>> and properties are mutually exclusive.
+|===
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-flume-ng_org-apache-logging-log4j-flume-appender-FlumeAppender[{open-book} Plugin reference for `Flume`]
+
+Additional runtime dependencies are required to use the Flume Appender:
+
+[tabs]
+====
+Maven::
++
+[source,xml]
+----
+<!-- We assume you use `log4j-bom` for dependency management -->
+<dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-flume-ng</artifactId>
+ <scope>runtime</scope>
+</dependency>
+----
+
+Gradle::
++
+[source,groovy]
+----
+// We assume you use `log4j-bom` for dependency management
+runtimeOnly 'org.apache.logging.log4j:log4j-flume-ng'
+----
+====
+
+[#Agent]
+=== Agent Addresses
+
+The address of the Flume server is specified using the `Agent` element, which supports the following configuration options:
+
+[#Agent-attributes]
+.`Agent` configuration attributes
+[cols="1m,1,1,5"]
+|===
+| Attribute | Type | Default value | Description
+
+| [[Agent-attr-host]]host
+| https://docs.oracle.com/javase/8/docs/api/java/net/InetAddress.html[`InetAddress`]
+| `localhost`
+| The host to connect to.
+
+| [[Agent-attr-port]]port
+| `int`
+| `35853`
+| The port to connect to.
+
+|===
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-flume-ng_org-apache-logging-log4j-flume-appender-Agent[{open-book} Plugin reference for `Agent`]
+
+[#FlumeEventFactory]
+=== Flume event factories
+
+Flume event factories are Log4j plugins that implement the
+link:../../javadoc/log4j-flume-ng/org/apache/logging/log4j/flume/appender/FlumeEventFactory.html[`FlumeEventFactory`]
+and allow to customize the way log events are transformed into
+link:../../javadoc/log4j-flume-ng/org/apache/logging/log4j/flume/appender/FlumeEvent.html[`FlumeEvent`]s.
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-flume-ng_org-apache-logging-log4j-flume-appender-FlumeEventFactory[{open-book} Plugin reference for `FlumeEventFactory`]
+
+[#FlumeAppender-examples]
+=== Configuration examples
+
+A sample Flume Appender which is configured with a primary and a secondary agent, compresses the body and formats the body using the RFC5424 Layout:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-avro.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-avro.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-avro.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-avro.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-avro.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-avro.yaml[tag=appender]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-avro.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-avro.properties[tag=appender]
+----
+====
+
+<1> Primary agent
+<2> Secondary agent
+
+A sample Flume Appender, which is configured with a primary and a secondary agent, compresses the body, formats the body using the RFC5424 Layout, and persists encrypted events to disk:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-persistent.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-persistent.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-persistent.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-persistent.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-persistent.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-persistent.yaml[tag=appender]
+----
+
+Properties::
++
+This example cannot be configured using Java properties.
+====
+
+A sample Flume Appender, which is configured with a primary and a secondary agent compresses the body, formats the body using RFC5424 Layout, and passes the events to an embedded Flume Agent.
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-embedded.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-embedded.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-embedded.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-embedded.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/flume-embedded.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/flume-embedded.yaml[tag=appender]
+----
+
+Properties::
++
+This example cannot be configured using Java properties.
+====
+
+[#JmsAppender]
+== JMS Appender
+
+The JMS Appender sends the formatted log event to a
+https://jakarta.ee/specifications/messaging/2.0/[Jakarta Messaging API]
+destination.
+
+[IMPORTANT]
+====
+As of Log4j `2.17.0` you need to enable the JMS Appender **explicitly** by setting the
+xref:manual/systemproperties.adoc#log4j2.enableJndiJms[`log4j2.enableJndiJms`]
+configuration property to `true`.
+
+Due to breaking changes in the underlying API, the JMS Appender cannot be used with Jakarta Messaging API 3.0 or later.
+====
+
+[#JmsAppender-attributes]
+.JMS Appender configuration attributes
+[cols="1m,1,1,5"]
+|===
+| Attribute | Type | Default value | Description
+
+4+h| Required
+
+| [[JmsAppender-attr-name]]name
+| `String`
+|
+| The name of the appender.
+
+| [[JmsAppender-attr-factoryBindingName]]factoryBindingName
+| https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Name.html[`Name`]
+|
+|
+The JNDI name of the
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/connectionfactory[`ConnectionFactory`].
+
+Only the `java:` protocol is supported.
+
+| [[JmsAppender-attr-destinationBindingName]]destinationBindingName
+| https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Name.html[`Name`]
+|
+|
+The JNDI name of the
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/destination[`Destination`], which can be either a
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/queue[`Queue`]
+or a
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/topic[`Topic`].
+
+Only the `java:` protocol is supported.
+
+4+h| JNDI configuration (overrides system properties)
+
+| [[JmsAppender-attr-factoryName]]factoryName
+| String
+|
+|
+It specifies the
+https://docs.oracle.com/javase/8/docs/api/javax/naming/spi/InitialContextFactory.html[`InitialContextFactory`].
+
+See
+https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[INITIAL_CONTEXT_FACTORY]
+for details.
+
+| [[JmsAppender-attr-urlPkgPrefixes]]urlPkgPrefixes
+| String[]
+|
+|
+A colon-separated list of package prefixes that contain URL context factories.
+
+See https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#URL_PKG_PREFIXES[URL_PKG_PREFIXES] for details.
+
+| [[JmsAppender-attr-providerURL]]providerURL
+| String
+|
+|
+A configuration parameter for the <<JmsAppender-attr-factoryName,`InitialContextFactory`>>.
+
+See https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#PROVIDER_URL[PROVIDER_URL]
+for details.
+
+| [[JmsAppender-attr-securityPrincipalName]]securityPrincipalName
+| String
+|
+|
+The name of the principal to use for the <<JmsAppender-attr-factoryName,`InitialContextFactory`>>.
+
+See
+https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[SECURITY_PRINCIPAL]
+for details.
+
+| securityCredentials
+| String
+| null
+|
+The security credentials for the <<JmsAppender-attr-securityPrincipalName,principal>>.
+
+See
+https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS[SECURITY_CREDENTIALS]
+for details.
+
+4+h| Optional
+
+| [[JmsAppender-attr-userName]]userName
+| `String`
+|
+|
+The username for the
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/connectionfactory[`ConnectionFactory`].
+
+| [[JmsAppender-attr-password]]password
+| `String`
+|
+|
+The password for the
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/connectionfactory[`ConnectionFactory`].
+
+| [[JmsAppender-attr-ignoreExceptions]]ignoreExceptions
+| `boolean`
+| `true`
+| If `false`, logging exception will be forwarded to the caller of the logging statement.
+Otherwise, they will be ignored.
+
+Logging exceptions are always also logged to xref:manual/status-logger.adoc[]
+
+| [[JmsAppender-attr-reconnectIntervalMillis]]reconnectIntervalMillis
+| `long`
+| `5000`
+|The request timeout in milliseconds.
+If `0` the timeout is infinite.
+
+|===
+
+[#JmsAppender-elements]
+.JMS Appender nested elements
+[cols="1m,1,4"]
+|===
+| Type | Multiplicity | Description
+
+| [[JmsAppender-element-Filter]]xref:manual/filters.adoc[`Filter`]
+| zero or one
+|
+Allows filtering log events just before they are formatted and sent.
+
+See also xref:manual/filters.adoc#appender-stage[appender filtering stage].
+
+| [[JmsAppender-element-Layout]]xref:manual/layouts.adoc[`Layout`]
+| **one**
+|
+Used in the mapping process to get a JMS
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/message[`Message`].
+
+See <<JmsAppender-mapping>> below for more information.
+
+|===
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-mom-JmsAppender[{open-book} Plugin reference for `JMS`]
+
+[#JmsAppender-mapping]
+=== Mapping events to JMS messages
+
+The mapping between log events and JMS messages has two steps:
+
+. First, the xref:manual/layouts.adoc[layout] is used to transform a log event into an intermediary format.
+. Then, a https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/message[`Message`] is created based on the type of object returned by the layout:
+
+`String`::
+Strings are converted into
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/textmessage[`TextMessage`]s.
+
+xref:manual/messages.adoc#MapMessage[`MapMessage`]::
+The Log4j `MapMessage` type is mapped to the JMS
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/mapmessage[`MapMessage`]
+type.
+
+`Serializable`::
+Anything else is converted into an
+https://jakarta.ee/specifications/platform/8/apidocs/javax/jms/objectmessage[`ObjectMessage`].
+
+[#JmsAppender-examples]
+=== Configuration examples
+
+Here is a sample JMS Appender configuration:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-simple.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-simple.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-simple.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-simple.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-simple.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-simple.yaml[tag=appender]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-simple.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-simple.properties[tag=appender]
+----
+====
+
+To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the layout of the appender to xref:manual/layouts.adoc#MessageLayout[`MessageLayout`]:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-message.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-message.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-message.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-message.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-message.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-message.yaml[tag=appender]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jms-message.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/message-queue/jms-message.properties[tag=appender]
+----
+====
+
+[[KafkaAppender]]
+== Kafka Appender
+
+The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic.
+Each log event is sent as a
+https://kafka.apache.org/30/javadoc/org/apache/kafka/clients/producer/ProducerRecord.html[`ProducerRecord<byte[\], byte[\]>`], where:
+
+* the key is provided by the byte representation of the <<KafkaAppender-attr-key,`key`>> attribute.
+* the value is provided by the byte representation produced by the <<KafkaAppender-element-Layout,layout>>.
+
+This appender is synchronous by default and will block until the record has been acknowledged by the Kafka server.
+The maximum delivery time can be configured using the
+https://kafka.apache.org/documentation.html#producerconfigs_delivery.timeout.ms[Kafka `delivery.timeout.ms` property].
+Wrap the appender with an
+xref:manual/appenders/delegating.adoc[Async Appender]
+or set
+<<KafkaAppender-attr-syncSend,`syncSend`>>
+to `false` to log asynchronously.
+
+[#KafkaAppender-attributes]
+.Kafka Appender configuration attributes
+[cols="1m,1,1,5"]
+|===
+| Attribute | Type | Default value | Description
+
+4+h| Required
+
+| [[KafkaAppender-attr-name]]name
+| `String`
+|
+| The name of the appender.
+
+
+| [[KafkaAppender-attr-topic]]topic
+| `String`
+|
+|
+The Kafka topic to use.
+
+4+h| Optional
+
+| [[KafkaAppender-attr-key]]key
+| `String`
+|
+|
+The key of the Kafka
+https://kafka.apache.org/30/javadoc/org/apache/kafka/clients/producer/ProducerRecord.html[`ProducerRecord`].
+
+Supports
+xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution]
+and is evaluated in the
+xref:manual/lookups.adoc#global-context[_global context_].
+
+| [[KafkaAppender-attr-ignoreExceptions]]ignoreExceptions
+| `boolean`
+| `true`
+| If `false`, logging exception will be forwarded to the caller of the logging statement.
+Otherwise, they will be ignored.
+
+Logging exceptions are always also logged to xref:manual/status-logger.adoc[]
+
+| [[KafkaAppender-attr-syncSend]]syncSend
+| `boolean`
+| `true`
+a|
+If `true`, the appender blocks until the record has been acknowledged by the Kafka server.
+Otherwise, the appender returns immediately, allowing for lower latency and significantly higher throughput.
+
+[NOTE]
+====
+If set to `false` any failure sending to Kafka will be reported as an error to xref:manual/status-logger.adoc[] and the log event will be dropped.
+The <<KafkaAppender-attr-ignoreExceptions,`ignoreExceptions`>> setting will not be effective.
+
+Log events may arrive out of order on the Kafka server.
+====
+|===
+
+[#KafkaAppender-elements]
+.Kafka Appender nested elements
+[cols="1m,1,4"]
+|===
+| Type | Multiplicity | Description
+
+| [[KafkaAppender-element-Filter]]xref:manual/filters.adoc[`Filter`]
+| zero or one
+|
+Allows filtering log events just before they are formatted and sent.
+
+See also xref:manual/filters.adoc#appender-stage[appender filtering stage].
+
+| [[KafkaAppender-element-Layout]]xref:manual/layouts.adoc[`Layout`]
+| **one**
+|
+Formats the log event as a byte array using
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html#toByteArray(org.apache.logging.log4j.core.LogEvent)[`Layout.toByteArray()`].
+
+See xref:manual/layouts.adoc[] for more information.
+
+| [[KafkaAppender-element-Property]]xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Property[`Property`]
+| one or more
+a|
+These properties are forwarded directly to the Kafka producer.
+See
+https://kafka.apache.org/documentation.html#producerconfigs[Kafka producer properties]
+for more details.
+
+`bootstrap.servers`::
+This property is **required**.
+
+`key.serializer`::
+`value.serializer`::
+These properties should not be used.
+
+|===
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-mom-kafka-KafkaAppender[{open-book} Plugin reference for `Kafka`]
+
+Additional runtime dependencies are required to use the Kafka Appender:
+
+[tabs]
+====
+Maven::
++
+[source,xml,subs="+attributes"]
+----
+<dependency>
+ <groupId>org.apache.kafka</groupId>
+ <artifactId>kafka-clients</artifactId>
+ <version>{kafka-version}</version>
+</dependency>
+----
+
+Gradle::
++
+[source,groovy,subs="+attributes"]
+----
+runtimeOnly 'org.apache.kafka:kafka-clients:{kafka-version}'
+----
+====
+
+[#KafkaAppender-examples]
+=== Configuration examples
+
+Here is a sample Kafka Appender configuration snippet:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.yaml[tag=appender]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.properties[tag=appender]
+----
+====
+
+<1> The <<KafkaAppender-attr-key,`key`>> attribute supports runtime lookups.
+
+[NOTE]
+=====
+Make sure to not let `org.apache.kafka` log to a Kafka appender on `DEBUG` level, since that will cause recursive logging:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.xml[tag=loggers]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.json[tag=loggers]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.yaml[tag=loggers]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/kafka.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/message-queue/kafka.properties[tag=loggers]
+----
+====
+
+<1> Remember to set the xref:manual/configuration.adoc#logger-attributes-additivity[`additivity`] configuration attribute to `false`.
+=====
+
+[[JeroMqAppender]]
+== ZeroMQ/JeroMQ Appender
+
+The ZeroMQ appender uses the https://github.com/zeromq/jeromq[JeroMQ] library to send log events to one or more ZeroMQ endpoints.
+
+[#JeroMqAppender-attributes]
+.JeroMQ Appender configuration attributes
+[cols="1m,1,1,5"]
+|===
+| Attribute | Type | Default value | Description
+
+4+h| Required
+
+| [[JeroMqAppender-attr-name]]name
+| `String`
+|
+| The name of the appender.
+
+4+h| Optional
+
+| [[JeroMqAppender-attr-ignoreExceptions]]ignoreExceptions
+| `boolean`
+| `true`
+| If `false`, logging exception will be forwarded to the caller of the logging statement.
+Otherwise, they will be ignored.
+
+Logging exceptions are always also logged to xref:manual/status-logger.adoc[]
+
+| [[JeroMqAppender-attr-affinity]]affinity
+| `long`
+| `0`
+|
+The I/O affinity of the sending thread.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setAffinity(long)[`Socket.setAffinity()`]
+for more details.
+
+| [[JeroMqAppender-attr-backlog]]backlog
+| `int`
+| `100`
+|
+The maximum size of the backlog.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setBacklog(long)[`Socket.setBacklog()`]
+for more details.
+
+| [[JeroMqAppender-attr-delayAttachOnConnect]]delayAttachOnConnect
+| `boolean`
+| `false`
+|
+Delays the attachment of a pipe on connection.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setDelayAttachOnConnect(long)[`Socket.setDelayAttachOnConnect()`]
+for more details.
+
+| [[JeroMqAppender-attr-identity]]identity
+| `byte[]`
+|
+|
+It sets the identity of the socket.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setIdentity(byte[])[`Socket.setIdentity()`]
+for more details.
+
+| [[JeroMqAppender-attr-ipv4Only]]ipv4Only
+| `boolean`
+| `true`
+|
+If set, only IPv4 will be used.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setIPv4Only(long)[`Socket.setIPv4Only()`]
+for more details.
+
+| [[JeroMqAppender-attr-linger]]linger
+| `long`
+| `-1`
+|
+It sets the linger-period for the socket.
+The value `-1` mean infinite.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setLinger(long)[`Socket.setLinger()`]
+for more details.
+
+| [[JeroMqAppender-attr-maxMsgSize]]maxMsgSize
+| `long`
+| `-1`
+|
+Size limit in bytes for inbound messages.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setMaxMsgSize(long)[`Socket.setMaxMsgSize()`]
+for more details.
+
+| [[JeroMqAppender-attr-rcvHwm]]rcvHwm
+| `int`
+| `1000`
+|
+It sets the high-water mark for inbound messages.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setRcvHWM(long)[`Socket.setRcvHWM()`]
+for more details.
+
+| [[JeroMqAppender-attr-receiveBufferSize]]receiveBufferSize
+| `long`
+| `0`
+|
+It sets the OS buffer size for inbound messages.
+A value of `0` uses the OS default value.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setReceiveBufferSize(long)[`Socket.setReceiveBufferSize()`]
+for more details.
+
+| [[JeroMqAppender-attr-receiveTimeOut]]receiveTimeOut
+| `int`
+| `-1`
+|
+It sets the timeout in milliseconds for receive operations.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setReceiveTimeOut(long)[`Socket.setReceiveTimeOut()`]
+for more details.
+
+| [[JeroMqAppender-attr-reconnectIVL]]reconnectIVL
+| `int`
+| `100`
+|
+It sets the reconnection interval.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setReconnectIVL(long)[`Socket.setReconnectIVL()`]
+for more details.
+
+| [[JeroMqAppender-attr-reconnectIVLMax]]reconnectIVLMax
+| `long`
+| `0`
+|
+It sets the maximum reconnection interval.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setReconnectIVLMax(long)[`Socket.setReconnectIVLMax()`]
+for more details.
+
+| [[JeroMqAppender-attr-sendBufferSize]]sendBufferSize
+| `int`
+| `0`
+|
+It sets the OS buffer size for outbound messages.
+A value of `0` uses the OS default value.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setSendBufferSize(long)[`Socket.setSendBufferSize()`]
+for more details.
+
+| [[JeroMqAppender-attr-sendTimeOut]]sendTimeOut
+| `int`
+| `-1`
+|
+It sets the timeout in milliseconds for send operations.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setSendTimeOut(long)[`Socket.setSendTimeOut()`]
+for more details.
+
+| [[JeroMqAppender-attr-sndHwm]]sndHwm
+| `int`
+| `1000`
+|
+It sets the OS buffer size for outbound messages.
+A value of `0` uses the OS default value.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setSendBufferSize(long)[`Socket.setSendBufferSize()`]
+for more details.
+
+| [[JeroMqAppender-attr-tcpKeepAlive]]tcpKeepAlive
+| `int`
+| `-1`
+a|
+A value of:
+
+`0`:: disables TCP keep-alive packets.
+
+`1`:: enables TCP keep-alive packets.
+
+`-1`:: uses the OS default value.
+
+See
+https://www.javadoc.io/doc/org.zeromq/jeromq/latest/org/zeromq/ZMQ.Socket.html#setTCPKeepAlive(long)[`Socket.setTCPKeepAlive()`]
+for more details.
+
+| [[JeroMqAppender-attr-tcpKeepAliveCount]]tcpKeepAliveCount
+| `long`
+| `-1`
+|
+It sets the maximum number of keep-alive probes before dropping the connection.
+A value of `-1` uses the OS default.
+
+See
+https://www.javadoc.io/doc/org.zeromq/jeromq/latest/org/zeromq/ZMQ.Socket.html#setTCPKeepAliveCount(long)[`Socket.setTCPKeepAliveCount()`]
+for more details.
+
+| [[JeroMqAppender-attr-tcpKeepAliveIdle]]tcpKeepAliveIdle
+| `long`
+| `-1`
+|
+It sets the time a connection needs to remain idle before keep-alive probes are sent.
+The unit depends on the OS and a value of `-1` uses the OS default.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setTCPKeepAliveIdle(long)[`Socket.setTCPKeepAliveIdle()`]
+for more details.
+
+| [[JeroMqAppender-attr-tcpKeepAliveInterval]]tcpKeepAliveInterval
+| `long`
+| `-1`
+|
+It sets the time between two keep-alive probes.
+The unit depends on the OS and a value of `-1` uses the OS default.
+
+See
+https://www.javadoc.io/static/org.zeromq/jeromq/0.6.0/org/zeromq/ZMQ.Socket.html#setTCPKeepAliveInterval(long)[`Socket.setTCPKeepAliveInterval()`]
+for more details.
+
+| [[JeroMqAppender-attr-xpubVerbose]]xpubVerbose
+| `boolean`
+| `false`
+|
+If `true`, all subscriptions are passed upstream.
+
+See
+https://www.javadoc.io/doc/org.zeromq/jeromq/latest/org/zeromq/ZMQ.Socket.html#setXpubVerbose(long)[`Socket.setXpubVerbose()`]
+for more details.
+|===
+
+[#JeroMqAppender-elements]
+.JeroMQ Appender nested elements
+[cols="1m,1,4"]
+|===
+| Type | Multiplicity | Description
+
+| [[JeroMqAppender-element-Filter]]xref:manual/filters.adoc[`Filter`]
+| zero or one
+|
+Allows filtering log events just before they are formatted and sent.
+
+See also xref:manual/filters.adoc#appender-stage[appender filtering stage].
+
+| [[JeroMqAppender-element-Layout]]xref:manual/layouts.adoc[`Layout`]
+| **one**
+|
+Formats the log event as a byte array using
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html#toByteArray(org.apache.logging.log4j.core.LogEvent)[`Layout.toByteArray()`].
+
+See xref:manual/layouts.adoc[] for more information.
+
+| [[JeroMqAppender-element-Property]]xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Property[`Property`]
+| one or more
+|
+Only properties with an `endpoint` name are supported.
+At least one is required to provide the address of the endpoint to connect to.
+
+See
+https://www.javadoc.io/doc/org.zeromq/jeromq/latest/org/zeromq/ZMQ.Socket.html#connect(java.lang.String)[`Socket.connect` JavaDoc]
+for more details.
+|===
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-mom-jeromq-JeroMqAppender[{open-book} Plugin reference for `JeroMQ`]
+
+
+Additional runtime dependencies are required to use the JeroMQ Appender:
+
+[tabs]
+====
+Maven::
++
+[source,xml,subs="+attributes"]
+----
+<dependency>
+ <groupId>org.zeromq</groupId>
+ <artifactId>jeromq</artifactId>
+ <version>{jeromq-version}</version>
+</dependency>
+----
+
+Gradle::
++
+[source,groovy,subs="+attributes"]
+----
+runtimeOnly 'org.zeromq:jeromq:{jeromq-version}'
+----
+====
+
+[#JeroMqAppender-examples]
+=== Configuration examples
+
+This is a simple JeroMQ configuration:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jeromq.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/appenders/message-queue/jeromq.xml[tag=appender]
+----
+
+JSON::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jeromq.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/appenders/message-queue/jeromq.json[tag=appender]
+----
+
+YAML::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jeromq.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/appenders/message-queue/jeromq.yaml[tag=appender]
+----
+
+Properties::
++
+.Snippet from an example {antora-examples-url}/manual/appenders/message-queue/jeromq.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/appenders/message-queue/jeromq.properties[tag=appender]
+----
+====
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders/network.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/network.adoc
index 43719dbfe7..5756963f63 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders/network.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders/network.adoc
@@ -268,7 +268,7 @@ include::example$manual/appenders/network/ssl.properties[tag=ssl]
The HTTP Appender sends log events over HTTP, by wrapping them in an HTTP request.
The `Content-Type` HTTP header is set based on the
-link:../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html#getContentType()[`getContentType()`]
+link:../../javadoc/log4j-core/org/apache/logging/log4j/core/Layout.html#getContentType()[`getContentType()`]
method of the
<<HttpAppender-element-Layout,nested layout>>.
Additional headers can be configured using the nested
diff --git a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
index 6b8e2ff940..689f44a60d 100644
--- a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
@@ -708,7 +708,7 @@ It bundles several predefined event templates modeling popular JSON-based log fo
Read more on xref:manual/json-template-layout.adoc[]...
-[#MapMessageLayout]
+[#MessageLayout]
=== Message Layout
`MessageLayout` is a special layout that extracts the