This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/2.x by this push:
new f56454a88f Fix `flowtracing.adoc` examples (#2662)
f56454a88f is described below
commit f56454a88faf49276377a8be08612b419bf8b8b6
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Wed Jun 19 13:30:42 2024 +0200
Fix `flowtracing.adoc` examples (#2662)
Co-authored-by: Piotr P. Karwasz <[email protected]>
---
src/site/antora/antora.tmpl.yml | 2 +
src/site/antora/antora.yml | 4 +-
.../ROOT/examples/manual/flowtracing/log4j2.json | 43 +++
.../examples/manual/flowtracing/log4j2.properties | 36 +++
.../ROOT/examples/manual/flowtracing/log4j2.xml | 43 +++
.../ROOT/examples/manual/flowtracing/log4j2.yaml | 40 +++
.../ROOT/examples/manual/flowtracing/logback.xml | 78 ++++++
src/site/antora/modules/ROOT/pages/faq.adoc | 2 +-
.../modules/ROOT/pages/manual/architecture.adoc | 4 +-
.../modules/ROOT/pages/manual/flowtracing.adoc | 305 ++++++++++++---------
.../modules/ROOT/pages/manual/getting-started.adoc | 4 +-
.../modules/ROOT/pages/manual/installation.adoc | 11 +-
.../modules/ROOT/pages/manual/pattern-layout.adoc | 8 +-
.../ROOT/pages/manual/systemproperties.adoc | 2 +-
.../modules/ROOT/pages/migrate-from-logback.adoc | 5 +-
.../modules/ROOT/pages/migrate-from-slf4j.adoc | 12 +-
.../antora/modules/ROOT/partials/concepts.adoc | 6 +-
.../properties-log4j-core-misc.adoc | 2 +
18 files changed, 442 insertions(+), 165 deletions(-)
diff --git a/src/site/antora/antora.tmpl.yml b/src/site/antora/antora.tmpl.yml
index 6be7c65d8c..8b7c1fd4ab 100644
--- a/src/site/antora/antora.tmpl.yml
+++ b/src/site/antora/antora.tmpl.yml
@@ -45,8 +45,10 @@ asciidoc:
project-id: "log4j"
java-target-version: "${maven.compiler.target}"
java-compiler-version: "${minimalJavaBuildVersion}"
+ logback-url: "https://logback.qos.ch"
logging-services-url: "https://logging.apache.org"
lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor"
+ slf4j-url: "https://www.slf4j.org"
# Dependency versions
commons-csv-version: "${site-commons-csv.version}"
commons-logging-version: "${site-commons-logging.version}"
diff --git a/src/site/antora/antora.yml b/src/site/antora/antora.yml
index 0feb6d46f3..e027636b21 100644
--- a/src/site/antora/antora.yml
+++ b/src/site/antora/antora.yml
@@ -45,8 +45,10 @@ asciidoc:
project-id: "log4j"
java-target-version: "8"
java-compiler-version: "[17,18)"
+ logback-url: "https://logback.qos.ch"
logging-services-url: "https://logging.apache.org"
- lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor/"
+ lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor"
+ slf4j-url: "https://www.slf4j.org"
# Dependency versions
commons-csv-version: "1.2.3-commons-csv"
commons-logging-version: "1.2.3-commons-logging"
diff --git
a/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.json
b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.json
new file mode 100644
index 0000000000..d20f770f85
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.json
@@ -0,0 +1,43 @@
+{
+ "Configuration": {
+
+ "MarkerFilter": { //<1>
+ "marker": "FLOW",
+ "onMatch": "ACCEPT",
+ "onMismatch": "NEUTRAL"
+ },
+
+ "Appenders": {
+ "Console": {
+ "name": "CONSOLE",
+ "PatternLayout": {
+ "MarkerPatternSelector": {
+ "defaultPattern": "%d %5p [%t] %c{1} -- %m%n",//<2>
+ "PatternMatch": [
+ {//<3>
+ "key": "ENTER",
+ "pattern": "%d %5p [%t] %c{1} => %m%n"
+ },
+ {//<4>
+ "key": "EXIT",
+ "pattern": "%d %5p [%t] %c{1} <= %m%n"
+ }
+ ]
+ }
+ }
+ }
+ },
+
+ "Loggers": {
+ "Root": {
+ "level": "WARN",
+ "AppenderRef": [
+ {
+ "ref": "CONSOLE"
+ }
+ ]
+ }
+ }
+
+ }
+}
diff --git
a/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.properties
b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.properties
new file mode 100644
index 0000000000..edecbf818b
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.properties
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+filter.0.type = MarkerFilter #<1>
+filter.0.marker = FLOW
+filter.0.onMatch = ACCEPT
+filter.0.onMismatch = NEUTRAL
+
+appender.0.type = Console
+appender.0.name = CONSOLE
+appender.0.layout.type = PatternLayout
+appender.0.layout.patternSelector.type = MarkerPatternSelector
+appender.0.layout.patternSelector.defaultPattern = "%d %5p [%t] %c{1} -- %m%n
#<2>
+appender.0.layout.patternSelector.properties.0.type = PatternMatch
+appender.0.layout.patternSelector.properties.0.key = ENTER
+appender.0.layout.patternSelector.properties.0.pattern = %d %5p [%t] %c{1} =>
%m%n #<3>
+appender.0.layout.patternSelector.properties.1.type = PatternMatch
+appender.0.layout.patternSelector.properties.1.key = EXIT
+appender.0.layout.patternSelector.properties.1.pattern = %d %5p [%t] %c{1} <=
%m%n #<4>
+
+rootLogger.level = WARN
+rootLogger.appenderRef.0.ref = CONSOLE
diff --git
a/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.xml
b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.xml
new file mode 100644
index 0000000000..9c53bb7dda
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<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">
+
+ <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/><!--1-->
+
+ <Appenders>
+ <Console name="CONSOLE">
+ <PatternLayout>
+ <MarkerPatternSelector defaultPattern="%d %5p [%t] %c{1} --
%m%n"><!--2-->
+ <PatternMatch key="ENTER" pattern="%d %5p [%t] %c{1} =>
%m%n"/><!--3-->
+ <PatternMatch key="EXIT" pattern="%d %5p [%t] %c{1} <=
%m%n"/><!--4-->
+ </MarkerPatternSelector>
+ </PatternLayout>
+ </Console>
+ </Appenders>
+
+ <Loggers>
+ <Root level="WARN">
+ <AppenderRef ref="CONSOLE"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
diff --git
a/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.yaml
b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.yaml
new file mode 100644
index 0000000000..89dea1393a
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/flowtracing/log4j2.yaml
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+Configuration:
+
+ MarkerFilter: #<1>
+ marker: "FLOW"
+ onMatch: "ACCEPT"
+ onMismatch: "NEUTRAL"
+
+ Appenders:
+ Console:
+ name: "CONSOLE"
+ PatternLayout:
+ MarkerPatternSelector:
+ defaultPattern: "%d %5p [%t] %c{1} -- %m%n" #<2>
+ PatternMatch:
+ - key: "ENTER" #<3>
+ pattern: "%d %5p [%t] %c{1} => %m%n"
+ - key: "EXIT" #<4>
+ pattern: "%d %5p [%t] %c{1} <= %m%n"
+
+ Loggers:
+ Root:
+ level: "WARN"
+ AppenderRef:
+ - ref: "CONSOLE"
diff --git
a/src/site/antora/modules/ROOT/examples/manual/flowtracing/logback.xml
b/src/site/antora/modules/ROOT/examples/manual/flowtracing/logback.xml
new file mode 100644
index 0000000000..c14f27370a
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/flowtracing/logback.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<!DOCTYPE configuration>
+<configuration>
+
+ <import class="ch.qos.logback.core.ConsoleAppender"/>
+ <import class="ch.qos.logback.core.filter.EvaluatorFilter"/>
+ <import class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"/>
+ <import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
+ <import class="ch.qos.logback.classic.turbo.MarkerFilter"/>
+
+ <turboFilter class="MarkerFilter"><!--1-->
+ <Marker>FLOW</Marker>
+ <OnMatch>ACCEPT</OnMatch>
+ </turboFilter>
+
+ <appender name="CONSOLE_DEFAULT" class="ConsoleAppender">
+ <filter class="EvaluatorFilter"><!--2-->
+ <evaluator class="OnMarkerEvaluator">
+ <marker>ENTER</marker>
+ <marker>EXIT</marker>
+ </evaluator>
+ <onMismatch>ACCEPT</onMismatch>
+ <onMatch>DENY</onMatch>
+ </filter>
+ <encoder class="PatternLayoutEncoder"><!--3-->
+ <pattern><![CDATA[%d %5p [%t] %c{1} -- %m%n]]></pattern>
+ </encoder>
+ </appender>
+
+ <appender name="CONSOLE_FLOW_ENTER" class="ConsoleAppender">
+ <filter class="EvaluatorFilter"><!--4-->
+ <evaluator class="OnMarkerEvaluator">
+ <marker>ENTER</marker>
+ </evaluator>
+ <onMismatch>DENY</onMismatch>
+ <onMatch>ACCEPT</onMatch>
+ </filter>
+ <encoder class="PatternLayoutEncoder"><!--5-->
+ <pattern><![CDATA[%d %5p [%t] %c{1} => %m%n]]></pattern>
+ </encoder>
+ </appender>
+
+ <appender name="CONSOLE_FLOW_EXIT" class="ConsoleAppender">
+ <filter class="EvaluatorFilter"><!--6-->
+ <evaluator class="OnMarkerEvaluator">
+ <marker>EXIT</marker>
+ </evaluator>
+ <onMismatch>DENY</onMismatch>
+ <onMatch>ACCEPT</onMatch>
+ </filter>
+ <encoder class="PatternLayoutEncoder"><!--7-->
+ <pattern><![CDATA[%d %5p [%t] %c{1} <= %m%n]]></pattern>
+ </encoder>
+ </appender>
+
+ <root level="WARN">
+ <appender-ref ref="CONSOLE_DEFAULT"/>
+ <appender-ref ref="CONSOLE_FLOW_ENTER"/>
+ <appender-ref ref="CONSOLE_FLOW_EXIT"/>
+ </root>
+
+</configuration>
diff --git a/src/site/antora/modules/ROOT/pages/faq.adoc
b/src/site/antora/modules/ROOT/pages/faq.adoc
index f284885fa0..c766fc42f1 100644
--- a/src/site/antora/modules/ROOT/pages/faq.adoc
+++ b/src/site/antora/modules/ROOT/pages/faq.adoc
@@ -174,7 +174,7 @@ In contrast, Log4j API has methods for up to ten unrolled
parameters.
Log4j API lets you log any `CharSequence` or `Object`.
Log4j Core can log any `Object` that implements `CharSequence` or
`org.apache.logging.log4j.util.StringBuilderFormattable` without creating
garbage.
-* The
https://www.slf4j.org/api/org/slf4j/spi/LocationAwareLogger.html#log(org.slf4j.Marker,java.lang.String,int,java.lang.String,java.lang.Object%5B%5D,java.lang.Throwable)[`org.slf4j.spi.LocationAwareLogger::log`]
method is not yet implemented in a garbage-free manner in the
`log4j-slf4j-impl` and `log4j-slf4j2-impl` bridges.
+* The
{slf4j-url}/api/org/slf4j/spi/LocationAwareLogger.html#log(org.slf4j.Marker,java.lang.String,int,java.lang.String,java.lang.Object%5B%5D,java.lang.Throwable)[`org.slf4j.spi.LocationAwareLogger::log`]
method is not yet implemented in a garbage-free manner in the
`log4j-slf4j-impl` and `log4j-slf4j2-impl` bridges.
It creates a new message object for each call.
[#gc-free-domain-object]
diff --git a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc
b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc
index 371095c378..448b392573 100644
--- a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc
@@ -177,8 +177,8 @@ where the event should always be logged regardless of the
configuration.
However, it is generally recommended that a Marker with a corresponding
global Marker Filter be used instead.
-http://logging.apache.org/log4j/1.2/manual.html[Log4j 1.x] and
-http://logback.qos.ch/manual/architecture.html#effectiveLevel[Logback]
+{logging-services-url}/log4j/1.x/manual.html[Log4j 1] and
+{logback-url}/manual/architecture.html#effectiveLevel[Logback]
both have the concept of "Level Inheritance". In Log4j 2, Loggers and
LoggerConfigs are two different objects so this concept is implemented
differently. Each Logger references the appropriate LoggerConfig which
diff --git a/src/site/antora/modules/ROOT/pages/manual/flowtracing.adoc
b/src/site/antora/modules/ROOT/pages/manual/flowtracing.adoc
index 41a41edc9a..c33ee7457f 100644
--- a/src/site/antora/modules/ROOT/pages/manual/flowtracing.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/flowtracing.adoc
@@ -14,111 +14,94 @@
See the License for the specific language governing permissions and
limitations under the License.
////
+
= Flow Tracing
-Flow tracing in Log4j is an advanced logging technique designed to enhance
-the visibility of application processes. With this technique, developers can
track
-data flow through their application using unique methods that log entry
-and exit points within the code.
+xref:manual/api.adoc[Log4j API] provides convenience logging methods to aid
the tracking of the data flow through an application, which is referred to as
*flow tracing*.
+<<impl,Logging implementations>> can choose to <<log-events,generate
specialized log events>> allowing users to handle these messages different from
the rest – see <<example>>.
-These methods are:
+Flow tracing is known to help with the following use cases:
-* `traceEntry()` (Deprecated `entry()`)
-* `traceExit()` (Deprecated: `exit()`)
-* `throwing()`
-* `catching()`
+* Troubleshooting without requiring a debugging session
+* Helping educate new developers in learning the application
-With these methods, we can investigate environments where traditional
debugging is not possible,
-such as in production or during live application monitoring.
-Furthermore, new developers can be educated on the application's behavior by
examining the logs.
+[#usage]
+== Usage
-Flow tracing offers a structured approach to all this.
+link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html[`Logger`]
provides following methods for flow tracing purposes:
-== Flow Tracing Methods
+`traceEntry()`:: Marks the entry to a block
+`traceExit()`:: Marks the exit from a block
+`catching()`:: Reports caught exceptions
+`throwing()`:: Reports exceptions that are either discarded or unlikely to be
handled
-The methods often used are `traceEntry()` and `traceExit()`.
-As the name suggests, the "entry" method is used at the beginning and the
"exit" method at the end of a method.
+The most used `traceEntry()` and `traceExit()` methods are intended to mark
the _entry_ and _exit_ points of a particular block of code:
-[source, java]
+[#example-trace]
+.Example `traceEntry()` and `traceExit()` usage
+[source,java]
----
public void someMethod() {
- logger.traceEntry(); <1>
- // method body
- logger.traceExit(); <2>
-}
-----
-<1> The `entry()` method is called at the beginning of the method.
-<2> The `exit()` method is called at the end of the method.
-
-Developers can call both `traceEntry()` and `traceExit()` methods with or
without parameters.
-In the case of `traceEntry()`, it makes sense to pass the method parameters on
as arguments.
-
-[source, java]
-----
-public void someMethod(String param) {
- logger.traceEntry(param); <1>
+ LOGGER.traceEntry(); //<1>
// method body
- logger.traceExit(); <2>
+ LOGGER.traceExit(); //<2>
}
----
-<1> The `traceEntry()` method is called at the beginning of the method.
-<2> The `traceExit()` method is called at the end of the method.
+<1> `traceEntry()` marks the entry to the block
+<2> `traceExit()` marks the exit from the block
-The `traceEntry()` also supports messages.
+Both `traceEntry()` and `traceExit()` also accept parameters.
+You can use them to track the input and output of the associated block:
-[source, java]
+[#example-trace-args]
+.Example `traceEntry()` and `traceExit()` usage with arguments
+[source,java]
----
-public void someMethod(String[] text) {
- logger.traceEntry(new JsonMessage(text)); <1>
+public String someMethod(String input) {
+ logger.traceEntry(null, input); // <1>
// method body
+ String output = ...;
+ return logger.traceExit(output); // <2>
}
----
-<1> Using the `JsonMessage` class to log the `text` parameter.
+<1> `traceEntry()` marks the entry to the block along with the input
+<2> `traceExit()` marks the exit from the block along with the output
-Very similar, it is possible to use `traceExit()` with methods that return a
value.
+The `catching()` method can be used by an application when it catches an
exception that it will not rethrow, either explicitly or attached to another
exception:
-[source, java]
+[#example-catching]
+.Example `catching()` usage
+[source,java]
----
-public String someMethod() {
- String result = "Hello";
- // method body
- return logger.traceExit(result); <1>
+public void someMethod() {
+ try {
+ // Business logic
+ } catch (Exception error) {
+ logger.catching(error); // <1>
+ }
}
----
-<1> The `traceExit()` method can also return a value.
-
-Developers can use the `catching()` and `throwing()` methods to work with
exceptions.
-
-The following code shows the `catching()` method. It will be called
-inside the `catch` block of a try-catch statement.
+<1> `catching()` reports the caught exception
-The `catching()` method can be used by an application when it catches an
-Exception that it will not rethrow, either explicitly or attached
-to another Exception. The generated logging event will have an `ERROR` level.
+The `throwing()` method can be used by an application when it is throwing an
exception that is unlikely to be handled, such as a `RuntimeException`.
+This will ensure that proper diagnostics are available if needed.
-[source, java]
+[#example-throwing]
+.Example `throwing()` usage
+[source,java]
----
public void someMethod() {
try {
- // Let's assume an exception is thrown here
- String msg = messages[messages.length];
- } catch (Exception ex) {
- logger.catching(ex); <1>
+ // Business logic
+ } catch (RuntimeException error) {
+ throw logger.throwing(error); // <1>
}
}
----
-<1> The `catching()` method logs exceptions that are caught and not rethrown.
-
-The `throwing()` method is used to log exceptions that are thrown and not
caught.
-The code shows how to use the `throwing()` method- like `catching()`, which
will be called
-inside the `catch` block of a try-catch statement.
-
-The `throwing()` method can be used by an application when it is throwing
-an exception that is unlikely to be handled, such as a RuntimeException.
-This will ensure that proper diagnostics are available if needed.
-The generated logging event will have an `ERROR` level.
+<1> `thrown()` reports the caught exception that is about to be rethrown
+<2> Rethrowing the exception, contrary to <<example-catching,the `catching()`
example>> suppressing the exception
-[source, java]
+[source,java]
----
public void someMethod() {
try {
@@ -131,83 +114,145 @@ public void someMethod() {
----
<1> The `throwing()` method logs exceptions that are thrown and not caught.
-== Differences in flow tracing methods
+[#aop]
+=== Aspect-oriented programming
+
+Logging has been a notorious example for demonstrating
https://en.wikipedia.org/wiki/Aspect-oriented_programming[aspect-oriented
programming] (AOP).
+For instance, using AOP, you can inject logging statements to methods that
match a particular footprint, e.g., all public methods in `com.mycompany`
package.
+With a couple of lines of AOP instructions, you can log input and output of
all matching functions.
+Flow tracing methods fits like a glove to this AOP use case.
+You can see a demonstration of this in
https://github.com/apache/logging-log4j-samples/tree/main/log4j-samples-aspectj[the
`log4j-samples-aspectj` project] demonstrating how you can implement this use
case using Log4j API flow methods and Spring Boot AspectJ support.
+
+[#impl]
+== Implementation
-Flow tracing methods have specific markers assigned and logs with a level of
`TRACE`.
-It's also noteworthy that all messages begin with "event".
+This section explains how flow tracing is implemented by different logging
implementations.
-The table below shows the methods and their unique features.
+[#impl-log4j]
+=== Log4j Core
-[cols="3,3,3", options="header"]
+Log4j Core, the reference implementation of Log4j API, implements the flow
tracing methods such that
+
+* <<impl-log4j-log-events,It generates specialized log events>>
+* <<impl-log4j-config,Its behaviour is configurable>>
+
+[#impl-log4j-log-events]
+==== Log events
+
+Log4j Core implements the flow tracing methods such that the generated log
events are decorated to accommodate any need to selectively handle them:
+
+[%header,cols="2m,1m,2,3"]
+|===
+|Method
+|Level
+|Markers
+|Message
+
+|traceEntry()
+|TRACE
+|`ENTER`, `FLOW`
+|link:../javadoc/log4j-api/org/apache/logging/log4j/message/EntryMessage.html[`EntryMessage`]
extending from
link:../javadoc/log4j-api/org/apache/logging/log4j/message/FlowMessage.html[`FlowMessage`]
+
+|traceExit()
+|TRACE
+|`EXIT`, `FLOW`
+|link:../javadoc/log4j-api/org/apache/logging/log4j/message/EntryMessage.html[`ExitMessage`]
extending from
link:../javadoc/log4j-api/org/apache/logging/log4j/message/FlowMessage.html[`FlowMessage`]
+
+| throwing()
+|ERROR
+|`THROWING`, `EXCEPTION`
+|Plain message
+
+| catching()
+|ERROR
+|`CATCHING`, `EXCEPTION`
+|Plain message
|===
-| Method Name | Marker Name | Special Features
-| `traceEntry()`
-| `ENTER`, `FLOW`
-| Can take a format string and a variable list of parameters.
+[#impl-log4j-config]
+==== Configuration
-| `entry()`
-| `ENTER`, `FLOW`
-| DEPRECATED. Accepts 0 to 4 parameters
+Flow tracing implementation of Log4j Core can be configured using the
following system properties:
-| `traceExit()`
-| `EXIT`, `FLOW`
-| Handles return values differently based on the method signature.
+include::partial$manual/systemproperties/properties-log4j-core-misc.adoc[leveloffset=+3,tag=flow-tracing]
-| `exit()`
-| `EXIT`, `FLOW`
-| DEPRECATED. Can be called with or without parameters.
+[#impl-logback]
+=== Logback
-| `throwing()`
-| `THROWING`, `EXCEPTION`
-| Typically used when an application throws an exception that is unlikely to
be handled, such as a RuntimeException.
+{logback-url}[Logback] is another logging implementation for the
{slf4j-url}[SLF4J] logging API, just like Log4j Core is a logging
implementation for the xref:manual/api.adoc[Log4j API].
+Using Log4j-to-SLF4J bridge, Logback can be
xref:manual/installation.adoc#impl-logback[configured to consume Log4j API].
-| `catching()`
-| `CATCHING`, `EXCEPTION`
-| Used when catching exceptions that are not rethrown; logs with ERROR level.
+Log4j-to-SLF4J bridge implements flow tracing methods such that log events are
generated with same <<impl-log4j-log-events,marker and level changes of Log4j
Core>>.
+They only differ in generated message types, since SLF4J has no
xref:manual/messages.adoc[extensible message contract] like Log4j, but plain
``String``-based messages.
+This effectively means Logback also has access to the stated marker and level
changes while using Log4j API flow tracing methods.
-|===
+[#example]
+== Example configuration
-== Flow Tracing Example Configuration
+In this section, we will share logging implementation configuration examples
to filter on flow tracing log events.
-The following example demonstrates how to configure Log4j to use flow tracing.
-Note: While developers should prefer the `JsonTemplateLayout` in production,
this example uses `PatternLayout` for simplicity.
+[#example-log4j]
+=== Log4j Core
-Two appenders are defined: `Console` and `File`.
+Log4j Core is the reference implementation of Log4j API.
+In the example configurations below, we will employ a
xref:manual/pattern-layout.adoc[] depending on the associated markers of the
log event:
-The `Console` appender outputs logs to `SYSTEM_OUT`, typically the console.
-It includes a `ThresholdFilter` set to only accept messages at the `ERROR`
level or above.
-Less severe messages are filtered.
+[tabs]
+====
+XML::
++
+.{antora-examples-url}manual/flowtracing/log4j2.xml[log4j2.xml] snippet
+[source,xml]
+----
+include::example$manual/flowtracing/log4j2.xml[lines=24..35,indent=0]
+----
-Similarly, the File appender directs logs to a file named `target/test.log`.
-The appenders configuration will create a new file for every application run.
+JSON::
++
+.{antora-examples-url}manual/flowtracing/log4j2.json[log4j2.json] snippet
+[source,json]
+----
+include::example$manual/flowtracing/log4j2.json[lines=4..29,indent=0]
+----
-Both appenders use the already mentioned `PatternLayout`, which includes
detailed information such as time, log level, class name, line number, and
method name.
+YAML::
++
+.{antora-examples-url}manual/flowtracing/log4j2.yaml[log4j2.yaml] snippet
+[source,yaml]
+----
+include::example$manual/flowtracing/log4j2.yaml[lines=19..34,indent=0]
+----
-Finally, in the Loggers section, the Root logger is set to a `TRACE` level,
which is necessary to see flow tracing in action.
-The Root logger references the File appender, directing its output to the
configured file.
+Properties::
++
+.{antora-examples-url}manual/flowtracing/log4j2.properties[log4j2.properties]
snippet
+[source,properties]
+----
+include::example$manual/flowtracing/log4j2.properties[lines=18..33,indent=0]
+----
+====
+<1> Accepting log events marked with `FLOW` regardless of their level
+<2> By default, log event messages will be formatted with a `--` prefix
+<3> Log events marked with `ENTER` (that is, generated by `traceEntry()`) will
have their message formatted with a `=>` prefix
+<4> Log events marked with `EXIT` (that is, generated by `traceExit()`) will
have their message formatted with a `<=` prefix
+[#example-logback]
+=== Logback
+
+{logback-url}[Logback] is another logging implementation for the
{slf4j-url}[SLF4J] logging API, just like Log4j Core is a logging
implementation for the xref:manual/api.adoc[Log4j API].
+Using Log4j-to-SLF4J bridge, Logback can be
xref:manual/installation.adoc#impl-logback[configured to consume Log4j API].
+
+Below we will use a combination of `EvaluatorFilter`, `MarkerFilter`, and
`OnMarkerEvaluator` in Logback to adapt the formatting pattern of messages
written to console based on flow tracing specific markers:
+
+.{antora-examples-url}manual/flowtracing/logback.xml[logback.xml] snippet
[source,xml]
----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration>
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
- <!-- Flow tracing is most useful with a pattern that shows location.
- Below pattern outputs class, line number and method name. -->
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M -
%msg%xEx%n"/>
- </Console>
- <File name="log" fileName="target/test.log" append="false">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M -
%msg%xEx%n"/>
- </File>
- </Appenders>
- <Loggers>
- <Root level="trace">
- <AppenderRef ref="log"/>
- </Root>
- </Loggers>
-</Configuration>
-----
-
-By changing the Root logger's level to `DEBUG`, developers can reduce the
amount of output.
+include::example$manual/flowtracing/logback.xml[lines=27..76,indent=0]
+----
+<1> Accepting log events marked with `FLOW` regardless of their level
+<2> In `CONSOLE_DEFAULT` appender, excluding all log events marked with
`ENTER` and `EXIT`
+<3> In `CONSOLE_DEFAULT` appender, log event messages will be formatted with a
`-` prefix
+<4> In `CONSOLE_FLOW_ENTER` appender, accepting only log events marked with
`ENTER`
+<5> In `CONSOLE_FLOW_ENTER` appender, log event messages will be formatted
with a `→` prefix
+<6> In `CONSOLE_FLOW_EXIT` appender, accepting only log events marked with
`EXIT`
+<7> In `CONSOLE_FLOW_EXIT` appender, log event messages will be formatted with
a `←` prefix
diff --git a/src/site/antora/modules/ROOT/pages/manual/getting-started.adoc
b/src/site/antora/modules/ROOT/pages/manual/getting-started.adoc
index 4ed2d22f93..d2d62c1220 100644
--- a/src/site/antora/modules/ROOT/pages/manual/getting-started.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/getting-started.adoc
@@ -218,7 +218,7 @@ dependencies {
If your application has (direct or transitive!) dependencies that use another
logging API, you need to <<logging-bridge,bridge>> that to Log4j.
This way the foreign logging API calls will effectively be consumed by Log4j
too.
-{slf4j-link} is another logging API used pretty common in the wild.
+{slf4j-url}[SLF4J] is another logging API used pretty common in the wild.
(xref:manual/installation.adoc[] covers all supported foreign APIs.)
Let's see how you can use the `log4j-slf4j2-impl` bridge to support SLF4J:
@@ -374,7 +374,7 @@ dependencies {
If your library has (direct or transitive!) dependencies that use another
logging API, you need to <<logging-bridge,bridge>> that to Log4j.
This way the foreign logging API calls will effectively be consumed by Log4j
too.
-{slf4j-link} is another logging API used pretty common in the wild.
+{slf4j-url}[SLF4J] is another logging API used pretty common in the wild.
(xref:manual/installation.adoc[] covers all supported foreign APIs.)
Let's see how you can use the `log4j-slf4j2-impl` bridge to support SLF4J:
diff --git a/src/site/antora/modules/ROOT/pages/manual/installation.adoc
b/src/site/antora/modules/ROOT/pages/manual/installation.adoc
index e3f27b9175..916ac2428c 100644
--- a/src/site/antora/modules/ROOT/pages/manual/installation.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/installation.adoc
@@ -17,7 +17,6 @@
:jpl-link: https://openjdk.org/jeps/264[JPL (Java Platform Logging)]
:jul-link:
https://docs.oracle.com/en/java/javase/{java-target-version}/core/java-logging-overview.html[JUL
(Java Logging)]
-:slf4j-link: https://www.slf4j.org/[SLF4J]
= Installation
@@ -186,9 +185,9 @@ The bridge that translates Log4j API calls to {jul-link}.
See <<impl-jul>> for the installation instructions.
`log4j-to-slf4j`::
-The bridge that translates Log4j API calls to {slf4j-link}.
+The bridge that translates Log4j API calls to {slf4j-url}[SLF4J].
Since currently only
-https://logback.qos.ch/[Logback] implements SLF4J natively, refer to
<<impl-logback>> for the installation instructions.
+{logback-url}[Logback] implements SLF4J natively, refer to <<impl-logback>>
for the installation instructions.
[IMPORTANT]
====
@@ -275,7 +274,7 @@ The following sections explain the installation of
Log4j-provided bridges.
[#impl-core-bridge-slf4j]
===== Installing SLF4J-to-Log4j bridge
-You can translate {slf4j-link} calls to Log4j API using the
`log4j-slf4j2-impl` artifact:
+You can translate {slf4j-url}[SLF4J] calls to Log4j API using the
`log4j-slf4j2-impl` artifact:
[tabs]
====
@@ -604,7 +603,7 @@ To configure JUL, see
https://docs.oracle.com/en/java/javase/{java-target-versio
[#impl-logback]
=== Installing Logback
-To install https://logback.qos.ch/[Logback] as the logging implementation, you
only need to add a Log4j-to-SLF4J bridge:
+To install {logback-url}[Logback] as the logging implementation, you only need
to add a Log4j-to-SLF4J bridge:
[tabs]
====
@@ -643,4 +642,4 @@ runtimeOnly 'org.apache.logging.log4j:log4j-to-slf4j' //
Log4j-to-SLF4J bridge
====
-To configure Logback, see
https://logback.qos.ch/manual/configuration.html[Logback's configuration
documentation].
+To configure Logback, see {logback-url}/manual/configuration.html[Logback's
configuration documentation].
diff --git a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
index fac5648b2a..e8a43cb32c 100644
--- a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
@@ -732,14 +732,10 @@ The `style` parameter is a comma-separated list of the
following directives:
See <<ansi-modifiers>> for the syntax of `<style_expression>`.
| STYLE=default
-| Sets the default style, which is equivalent to the following sequence of
directives:
-`FATAL=bold red, ERROR=bold red, WARN=yellow, INFO=green, DEBUG=cyan,
TRACE=black`.
+| Sets the default style, which is equivalent to the following sequence of
directives: `FATAL=bold red, ERROR=bold red, WARN=yellow, INFO=green,
DEBUG=cyan, TRACE=black`.
| STYLE=logback
-| Applies the style used by
-https://logback.qos.ch/manual/layouts.html#coloring[Logback's `%highlight`
converter],
-which is equivalent to the following sequence of directives:
-`FATAL=blink bold red, ERROR=bold red, WARN=red, INFO=blue, DEBUG=normal,
TRACE=normal`.
+| Applies the style used by
{logback-url}/manual/layouts.html#coloring[Logback's `%highlight` converter],
which is equivalent to the following sequence of directives: `FATAL=blink bold
red, ERROR=bold red, WARN=red, INFO=blue, DEBUG=normal, TRACE=normal`.
|===
You can use the default colors with:
diff --git a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
index 822d343bfe..3c1618673c 100644
--- a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
@@ -179,7 +179,7 @@ The behavior of the `ThreadContext` class can be fine-tuned
using the following
====
These configuration properties are only used by the Log4j Core and
xref:manual/simple-logger.adoc[] implementations of Log4j API.
-The `log4j-to-slf4j` logging bridge delegates `ThreadContext` calls to the
SLF4J https://slf4j.org/api/org/slf4j/MDC.html[MDC] class.
+The `log4j-to-slf4j` logging bridge delegates `ThreadContext` calls to
{slf4j-url}/api/org/slf4j/MDC.html[the SLF4J `MDC` class].
The `log4j-to-jul` logging bridge ignores all `ThreadContext` method calls.
====
diff --git a/src/site/antora/modules/ROOT/pages/migrate-from-logback.adoc
b/src/site/antora/modules/ROOT/pages/migrate-from-logback.adoc
index a9662347d9..9d2ac5cd24 100644
--- a/src/site/antora/modules/ROOT/pages/migrate-from-logback.adoc
+++ b/src/site/antora/modules/ROOT/pages/migrate-from-logback.adoc
@@ -15,12 +15,9 @@ Licensed to the Apache Software Foundation (ASF) under one
or more
limitations under the License.
////
-:logback-link: https://logback.qos.ch/[Logback]
-:slf4j-link: https://www.slf4j.org/[SLF4J]
-
= Migrating from Logback
-{logback-link} is a logging implementation for the {slf4j-link} logging API,
just like Log4j Core is a logging implementation for the
xref:manual/api.adoc[Log4j API].
+{logback-url}[Logback] is a logging implementation for the {slf4j-url}[SLF4J]
logging API, just like Log4j Core is a logging implementation for the
xref:manual/api.adoc[Log4j API].
In this page we will guide you through migrating from Logback to Log4j Core as
your logging implementation.
[TIP]
diff --git a/src/site/antora/modules/ROOT/pages/migrate-from-slf4j.adoc
b/src/site/antora/modules/ROOT/pages/migrate-from-slf4j.adoc
index ab0f9e0572..2f389f6787 100644
--- a/src/site/antora/modules/ROOT/pages/migrate-from-slf4j.adoc
+++ b/src/site/antora/modules/ROOT/pages/migrate-from-slf4j.adoc
@@ -15,13 +15,9 @@ Licensed to the Apache Software Foundation (ASF) under one
or more
limitations under the License.
////
-:logback-link: https://logback.qos.ch/[Logback]
-:slf4j-link: https://www.slf4j.org/[SLF4J]
-:slf4j-javadoc-url: https://www.slf4j.org/api
-
= Migrating from SLF4J
-{slf4j-link} is a logging API whose reference implementation is
{logback-link}, just like xref:manual/api.adoc[Log4j API] is a logging API
whose reference implementation is Log4j Core.
+{slf4j-url}[SLF4J] is a logging API whose reference implementation is
{logback-url}[Logback], just like xref:manual/api.adoc[Log4j API] is a logging
API whose reference implementation is Log4j Core.
In this page we will guide you through migrating from SLF4J to Log4j API as
your logging API.
[TIP]
@@ -56,15 +52,15 @@ This you can use to
. or run OpenRewrite to automatically migrate the code.
====
+
-{slf4j-javadoc-url}/org/slf4j/LoggerFactory.html[`org.slf4j.LoggerFactory`]::
+{slf4j-url}/api/org/slf4j/LoggerFactory.html[`org.slf4j.LoggerFactory`]::
Replace its usages with
link:javadoc/log4j-api/org/apache/logging/log4j/LogManager.html[`org.apache.logging.log4j.LogManager`].
Note that `LogManager.getLogger(Foo.class)` can be simplified as
`LogManager.getLogger()`, if `Foo` is the enclosing class of the field.
+
-{slf4j-javadoc-url}/org/slf4j/Logger.html[`org.slf4j.Logger`]::
+{slf4j-url}/api/org/slf4j/Logger.html[`org.slf4j.Logger`]::
Replace its usages with
link:javadoc/log4j-api/org/apache/logging/log4j/Logger.html[`org.apache.logging.log4j.Logger`].
Since SLF4J's `Logger` is almost a parent of Log4j's `Logger`, most methods
should work without any changes.
+
-{slf4j-javadoc-url}/org/slf4j/MDC.html[`org.slf4j.MDC`]::
+{slf4j-url}/api/org/slf4j/MDC.html[`org.slf4j.MDC`]::
Replace its usages with
link:javadoc/log4j-api/org/apache/logging/log4j/ThreadContext.html[`org.apache.logging.log4j.ThreadContext`].
. If you use https://projectlombok.org/features/log[`@Slf4j` from Lombok], you
need to replace them with `@Log4j2` instead.
diff --git a/src/site/antora/modules/ROOT/partials/concepts.adoc
b/src/site/antora/modules/ROOT/partials/concepts.adoc
index 883b2e5f21..04ef812bab 100644
--- a/src/site/antora/modules/ROOT/partials/concepts.adoc
+++ b/src/site/antora/modules/ROOT/partials/concepts.adoc
@@ -25,8 +25,6 @@
:jcl-link: https://commons.apache.org/proper/commons-logging/[JCL (Apache
Commons Logging)]
:jpl-link: https://openjdk.org/jeps/264[JPL (Java Platform Logging)]
:jul-link:
https://docs.oracle.com/en/java/javase/{java-target-version}/core/java-logging-overview.html[JUL
(Java Logging)]
-:logback-link: https://logback.qos.ch/[Logback]
-:slf4j-link: https://www.slf4j.org/[SLF4J]
:jboss-logging-link: https://github.com/jboss-logging/jboss-logging[JBoss
Logging]
// end::inc[]
@@ -38,7 +36,7 @@ Logging API::
A logging API is an interface your code or your dependencies directly logs
against.
It is required at compile-time.
It is implementation agnostic to ensure that your application can write logs,
but is not tied to a specific logging implementation.
-Log4j API, {slf4j-link}, {jul-link}, {jcl-link}, {jpl-link} and
{jboss-logging-link} are major logging APIs.
+Log4j API, {slf4j-url}[SLF4J], {jul-link}, {jcl-link}, {jpl-link} and
{jboss-logging-link} are major logging APIs.
// end::api[]
@@ -47,7 +45,7 @@ Log4j API, {slf4j-link}, {jul-link}, {jcl-link}, {jpl-link}
and {jboss-logging-l
[#logging-impl]
Logging implementation::
A logging implementation is only required at runtime and can be changed
without the need to recompile your software.
-Log4j Core, {jul-link}, {logback-link} are the most well-known logging
implementations.
+Log4j Core, {jul-link}, {logback-url}[Logback] are the most well-known logging
implementations.
// end::impl[]
diff --git
a/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-core-misc.adoc
b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-core-misc.adoc
index d23e19f378..8ac34f1101 100644
---
a/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-core-misc.adoc
+++
b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-core-misc.adoc
@@ -230,6 +230,7 @@ Fully qualified class name of a
link:../javadoc/log4j-api/org/apache/logging/log4j/message/MessageFactory.html[`MessageFactory`]
implementation that will be used by loggers if no explicit factory was
specified.
+// tag::flow-tracing[]
[id=log4j2.flowMessageFactory]
== `log4j2.flowMessageFactory`
@@ -248,6 +249,7 @@ implementation that will be used by loggers if no explicit
factory was specified
Fully qualified class name of a
link:../javadoc/log4j-api/org/apache/logging/log4j/message/FlowMessageFactory.html[`FlowMessageFactory`]
implementation to be used by all loggers.
+// end::flow-tracing[]
[id=log4j2.loggerContextStacktraceOnStart]
== `log4j2.loggerContextStacktraceOnStart`