Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/site/antora/modules/ROOT/pages/manual/architecture.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,17 @@ Appender -[#green,thickness=6]-> AbstractManager
@enduml
....

At a really high level,
At a high level,

* A <<LoggerContext>>, the composition anchor, gets created in combination with a <<Configuration>>.
Both can be created either directly (i.e., programmatically) or indirectly at first interaction with Log4j.
Both can be created directly (i.e., programmatically) or indirectly at first interaction with Log4j.
* `LoggerContext` creates <<Logger>>s that users interact with for logging purposes.
* <<Appender>> delivers a link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[`LogEvent`] to a target (file, socket, database, etc.) and typically uses a <<Layout>> to encode log events and an <<AbstractManager>> to handle the lifecycle of the target resource.
* <<LoggerConfig>> encapsulates configuration for a `Logger`, as `AppenderControl` and `AppenderRef` for ``Appender``s.
* <<LoggerConfig>> encapsulates configuration for a `Logger,` as `AppenderControl` and `AppenderRef` for ``Appender``s.
* <<Configuration>> is equipped with <<StrSubstitutor>> to allow property substitution in `String`-typed values.
* A typical `log()` call triggers a chain of invocations through classes `Logger`, `LoggerConfig`, `AppenderControl`, `Appender`, and `AbstractManager` in order – this is depicted using green arrows in xref:architecture-diagram[xrefstyle=short].

Following sections examine this interplay in detail.
The following sections examine this interplay in detail.

[#LoggerContext]
== `LoggerContext`
Expand Down
54 changes: 27 additions & 27 deletions src/site/antora/modules/ROOT/pages/manual/async.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
////
= Asynchronous loggers

Asynchronous logging is a technique to improve application logging performance by executing all I/O operations in a separate thread.
Asynchronous logging is a technique that improves application logging performance by executing all I/O operations in a separate thread.

Log4j offers out-of-the-box two different asynchronous logging solutions:

Asynchronous appender::
A classical queue-based asynchronous appender, which is available since Log4j 1.
An asynchronous appender is a classical queue-based asynchronous appender which is available since Log4j 1.
+
See xref:manual/appenders/delegating.adoc#AsyncAppender[Asynchronous appender] for more details.

Asynchronous loggers::
Asynchronous loggers are a new feature available since Log4j 2.
Asynchronous loggers have been a new feature since Log4j 2.
They are based on
{lmax-disruptor-url}[LMAX Disruptor],
a lock-free inter-thread communication library, instead of queues, resulting in higher throughput and lower latency.
Expand All @@ -35,9 +35,9 @@ The rest of this chapter is dedicated to this new component.

[WARNING]
====
Logging performance depends greatly on the architecture of your application and the way you use logging.
The solutions offered by this chapter should be evaluated using benchmarks against your own application.
If benchmarks and profiling don't show a statistically significant difference between asynchronous and synchronous logging solutions, the latter one is recommended, since it is the simplest one.
Logging performance depends significantly on the architecture of your application and the way you use logging.
The solutions offered by this chapter should be evaluated using benchmarks against your application.
If benchmarks and profiling don't show a statistically significant difference between asynchronous and synchronous logging solutions, the latter is recommended since it is the simplest.
====

include::partial$manual/async-trade-offs.adoc[leveloffset=+1]
Expand All @@ -58,7 +58,7 @@ You can:
** <<AllAsync>>, which gives a better performance,
** <<MixedSync-Async>>, which gives more flexibility.

Under the hood these methods use different Log4j plugins, but also share a
Under the hood, these methods use different Log4j plugins but also share a
<<common-configuration-properties,set of common configuration properties>>.

[#AllAsync]
Expand All @@ -76,10 +76,10 @@ This will create a different logger context and disruptor for each classloader i

[IMPORTANT]
====
When using an asynchronous logger context you should use only `Root` and `Logger` elements (cf.
When using an asynchronous logger context, you should only use the `Root` and `Logger` elements (cf.
xref:manual/configuration.adoc#configuring-loggers[Logger configuration]).

If you use `AsyncRoot` and `AsyncLogger` configuration elements, two asynchronous barriers will be created instead of one, which will impair performance.
If you use `AsyncRoot` and `AsyncLogger` configuration elements, two asynchronous barriers will be created instead of one, impairing performance.
====

[#SysPropsAllAsync]
Expand All @@ -91,11 +91,11 @@ Beyond the <<common-configuration-properties,common configuration properties>>,

include::partial$manual/systemproperties/properties-async-logger.adoc[leveloffset=+2]

* the generic behavior of asynchronous components, such as the queue full policy and message formatting.
+
See xref:manual/systemproperties.adoc#properties-async[common asynchronous logging configurations] for more details.
* The generic behavior of asynchronous components, such as the queue full policy and message formatting.
+
For more details, see xref:manual/systemproperties.adoc#properties-async[common asynchronous logging configurations].

* the parameters of the disruptor, such as the size of the ring buffer and the wait strategy to use.
* The parameters of the disruptor, such as the size of the ring buffer and the wait strategy to use.
+
See xref:manual/systemproperties.adoc#properties-async-logger[asynchronous logger configuration] for more details.

Expand All @@ -111,11 +111,11 @@ See xref:manual/systemproperties.adoc#property-sources[Property Sources] for mor
=== Mixing synchronous and asynchronous loggers

Synchronous and asynchronous loggers can be combined in a single configuration.
This gives you more flexibility at the cost of a slight loss in performance (compared to making all loggers asynchronous).
This gives you more flexibility at the cost of a slight performance loss (compared to making all loggers asynchronous).

In order to use this configuration, you need to keep the
To use this configuration, you need to keep the
xref:manual/systemproperties.adoc#log4j2.contextSelector[`log4j2.contextSelector`] at its default value and use one of the
`AsyncRoot` and `AsyncLogger` configuration elements to designate the loggers that you want to be asynchronous.
`AsyncRoot` and `AsyncLogger` configuration elements designate the loggers you want to be asynchronous.

A configuration that mixes asynchronous loggers might look like:

Expand Down Expand Up @@ -154,14 +154,14 @@ include::example$manual/async/mixed-async.properties[lines=28..-1]
----
====
<1> All the appenders referenced by `Root` and `Logger` are called synchronously.
This is especially important for audit logging, since exceptions can be forwarded to the caller.
This is especially important for audit logging since exceptions can be forwarded to the caller.
<2> All the appenders references by `AsyncRoot` and `AsyncLogger` are called asynchronously.
These log statements will cause a smaller latency for the caller.

[[SysPropsMixedSync-Async]]
=== Tuning a mixed synchronous/asynchronous configuration

Since all `AsyncRoot` and `AsyncLogger` components share the same Disruptor instance, its configuration is available through configuration properties.
Since all `AsyncRoot` and `AsyncLogger` components share the same Disruptor instance, their configuration is available through configuration properties.

Beyond the <<common-configuration-properties,common configuration properties>>, the following additional elements are configurable:

Expand All @@ -177,7 +177,7 @@ See xref:manual/systemproperties.adoc#property-sources[Property Sources] for mor
[#common-configuration-properties]
=== Common configuration properties

Regardless of the way you configure asynchronous loggers in Log4j, you can use the following properties to further tune your installation:
Regardless of the way you configure asynchronous loggers in Log4j, you can use the following properties to tune your installation further:

include::partial$manual/systemproperties/properties-async.adoc[leveloffset=+2]

Expand All @@ -186,7 +186,7 @@ include::partial$manual/systemproperties/properties-async.adoc[leveloffset=+2]

The system properties mentioned in the section above allow only to choose from among a fixed set of wait strategies.

In order to use a custom wait strategy you need to:
To use a custom wait strategy, you need to:

. Use the <<MixedSync-Async,mixed sync/async configuration method>> above,
. Implement the interface link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactory.html[`AsyncWaitStrategyFactory`]; the implementation must have a public no-arg constructor,
Expand Down Expand Up @@ -232,21 +232,21 @@ include::example$manual/async/custom-wait-strategy.properties[lines=17..-1]
== Location information

xref:manual/layouts.adoc#LocationInformation[Computing the location information (i.e., the caller class, method, file, and line number) of a log event is an expensive operation.]
The impact on asynchronous loggers and appenders is even higher, since the component must decide whether to compute it or not **before** crossing the asynchronous barrier.
Hence, the location information is disabled by default for asynchronous loggers and appenders.
In order to enable it for a certain logger, set its xref:manual/configuration.adoc#logger-attributes-includeLocation[`includeLocation`] attribute to `true`.
The impact on asynchronous loggers and appenders is even higher since the component must decide whether to compute it or not **before** crossing the asynchronous barrier.
Location information is turned off by default for asynchronous loggers and appenders.
To enable it for a certain logger, set its xref:manual/configuration.adoc#logger-attributes-includeLocation[`includeLocation`] attribute to `true`.

[id=exception-handler]
== Exception handler

In order to handle exceptions that occur on the asynchronous thread, you can configure a custom
To handle exceptions that occur on the asynchronous thread, you can configure a custom
https://lmax-exchange.github.io/disruptor/javadoc/com.lmax.disruptor/com/lmax/disruptor/ExceptionHandler.html[`ExceptionHandler<T>`].

The exact type of handler depends on the configuration mode:

Full asynchronous::
+
If all the loggers are asynchronous you need to:
If all the loggers are asynchronous, you need to:
+
* implement an link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/RingBufferLogEvent.html[`ExceptionHandler<? super RingBufferLogEvent>`]
* set its fully qualified class name as value of the
Expand All @@ -255,10 +255,10 @@ configuration property.

Mixed synchronous/asynchronous::
+
If you use a mix of synchronous and asynchronous loggers you need to:
If you use a mix of synchronous and asynchronous loggers, you need to:
+
* implement a
link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncLoggerConfigDisruptor.Log4jEventWrapper.html[`ExceptionHandler<? super AsyncLoggerConfigDisruptor.Log4jEventWrapper>`]
* set its fully qualified class name as value of the
* set its fully qualified class name as the value of the
xref:manual/systemproperties.adoc#log4j2.asyncLoggerConfigExceptionHandler[`log4j2.asyncLoggerConfigExceptionHandler`]
configuration property.
Loading