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 be863cf901 Improve layout docs on property substitution (#2667)
be863cf901 is described below
commit be863cf901b643e754efee2216d5b13f3ae208f9
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Wed Jun 19 14:46:11 2024 +0200
Improve layout docs on property substitution (#2667)
---
.../resources/threadLocalRecyclerNestedLogging.xml | 4 +-
.../json/resolver/TemplateResolverContext.java | 2 +-
.../TemplateResolverStringSubstitutor.java | 4 +-
.../template/json/resolver/package-info.java | 2 +-
.../log4j2.json | 0
.../log4j2.properties | 0
.../log4j2.xml | 0
.../log4j2.yaml | 0
.../property-substitution/log4j2.json | 27 ++++
.../log4j2.properties} | 34 ++---
.../log4j2.xml | 17 +--
.../log4j2.yaml | 14 +-
.../modules/ROOT/pages/manual/garbagefree.adoc | 4 +-
.../ROOT/pages/manual/json-template-layout.adoc | 155 ++++++++++++++++++---
.../antora/modules/ROOT/pages/manual/layouts.adoc | 4 -
.../antora/modules/ROOT/pages/manual/lookups.adoc | 1 +
.../modules/ROOT/pages/manual/pattern-layout.adoc | 50 ++++++-
.../partials/manual/layouts-gcfree-lookup.adoc | 21 ---
18 files changed, 234 insertions(+), 105 deletions(-)
diff --git
a/log4j-layout-template-json-test/src/test/resources/threadLocalRecyclerNestedLogging.xml
b/log4j-layout-template-json-test/src/test/resources/threadLocalRecyclerNestedLogging.xml
index e3f5be0b8e..06c8a99022 100644
---
a/log4j-layout-template-json-test/src/test/resources/threadLocalRecyclerNestedLogging.xml
+++
b/log4j-layout-template-json-test/src/test/resources/threadLocalRecyclerNestedLogging.xml
@@ -30,9 +30,7 @@
<Loggers>
<Root level="trace">
<AppenderRef ref="List1"/>
- </Root>
- <Logger name="org" level="trace">
<AppenderRef ref="List2"/>
- </Logger>
+ </Root>
</Loggers>
</Configuration>
diff --git
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverContext.java
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverContext.java
index 74ca965887..e7522e3da9 100644
---
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverContext.java
+++
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverContext.java
@@ -30,7 +30,7 @@ import
org.apache.logging.log4j.layout.template.json.util.JsonWriter;
*
* @see TemplateResolverFactory
*/
-interface TemplateResolverContext<V, C extends TemplateResolverContext<V, C>> {
+public interface TemplateResolverContext<V, C extends
TemplateResolverContext<V, C>> {
Class<C> getContextClass();
diff --git
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverStringSubstitutor.java
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverStringSubstitutor.java
index 64b54a0202..c765dc8427 100644
---
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverStringSubstitutor.java
+++
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/TemplateResolverStringSubstitutor.java
@@ -28,8 +28,8 @@ public interface TemplateResolverStringSubstitutor<V> {
StrSubstitutor getInternalSubstitutor();
/**
- * A substitutor is stable if the replacement doesn't vary with the
provided
- * value. In such a case, value is always set to {@code null}.
+ * A substitutor is stable if the replacement doesn't vary with the
provided value.
+ * That is, in a stable substitutor, {@code value} argument of {@link
#replace(Object, String)} is always ignored.
*/
boolean isStable();
diff --git
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/package-info.java
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/package-info.java
index 6398bdffb3..376a67bd33 100644
---
a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/package-info.java
+++
b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/package-info.java
@@ -16,7 +16,7 @@
*/
@Export
@Open("org.apache.logging.log4j.core")
-@Version("2.20.1")
+@Version("2.21.0")
package org.apache.logging.log4j.layout.template.json.resolver;
import aQute.bnd.annotation.jpms.Open;
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.json
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.json
similarity index 100%
rename from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.json
rename to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.json
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.properties
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.properties
similarity index 100%
rename from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.properties
rename to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.properties
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.xml
similarity index 100%
copy from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml
copy to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.xml
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.yaml
similarity index 100%
copy from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
copy to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/event-template-additional-field/log4j2.yaml
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.json
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.json
new file mode 100644
index 0000000000..bf85540b4d
--- /dev/null
+++
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.json
@@ -0,0 +1,27 @@
+{
+ "Configuration": {
+ "Appenders": {
+ "Console": {
+ "name": "CONSOLE",
+ "JsonTemplateLayout": {
+ "eventTemplate": "{\"instant\": {\"$resolver\": \"pattern\",
\"pattern\": \"${env:LOG4J_DATE_PATTERN:-%d}\"}}", //<1>
+ "eventTemplateAdditionalField": [
+ {
+ "key": "message",
+ "format": "JSON",
+ "value": "{\"$resolver\": \"pattern\", \"pattern\":
\"${env:LOG4J_MESSAGE_PATTERN:-%m}\"}" //<2>
+ }
+ ]
+ }
+ }
+ },
+ "Loggers": {
+ "Root": {
+ "level": "WARN",
+ "AppenderRef": {
+ "ref": "CONSOLE"
+ }
+ }
+ }
+ }
+}
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.properties
similarity index 55%
copy from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
copy to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.properties
index 0349dd2575..d32d6cd88d 100644
---
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
+++
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.properties
@@ -14,28 +14,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-Configuration:
+appender.0.type = Console
+appender.0.name = CONSOLE
+appender.0.layout.type = JsonTemplateLayout
+appender.0.layout.eventTemplate = {"instant": {"$resolver": "pattern",
"pattern": "${env:LOG4J_DATE_PATTERN:-%d}"}} #<1>
+appender.0.layout.eventTemplateAdditionalField[0].type =
EventTemplateAdditionalField
+appender.0.layout.eventTemplateAdditionalField[0].key = message
+appender.0.layout.eventTemplateAdditionalField[0].format = JSON
+appender.0.layout.eventTemplateAdditionalField[0].value = {"$resolver":
"pattern", "pattern": "${env:LOG4J_MESSAGE_PATTERN:-%m}"} #<2>
- Appenders:
- Console:
- name: "CONSOLE"
- JsonTemplateLayout:
- eventTemplateUri: "classpath:GelfLayout.json"
- eventTemplateAdditionalField:
- - key: "aString"
- value: "foo" #<1>
- - key: "marker"
- value: '{"$resolver": "marker", "field": "name"}'
- format: "JSON"
- - key: "aNumber"
- value: "1"
- format: "JSON"
- - key: "aList"
- value: '[1, 2, "three"]'
- format: "JSON"
-
- Loggers:
- Root:
- level: "WARN"
- AppenderRef:
- ref: "CONSOLE"
+rootLogger.level = WARN
+rootLogger.appenderRef.0.ref = CONSOLE
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.xml
similarity index 74%
rename from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml
rename to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.xml
index c6b2f32ae8..8e44b6e96c 100644
---
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml
+++
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.xml
@@ -23,22 +23,11 @@
<Appenders>
<Console name="CONSOLE">
- <JsonTemplateLayout eventTemplateUri="classpath:GelfLayout.json">
+ <JsonTemplateLayout eventTemplate='{"instant": {"$resolver": "pattern",
"pattern": "${env:LOG4J_DATE_PATTERN:-%d}"}}'> <!--1-->
<EventTemplateAdditionalField
- key="aString"
- value="foo"/><!--1-->
- <EventTemplateAdditionalField
- key="marker"
- format="JSON"
- value='{"$resolver": "marker", "field": "name"}'/>
- <EventTemplateAdditionalField
- key="aNumber"
- format="JSON"
- value="1"/>
- <EventTemplateAdditionalField
- key="aList"
+ key="message"
format="JSON"
- value='[1, 2, "three"]'/>
+ value='{"$resolver": "pattern", "pattern":
"${env:LOG4J_MESSAGE_PATTERN:-%m}"}'/> <!--2-->
</JsonTemplateLayout>
</Console>
</Appenders>
diff --git
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.yaml
similarity index 73%
rename from
src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
rename to
src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.yaml
index 0349dd2575..382e9e5af4 100644
---
a/src/site/antora/modules/ROOT/examples/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml
+++
b/src/site/antora/modules/ROOT/examples/manual/json-template-layout/property-substitution/log4j2.yaml
@@ -20,19 +20,11 @@ Configuration:
Console:
name: "CONSOLE"
JsonTemplateLayout:
- eventTemplateUri: "classpath:GelfLayout.json"
+ eventTemplate: '{"instant": {"$resolver": "pattern", "pattern":
"${env:LOG4J_DATE_PATTERN:-%d}"}}' #<1>
eventTemplateAdditionalField:
- - key: "aString"
- value: "foo" #<1>
- - key: "marker"
- value: '{"$resolver": "marker", "field": "name"}'
- format: "JSON"
- - key: "aNumber"
- value: "1"
- format: "JSON"
- - key: "aList"
- value: '[1, 2, "three"]'
+ - key: "message"
format: "JSON"
+ value: '{"$resolver": "pattern", "pattern":
"${env:LOG4J_MESSAGE_PATTERN:-%m}"}' #<2>
Loggers:
Root:
diff --git a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
index c8736c8ef1..5bc6438cfa 100644
--- a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc
@@ -57,7 +57,7 @@ If not for yours, keep on reading.
In order to have a garbage-free Log4j Core, you need to
* <<core-properties,configure it using properties>>,
-* and employ garbage-free <<Layouts[layouts], xref:Appenders[appenders], and
xref:#Filters,filters>>.
+* and employ garbage-free <<Layouts,layouts>>, <<Appenders,appenders>>, and
<<Filters,filters>>.
[#core-properties]
=== Properties
@@ -211,7 +211,7 @@ Not all Log4j API feature set is garbage-free, specifically:
* The `ThreadContext` map (aka. MDC) is not garbage-free by default, but can
be configured to be garbage-free by setting
<<log4j2.garbagefreeThreadContextMap,the `log4j2.garbagefreeThreadContextMap`
system property>> to `true`.
* The `ThreadContext` stack (aka. NDC) is not garbage-free.
* xref:manual/scoped-context.adoc[] is not garbage-free.
-* Logging very large messages (i.e., more than
<<log4j2.maxReusableMsgSize[`log4j2.maxReusableMsgSize`] characters, which
defaults to 518), when all loggers are xref:manual/async.adoc,asynchronous
loggers>>, will cause the internal `StringBuilder` in the
+* Logging very large messages (i.e., more than <<log4j2.maxReusableMsgSize>>
characters, which defaults to 518), when all loggers are
xref:manual/async.adoc[asynchronous loggers], will cause the internal
`StringBuilder` in the
`RingBuffer` to be trimmed back to their configured maximum size.
* Logging messages containing `$\{variable}` substitutions creates temporary
objects.
* Logging a lambda as a parameter:
diff --git
a/src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
b/src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
index 016450092c..2b36a611dc 100644
--- a/src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/json-template-layout.adoc
@@ -16,7 +16,7 @@
////
= JSON Template Layout
-`JsonTemplateLayout` is a customizable, <<performance,efficient>>, and
xref:#faq-garbage-free,garbage-free>> JSON generating layout.
+`JsonTemplateLayout` is a customizable, <<performance,efficient>>, and
<<faq-garbage-free,garbage-free>> JSON generating layout.
It encodes ``LogEvent``s according to the structure described by the JSON
template provided.
In a nutshell, it shines with its
@@ -348,7 +348,7 @@ That is,
"key00002": "value00002",
"key00003": "value00003",
// ...
- "key16384": "value16384",
+ "key16384": "value16384"
}
}
----
@@ -403,34 +403,34 @@ Below we share an example configuration overriding the
`GelfLayout.json` event t
====
XML::
+
-.Snippet from an example
{antora-examples-url}/manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml[`log4j2.xml`]
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/event-template-additional-field/log4j2.xml[`log4j2.xml`]
[source,xml]
----
-include::example$manual/json-template-layout/eventTemplateAdditionalField/log4j2.xml[lines=26..42,indent=0]
+include::example$manual/json-template-layout/event-template-additional-field/log4j2.xml[lines=26..42,indent=0]
----
JSON::
+
-.Snippet from an example
{antora-examples-url}/manual/json-template-layout/eventTemplateAdditionalField/log4j2.json[`log4j2.json`]
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/event-template-additional-field/log4j2.json[`log4j2.json`]
[source,json]
----
-include::example$manual/json-template-layout/eventTemplateAdditionalField/log4j2.json[lines=6..29,indent=0]
+include::example$manual/json-template-layout/event-template-additional-field/log4j2.json[lines=6..29,indent=0]
----
YAML::
+
-.Snippet from an example
{antora-examples-url}/manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml[`log4j2.yaml`]
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/event-template-additional-field/log4j2.yaml[`log4j2.yaml`]
[source,xml]
----
-include::example$manual/json-template-layout/eventTemplateAdditionalField/log4j2.yaml[lines=22..35,indent=0]
+include::example$manual/json-template-layout/event-template-additional-field/log4j2.yaml[lines=22..35,indent=0]
----
Properties::
+
-.Snippet from an example
{antora-examples-url}/manual/json-template-layout/eventTemplateAdditionalField/log4j2.properties[`log4j2.properties`]
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/event-template-additional-field/log4j2.properties[`log4j2.properties`]
[source,xml]
----
-include::example$manual/json-template-layout/eventTemplateAdditionalField/log4j2.properties[lines=19..35,indent=0]
+include::example$manual/json-template-layout/event-template-additional-field/log4j2.properties[lines=19..35,indent=0]
----
====
<1> Since the `format` attribute is not explicitly set, the default (i.e.,
`STRING`) will be used
@@ -1208,6 +1208,8 @@ pattern = "pattern" -> string
stackTraceEnabled = "stackTraceEnabled" -> boolean
----
+Unlike providing the `pattern` attribute to Pattern Layout in a configuration
file, <<faq-lookups,property substitutions>> found in the `pattern` will _not_
be resolved.
+
The default value of `stackTraceEnabled` is inherited from the parent JSON
Template Layout.
[NOTE]
@@ -1642,6 +1644,127 @@ config = "field" -> (
All above accesses to `StackTraceElement` is garbage-free.
+[#faq-lookups]
+== Property substitution
+
+Property substitutions (e.g., `$\{myProperty}`), including
xref:manual/lookups.adoc[lookups] (e.g., `${java:version}`, `${env:USER}`,
`${date:MM-dd-yyyy}`), are supported, but extra care needs to be taken.
+*We strongly advise you to carefully read
xref:manual/configuration.adoc#property-substitution[the configuration manual]*
before using them.
+
+[IMPORTANT]
+====
+xref:manual/lookups.adoc[] are intended as a very generic, convenience utility
to perform string interpolation for, in particular, configuration files and
components (e.g., layouts) lacking this mechanism.
+*JSON Template Layout has a rich template resolver collection, and you should
always prefer it whenever possible over lookups.*
+
+.Which resolvers can I use to replace lookups?
+[%collapsible]
+=====
+[%header,cols="1,1"]
+|===
+|Instead of this lookup
+|Use this resolver
+
+|xref:manual/lookups.adoc#ContextMapLookup[Context Map Lookup]
+|<<event-template-resolver-mdc>>
+
+|xref:manual/lookups.adoc#DateLookup[Date Lookup]
+|<<event-template-resolver-timestamp>>
+
+|xref:manual/lookups.adoc#EventLookup[Event Lookup]
+|<<event-template-resolver-exception>> +
+<<event-template-resolver-level>> +
+<<event-template-resolver-logger>> +
+<<event-template-resolver-marker>> +
+<<event-template-resolver-message>> +
+<<event-template-resolver-thread>> +
+<<event-template-resolver-timestamp>>
+
+|xref:manual/lookups.adoc#LowerLookup[Lower Lookup]
+|<<event-template-resolver-caseConverter>>
+
+|xref:manual/lookups.adoc#AppMainArgsLookup[Main Arguments Lookup]
+|<<event-template-resolver-main>>
+
+|xref:manual/lookups.adoc#MapLookup[Map Lookup]
+|<<event-template-resolver-map>>
+
+|xref:manual/lookups.adoc#marker-lookup[Marker Lookup]
+|<<event-template-resolver-marker>>
+
+|xref:manual/lookups.adoc#UpperLookup[Upper Lookup]
+|<<event-template-resolver-caseConverter>>
+|===
+=====
+====
+
+[#property-substitution-in-template]
+=== Property substitution in event templates
+
+JSON Template Layout performs property substitution in string literals in
templates, except if they are located in _configuration object of resolvers_.
+Consider the following event template file provided using
<<plugin-attr-eventTemplateUri,the `eventTemplateUri` attribute>>:
+
+[source,json]
+----
+{
+ "java-version": "${java:version}", //<1>
+ "pid": {
+ "$resolver": "pattern",
+ "pattern": "${env:NO_SUCH_KEY:-%pid}" //<2>
+ }
+}
+----
+<1> This works. `${java:version}` will be replaced with the corresponding
value.
+<2> This won't work! That is, `${env:NO_SUCH_KEY:-%pid}` literal will not get
substituted, since it is located in a _configuration object of a resolver_.
+
+[#property-substitution-in-config]
+=== Property substitution in configuration files
+
+If the very same event template <<property-substitution-in-template,shared
above>> is inlined in a configuration file using
<<plugin-attr-eventTemplate,the `eventTemplate` attribute>> or
<<plugin-element-EventTemplateAdditionalField,additional event template
fields>>, then all substitutions will be replaced, once, at configuration-time.
+This has nothing to do with the JSON Template Layout, but the substitution
performed by the configuration mechanism when the configuration is read.
+Consider the following example:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/property-substitution/log4j2.xml[`log4j2.xml`]
+[source,xml]
+----
+include::example$manual/json-template-layout/property-substitution/log4j2.xml[lines=26..31,indent=0]
+----
+
+JSON::
++
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/property-substitution/log4j2.json[`log4j2.json`]
+[source,json]
+----
+include::example$manual/json-template-layout/property-substitution/log4j2.json[lines=6..15,indent=0]
+----
+
+YAML::
++
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/property-substitution/log4j2.yaml[`log4j2.yaml`]
+[source,xml]
+----
+include::example$manual/json-template-layout/property-substitution/log4j2.yaml[lines=22..27,indent=0]
+----
+
+Properties::
++
+.Snippet from an example
{antora-examples-url}/manual/json-template-layout/property-substitution/log4j2.properties[`log4j2.properties`]
+[source,xml]
+----
+include::example$manual/json-template-layout/property-substitution/log4j2.properties[lines=19..24,indent=0]
+----
+====
+<1> `eventTemplate` will be passed to the layout with `${env:...}` substituted
+<2> `value` will be passed to the layout with `${env:...}` substituted
+
+[WARNING]
+====
+External values injected this way can corrupt your JSON schema.
+It is your responsibility to ensure the sanitization and safety of the
substitution source.
+====
+
[#recycling-strategy]
== Recycling strategy
@@ -2051,13 +2174,6 @@ To get the most out of it, mind the following checklist:
[#faq]
== F.A.Q.
-[#faq-lookups]
-=== Are lookups supported in templates?
-
-Yes, xref:manual/lookups.adoc[lookups] (e.g., `${java:version}`,
`${env:USER}`, `${date:MM-dd-yyyy}`) are supported in string literals of
templates.
-
-include::partial$manual/layouts-gcfree-lookup.adoc[]
-
[#faq-recursive-collection]
=== Are recursive collections supported?
@@ -2085,6 +2201,7 @@ Take into account the following caveats:
* Serialization of ``MapMessage``s and ``ObjectMessage``s are mostly
garbage-free except for certain types (e.g., `BigDecimal`, `BigInteger`,
``Collection``s, except `List`).
-* xref:manual/lookups.adoc[Lookups] (that is, `${...}` variables) are not
garbage-free.
+* <<faq-lookups,Property substitutions>> (that is, `${...}` variables) _might_
not be garbage-free.
-Don't forget to check out <<event-template-resolvers,the notes on garbage
footprint of resolvers>> you employ in templates.
+<<event-template-resolvers>> contain notes on their garbage footprint.
+Make sure to check those notes of resolvers you employ in templates.
diff --git a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
index 457c71c7d8..1551802e5f 100644
--- a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc
@@ -631,8 +631,6 @@ runtimeOnly
'com.fasterxml.jackson.core:jackson-databind:{jackson-version}'
`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON
generating layout.
It encodes ``LogEvent``s according to the structure described by the JSON
template provided.
-xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-JsonTemplateLayout[📖
Plugin reference for `JsonTemplateLayout`]
-
For instance, given the following event template stored in `MyLayout.json` in
your classpath:
[source,json]
@@ -718,8 +716,6 @@ Pattern Layout is not intended for _structural logging_
purposes.
For production environments, you are strongly advised to use
xref:manual/json-template-layout.adoc[] producing JSON output ready to be
delivered to log ingestion systems such as Elasticsearch or Google Cloud
Logging.
====
-xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-PatternLayout[📖
Plugin reference for `PatternLayout`]
-
A conversion pattern is composed of literal text and format control
expressions.
For instance, given the `%-5p [%t]: %m%n` pattern, following statements
diff --git a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc
b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc
index 3b24c6ee4d..b417b5cd9e 100644
--- a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc
@@ -469,6 +469,7 @@ page for information on how to set the default values.
</Routing>
----
+[#marker-lookup]
== Marker Lookup
The marker lookup allows you to use markers in interesting
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 e8a43cb32c..ab4216480f 100644
--- a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
@@ -17,7 +17,7 @@
= Pattern Layout
-`PatternLayout` is a customizable, <<performance[efficient],
xref:#garbage-free,garbage-free>>, and human-readable string generating layout
using a user-provided pattern.
+`PatternLayout` is a customizable, <<performance,efficient>>,
<<garbage-free,garbage-free>>, and human-readable string generating layout
using a user-provided pattern.
It is analogous to `String#format()` with specialized directives on injecting
certain properties of a `LogEvent`.
[IMPORTANT]
@@ -1678,12 +1678,56 @@ Format modifiers to control such things as field width,
padding, left, and right
|
|literal text
-a|Garbage-free, but care is needed for xref:manual/lookups.adoc[].
-include::partial$manual/layouts-gcfree-lookup.adoc[]
+a|Garbage-free, but care is needed for <<property-substitution>>, including
xref:manual/lookups.adoc[]
|===
Patterns containing regular expressions and
xref:manual/layouts.adoc#LocationInformation[location information] are not
garbage-free.
+[#property-substitution]
+== Property substitution
+
+xref:manual/configuration.adoc#property-substitution[Property substitutions]
(e.g., `$\{myProperty}`), including xref:manual/lookups.adoc[lookups] (e.g.,
`${java:version}`, `${env:USER}`, `${date:MM-dd-yyyy}`) are supported, but
extra care needs to be taken.
+*We strongly advise you to carefully read
xref:manual/configuration.adoc#property-substitution[the configuration manual]*
before using them.
+
+[IMPORTANT]
+====
+xref:manual/lookups.adoc[] are intended as a very generic, convenience utility
to perform string interpolation for, in particular, configuration files and
components (e.g., layouts) lacking this mechanism.
+*Pattern Layout has a rich converter collection, and you should always prefer
it whenever possible over lookups.*
+
+.Which converters can I use to replace lookups?
+[%collapsible]
+=====
+[%header,cols="1,1"]
+|===
+|Instead of this lookup
+|Use this converter
+
+|xref:manual/lookups.adoc#ContextMapLookup[Context Map Lookup]
+|<<converter-thread-context-map>>
+
+|xref:manual/lookups.adoc#DateLookup[Date Lookup]
+|<<converter-date>>
+
+|xref:manual/lookups.adoc#EventLookup[Event Lookup]
+|<<converter-exception>> +
+<<converter-exception-extended>> +
+<<converter-level>> +
+<<converter-logger>> +
+<<converter-marker>> +
+<<converter-message>> +
+<<converter-thread-id>> +
+<<converter-thread-name>> +
+<<converter-date>>
+
+|xref:manual/lookups.adoc#MapLookup[Map Lookup]
+|<<converter-map>>
+
+|xref:manual/lookups.adoc#marker-lookup[Marker Lookup]
+|<<converter-marker>>
+|===
+=====
+====
+
[#extending]
== Extending
diff --git
a/src/site/antora/modules/ROOT/partials/manual/layouts-gcfree-lookup.adoc
b/src/site/antora/modules/ROOT/partials/manual/layouts-gcfree-lookup.adoc
deleted file mode 100644
index 1fd022a2f5..0000000000
--- a/src/site/antora/modules/ROOT/partials/manual/layouts-gcfree-lookup.adoc
+++ /dev/null
@@ -1,21 +0,0 @@
-////
- 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.
-////
-
-Encoding the output of a lookup is garbage-free, but executing the lookup
might not be.
-For instance, even though xref:manual/lookups.adoc#DateLookup[the `date`
lookup] allocates a new `String` for each invocation, adding
`${date:YYYY-MM-dd}` is garbage-free, because it will be expanded at
configuration time, that is, only once.
-Whereas adding `$${date:YYYY-MM-dd}` is not, since it will be expanded for
each log event.
-See xref:manual/configuration.adoc#property-substitution[property
substitution] for details.