Skip to content

Commit

Permalink
Clean up mentions of log4j2.enable.threadLocals property (#2171)
Browse files Browse the repository at this point in the history
  • Loading branch information
vy committed Jan 15, 2024
1 parent 7f41487 commit e6044c9
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 111 deletions.
6 changes: 2 additions & 4 deletions src/site/asciidoc/manual/async.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -687,10 +687,8 @@ command line options we used:
* -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin
wait strategy reduces some jitter.)
* *classic mode:* -Dlog4j2.enable.threadlocals=false
-Dlog4j2.enable.direct.encoders=false +
*garbage-free mode:* -Dlog4j2.enable.threadlocals=true
-Dlog4j2.enable.direct.encoders=true
* *classic mode:* -Dlog4j2.enable.direct.encoders=false +
*garbage-free mode:* -Dlog4j2.enable.direct.encoders=true
* -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle
* -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime
Expand Down
3 changes: 1 addition & 2 deletions src/site/asciidoc/manual/extending.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,7 @@ declare it as a service by defining the implmentation class in a file named
== Custom ThreadContextMap implementations
A garbage-free `StringMap`-based context map can be installed by setting
system property `log4j2.garbagefreeThreadContextMap` to true. (Log4j
must be link:garbagefree.html#Config[enabled] to use ThreadLocals.)
system property `log4j2.garbagefreeThreadContextMap` to true.
Any custom link:../log4j-core/apidocs/org/apache/logging/log4j/spi/ThreadContextMap.html[`ThreadContextMap`]
implementation can be installed by setting system property `log4j2.threadContextMap`
Expand Down
13 changes: 2 additions & 11 deletions src/site/asciidoc/manual/garbagefree.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ you may also configure a link:async.html#WaitStrategy[custom wait strategy].)
There are two separate system properties for manually controlling the
mechanisms Log4j uses to avoid creating temporary objects:
* `log4j2.enableThreadlocals` - if "true" (the default for non-web
applications) objects are stored in ThreadLocal fields and reused,
otherwise new objects are created for each log event.
* `log4j2.enableDirectEncoders` - if "true" (the default) log events are
converted to text and this text is converted to bytes without creating
temporary objects. Note: _synchronous_ logging performance may be worse
Expand Down Expand Up @@ -386,10 +383,6 @@ http://logging.apache.org/log4j/2.x/log4j-api/xref/org/apache/logging/log4j/util
interface. If an object is logged that implements this interface, its
`formatTo` method is called instead of `toString()`.
Log4j may call `toString()` on message and parameter objects when
garbage-free logging is disabled (when system property
`log4j2.enableThreadlocals` is set to "false".)
[#codeImpact]
=== Impact on Application Code: Autoboxing
Expand Down Expand Up @@ -463,10 +456,8 @@ command line options we used:
* -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin
wait strategy reduces some jitter.)
* *classic mode:* -Dlog4j2.enable.threadlocals=false
-Dlog4j2.enable.direct.encoders=false +
*garbage-free mode:* -Dlog4j2.enable.threadlocals=true
-Dlog4j2.enable.direct.encoders=true
* *classic mode:* -Dlog4j2.enable.direct.encoders=false +
*garbage-free mode:* -Dlog4j2.enable.direct.encoders=true
* -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle
* -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime
Expand Down
86 changes: 2 additions & 84 deletions src/site/asciidoc/manual/json-template-layout.adoc.vm
Original file line number Diff line number Diff line change
Expand Up @@ -338,48 +338,6 @@ JsonTemplateLayout:
}
----

[#recycling-strategy]
=== Recycling strategy

`RecyclerFactory` plays a crucial role for determining the memory footprint of
the layout. Template resolvers employ it to create recyclers for objects that
they can reuse. The behavior of each `RecyclerFactory` and when one should
prefer one over another is explained below:

* `dummy` performs no recycling, hence each recycling attempt will result in a
new instance. This will obviously create a load on the garbage-collector. It
is a good choice for applications with low and medium log rate.

* `threadLocal` performs the best, since every instance is stored in
``ThreadLocal``s and accessed without any synchronization cost. Though this
might not be a desirable option for applications running with hundreds of
threads or more, e.g., a web servlet.

* `queue` is the best of both worlds. It allows recycling of objects up to a
certain number (`capacity`). When this limit is exceeded due to excessive
concurrent load (e.g., `capacity` is 50 but there are 51 threads concurrently
trying to log), it starts allocating. `queue` is a good strategy where
`threadLocal` is not desirable.
+
`queue` also accepts optional `supplier` (of type `java.util.Queue`, defaults to
`org.jctools.queues.MpmcArrayQueue.new` if JCTools is in the classpath;
otherwise `java.util.concurrent.ArrayBlockingQueue.new`) and `capacity` (of
type `int`, defaults to `max(8,2*cpuCount+1)`) parameters:
+
.Example configurations of `queue` recycling strategy
[source]
----
queue:supplier=org.jctools.queues.MpmcArrayQueue.new
queue:capacity=10
queue:supplier=java.util.concurrent.ArrayBlockingQueue.new,capacity=50
----

The default `RecyclerFactory` is `threadLocal`, if
`log4j2.enable.threadlocals=true`; otherwise, `queue`.

See <<extending-recycler>> for details on how to introduce custom
`RecyclerFactory` implementations.

[#template-config]
== Template Configuration

Expand Down Expand Up @@ -1082,8 +1040,7 @@ Resolves `logEvent.getMessage().getParameters()`.
====
Regarding garbage footprint, `stringified` flag translates to
`String.valueOf(value)`, hence mind not-`String`-typed values. Further,
`logEvent.getMessage()` is expected to implement `ParameterVisitable` interface,
which is the case if `log4j2.enableThreadLocals` property set to true.
`logEvent.getMessage()` is expected to implement `ParameterVisitable` interface.
====

====== Examples
Expand Down Expand Up @@ -1590,7 +1547,6 @@ plugins:

* Event template resolvers (e.g., `exception`, `message`, `level` event template resolvers)
* Event template interceptors (e.g., injection of `eventTemplateAdditionalField`)
* Recycler factories

Following sections cover these in detail.

Expand Down Expand Up @@ -1829,44 +1785,6 @@ provided an `eventTemplateRootObjectKey`. If so, it wraps the root `node` with a
new object; otherwise, returns the `node` as is. Note that `node` refers to the
root Java object of the event template read by `JsonReader`.

[#extending-recycler]
=== Extending Recycler Factories

`recyclerFactory` input `String` read from the layout configuration is converted
to a `RecyclerFactory` using the default `RecyclerFactoryConverter` extending
from `TypeConverter<RecyclerFactory>`. If one wants to change this behavior,
they simply need to add their own `TypeConverter<RecyclerFactory>` implementing
`Comparable<TypeConverter<?>>` to prioritize their custom converter.

[source,java]
.Custom `TypeConverter` for `RecyclerFactory`
----
package com.acme.logging.log4j.layout.template.json;

import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.convert.TypeConverter;

@Category(TypeConverter.CATEGORY)
@Plugin("AcmeRecyclerFactoryConverter")
public final class AcmeRecyclerFactoryConverter
implements TypeConverter<RecyclerFactory>, Comparable<TypeConverter<?>> {

@Override
public RecyclerFactory convert(final String recyclerFactorySpec) {
return AcmeRecyclerFactory.ofSpec(recyclerFactorySpec);
}

@Override
public int compareTo(final TypeConverter<?> ignored) {
return -1;
}

}
----

Here note that `compareTo()` always returns -1 to rank it higher compared to
other matching converters.

[#features]
== Features

Expand Down Expand Up @@ -1966,7 +1884,7 @@ Yes, if the garbage-free layout behaviour toggling properties
`log4j2.enableDirectEncoders` and `log4j2.garbagefreeThreadContextMap` are
enabled. Take into account the following caveats:

* The configured link:#recycling-strategy[recycling strategy] might not be
* The configured recycling strategy might not be
garbage-free.

* Since `Throwable#getStackTrace()` clones the original `StackTraceElement[]`,
Expand Down
10 changes: 0 additions & 10 deletions src/site/asciidoc/manual/systemproperties.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -365,16 +365,6 @@ class name of a custom `ThreadContextMap` implementation class.
|If `true` use a `InheritableThreadLocal` to implement the ThreadContext map. Otherwise, use a plain `ThreadLocal`.
(May be ignored if a custom ThreadContext map is specified.)
|ThreadLocals
|enable
|log4j2.enableThreadlocals, LOG4J_ENABLE_THREADLOCALS
|System
|true
|This system property can be used to switch off the use of threadlocals, which will partly disable Log4j's
garbage-free behaviour: to be fully garbage-free, Log4j stores objects in ThreadLocal fields to reuse them,
otherwise new objects are created for each log event. Note that this property is not effective when Log4j
detects it is running in a web application.
|Unbox
|ringBufferSize
|log4j2.unboxRingbufferSize, LOG4J_UNBOX_RINGBUFFER_SIZE
Expand Down

0 comments on commit e6044c9

Please sign in to comment.