Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x] Revamp the performance-related website content #2576

Merged
merged 20 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 17 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
1 change: 1 addition & 0 deletions src/site/antora/antora.tmpl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ asciidoc:
java-target-version: "${maven.compiler.target}"
java-compiler-version: "${minimalJavaBuildVersion}"
logging-services-url: "https://logging.apache.org"
lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor"
# Dependency versions
commons-logging-version: "${site-commons-logging.version}"
jackson-version: "${site-jackson.version}"
Expand Down
1 change: 1 addition & 0 deletions src/site/antora/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ asciidoc:
java-target-version: "8"
java-compiler-version: "[17,18)"
logging-services-url: "https://logging.apache.org"
lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor"
# Dependency versions
commons-logging-version: "1.2.3-commons-logging"
jackson-version: "1.2.3-jackson"
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
13 changes: 10 additions & 3 deletions src/site/antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,21 @@
** xref:manual/systemproperties.adoc[]
* xref:manual/usage.adoc[]
* xref:manual/cloud.adoc[]
* xref:manual/async.adoc[]
* xref:manual/garbagefree.adoc[]
* xref:manual/lookups.adoc[]
* xref:manual/appenders.adoc[]
* xref:manual/layouts.adoc[]
** xref:manual/json-template-layout.adoc[]
* xref:manual/filters.adoc[]
* xref:manual/extending.adoc[]
** xref::manual/customconfig.adoc[]
** xref:manual/customconfig.adoc[]
* xref:manual/plugins.adoc[]
* xref:manual/customconfig.adoc[]
* xref:manual/customloglevels.adoc[]
* xref:manual/jmx.adoc[]
* xref:manual/logsep.adoc[]
* xref:manual/performance.adoc[]
** xref:manual/async.adoc[]
** xref:manual/garbagefree.adoc[]
vy marked this conversation as resolved.
Show resolved Hide resolved

.References
* xref:plugin-reference.adoc[Plugin reference]
Expand Down
82 changes: 7 additions & 75 deletions src/site/antora/modules/ROOT/pages/manual/async.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
See the License for the specific language governing permissions and
limitations under the License.
////
= Lock-free Asynchronous Loggers for Low-Latency Logging
= Asynchronous loggers

Asynchronous logging can improve your application's performance by
executing the I/O operations in a separate thread.
executing the I/O operations in a separate thread.
Log4j 2 makes several improvements in this area.

* *Asynchronous Loggers* are a new addition in Log4j 2. They aim to
Expand All @@ -39,75 +39,7 @@ touch the disk on every log event. (Async Appenders use
ArrayBlockingQueue internally and do not need the disruptor jar on the
classpath.)

[#Trade-offs]
== Trade-offs

Although asynchronous logging can give significant performance benefits,
there are situations where you may want to choose synchronous logging.
This section describes some of the trade-offs of asynchronous logging.

=== Benefits

* Higher peak link:#Performance[throughput]. With an asynchronous logger
your application can log messages at 6 - 68 times the rate of a
synchronous logger.
+
This is especially interesting for applications that occasionally need
to log bursts of messages. Async logging can help prevent or dampen
latency spikes by shortening the wait time until the next message can be
logged. If the queue size is configured large enough to handle the
burst, asynchronous logging will help prevent your application from
falling behind (as much) during a sudden increase in activity.
* Lower logging response time link:#Latency[latency]. Response time
latency is the time it takes for a call to Logger.log to return under a
given workload. Asynchronous Loggers have consistently lower latency
than synchronous loggers or even queue-based asynchronous appenders.

=== Drawbacks

* Error handling. If a problem happens during the logging process and an
exception is thrown, it is less easy for an asynchronous logger or
appender to signal this problem to the application. This can partly be
alleviated by configuring an `ExceptionHandler`, but this may still not
cover all cases. For this reason, if logging is part of your business
logic, for example, if you are using Log4j as an audit logging framework,
we would recommend synchronously logging those audit messages. (Note that
you can still link:#MixedSync-Async[combine] them and use asynchronous
logging for debug/trace logging in addition to synchronous logging for
the audit trail.)
* In some rare cases, care must be taken with mutable messages. Most of
the time you don't need to worry about this. Log4 will ensure that log
messages like `logger.debug("My object is {}", myObject)` will use the
state of the `myObject` parameter at the time of the call to
`logger.debug()`. The log message will not change even if `myObject` is
modified later. It is safe to asynchronously log mutable objects because
most
link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`]
implementations built-in to Log4j take a snapshot of the parameters.
There are some exceptions, however:
link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[`MapMessage`]
and
link:../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html[`StructuredDataMessage`]
are mutable by design: fields can be added to these messages after the
message object was created. These messages should not be modified after
they are logged with asynchronous loggers or asynchronous appenders; you
may or may not see the modifications in the resulting log output.
Similarly, custom
link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`]
implementations should be designed with asynchronous use in mind, and
either take a snapshot of their parameters at construction time, or
document their thread-safety characteristics.

* If your application is running in an environment where CPU resources
are scarce, like a machine with one CPU with a single core, starting
another thread is not likely to give better performance.
* If the _sustained rate_ at which your application is logging messages
is faster than the maximum sustained throughput of the underlying
appender, the queue will fill up and the application will end up logging
at the speed of the slowest appender. If this happens, consider
selecting an xref:manual/performance.adoc#whichAppender[faster appender], or
logging less. If neither of these is an option, you may get better
throughput and fewer latency spikes by logging synchronously.
include::partial$manual/async-trade-offs.adoc[leveloffset=+1]

[#AllAsync]
== Making All Loggers Asynchronous
Expand Down Expand Up @@ -177,7 +109,7 @@ of the application.
[[SysPropsAllAsync]]
=== Configuration Properties

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

There are also a few system properties that can be used to maintain
application throughput even when the underlying appender cannot keep up
Expand Down Expand Up @@ -251,7 +183,7 @@ of the application.
[[SysPropsMixedSync-Async]]
=== Configuration Properties

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

There are also a few system properties that can be used to maintain
application throughput even when the underlying appender cannot keep up
Expand Down Expand Up @@ -457,7 +389,7 @@ threads

This section has been rewritten with the Log4j 2.6 release. The
previous version only reported _service time_ instead of _response
time_. See the xref:manual/performance.adoc#responseTime[response time] sidebar on the performance page on why this is too optimistic.
time_. See the xref:manual/performance.adoc#responseTime[response time] sidebar on the performance page on why this is too optimistic.
Furthermore, the previous version reported average latency, which does not make sense
since latency is not a normal distribution. Finally, the previous
version of this section only reported the maximum latency of up to
Expand All @@ -472,7 +404,7 @@ the "Oh s#@t!" presentation.)

xref:manual/performance.adoc#responseTime[Response time] is how long it
takes to log a message under a certain load. What is often reported as
latency is _service time_: how long it took to operate.
latency is _service time_: how long it took to operate.
This hides the fact that a single spike in service time adds
a queueing delay for many of the subsequent operations. Service time is
easy to measure (and often looks good on paper) but is irrelevant for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ Log events that are more specific than this setting will be filtered out.
See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to a logger configuration.

[id=property-substitution]
=== Property substitution
=== [[PropertySubstitution]]Property substitution

Log4j provides a simple and extensible mechanism to reuse values in the configuration file using `$\{name}` expressions, such as those used in Bash, Ant or Maven.

Expand Down
Loading
Loading