diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java index e140b6d25c3..fd60f1cc6e5 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/lookup/MainInputArgumentsJmxLookupTest.java @@ -18,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; -import org.junit.jupiter.api.Test; +import java.util.Map; /** * Tests {@link JmxRuntimeInputArgumentsLookup} from the command line, not a JUnit test. @@ -33,18 +33,14 @@ public static void main(final String[] args) { new MainInputArgumentsJmxLookupTest().callFromMain(); } - @Test - public void testMap() { - final JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON; - assertNull(lookup.lookup(null)); - assertNull(lookup.lookup("X")); - assertNull(lookup.lookup("foo.txt")); - } - public void callFromMain() { final JmxRuntimeInputArgumentsLookup lookup = JmxRuntimeInputArgumentsLookup.JMX_SINGLETON; - assertNull(lookup.lookup(null)); - assertNull(lookup.lookup("X")); + String result1 = null; + assertNull(result1); + String result = null; + final Map map = lookup.getMap(); + result = map == null ? null : map.get("X"); + assertNull(result); // Eclipse adds -Dfile.encoding=Cp1252 // assertEquals("--file", lookup.lookup("0")); // assertEquals("foo.txt", lookup.lookup("1")); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/AbstractLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/AbstractLookup.java index 1950fa96884..2e039d1430e 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/AbstractLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/AbstractLookup.java @@ -16,6 +16,8 @@ */ package org.apache.logging.log4j.core.lookup; +import org.apache.logging.log4j.core.LogEvent; + /** * A default lookup for others to extend. * diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EnvironmentLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EnvironmentLookup.java index b31055bde28..7836c946705 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EnvironmentLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EnvironmentLookup.java @@ -27,12 +27,12 @@ public class EnvironmentLookup extends AbstractLookup { /** * Looks up the value of the environment variable. - * @param event The current LogEvent (is ignored by this StrLookup). + * * @param key the key to be looked up, may be null * @return The value of the environment variable. */ @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { return System.getenv(key); } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JavaLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JavaLookup.java index 11e74852a45..54c7fed56d0 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JavaLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JavaLookup.java @@ -90,14 +90,12 @@ public String getVirtualMachine() { /** * Looks up the value of the environment variable. * - * @param event - * The current LogEvent (is ignored by this StrLookup). * @param key * the key to be looked up, may be null * @return The value of the environment variable. */ @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { switch (key) { case "version": return "Java version " + getSystemProperty("java.version"); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java index ae9acbc3db5..45f216f1b40 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JmxRuntimeInputArgumentsLookup.java @@ -48,12 +48,7 @@ public JmxRuntimeInputArgumentsLookup(final Map map) { } @Override - public String lookup(final LogEvent event, final String key) { - return lookup(key); - } - - @Override - public String lookup(final String key) { + public String lookup(final LogEvent ignored, final String key) { if (key == null) { return null; } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java index 33df36d2046..34acd58a003 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java @@ -50,12 +50,11 @@ public JndiLookup() { /** * Looks up the value of the JNDI resource. * - * @param event The current LogEvent (is ignored by this StrLookup). * @param key the JNDI resource name to be looked up, may be null * @return The String value of the JNDI resource. */ @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { if (key == null) { return null; } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Log4jLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Log4jLookup.java index 8b19de63402..b16d47b7681 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Log4jLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Log4jLookup.java @@ -53,7 +53,7 @@ private static URI getParent(final URI uri) throws URISyntaxException { } @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { if (configuration != null) { final ConfigurationSource configSrc = configuration.getConfigurationSource(); final File file = configSrc.getFile(); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/LowerLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/LowerLookup.java index 79fe30c74ec..474a4e28972 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/LowerLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/LowerLookup.java @@ -25,26 +25,16 @@ * Converts values to lower case. The passed in "key" should be the value of another lookup. */ @Plugin(name = "lower", category = StrLookup.CATEGORY) -public class LowerLookup implements StrLookup { +public class LowerLookup extends AbstractLookup { /** * Converts the "key" to lower case. + * * @param key the key to be looked up, may be null * @return The value associated with the key. */ @Override - public String lookup(final String key) { + public String lookup(final LogEvent ignored, final String key) { return key != null ? toRootLowerCase(key) : null; } - - /** - * Converts the "key" to lower case. - * @param event The current LogEvent. - * @param key the key to be looked up, may be null - * @return The value associated with the key. - */ - @Override - public String lookup(final LogEvent event, final String key) { - return lookup(key); - } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MainMapLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MainMapLookup.java index 144515c8131..0b7a9a16f90 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MainMapLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/MainMapLookup.java @@ -82,7 +82,7 @@ public static void setMainArguments(final String... args) { } @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { return MAIN_SINGLETON.getMap().get(key); } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ResourceBundleLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ResourceBundleLookup.java index dd99467a84a..9b95f14f87b 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ResourceBundleLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/ResourceBundleLookup.java @@ -39,14 +39,12 @@ public class ResourceBundleLookup extends AbstractLookup { * * For example: "com.domain.messages:MyKey". * - * @param event - * The current LogEvent. * @param key * the key to be looked up, may be null * @return The value associated with the key. */ @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { if (key == null) { return null; } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/StructuredDataLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/StructuredDataLookup.java index 3b4324b04bb..05ef9e42079 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/StructuredDataLookup.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/StructuredDataLookup.java @@ -24,7 +24,7 @@ * Looks up keys from {@link org.apache.logging.log4j.message.StructuredDataMessage} log messages. */ @Plugin(name = "sd", category = StrLookup.CATEGORY) -public class StructuredDataLookup implements StrLookup { +public class StructuredDataLookup extends AbstractLookup { /** * Key to obtain the id of a structured message. @@ -36,16 +36,6 @@ public class StructuredDataLookup implements StrLookup { */ public static final String TYPE_KEY = "type"; - /** - * Returns {@code null}. This Lookup plugin does not make sense outside the context of a LogEvent. - * @param key The key to be looked up, may be null. - * @return {@code null} - */ - @Override - public String lookup(final String key) { - return null; - } - /** * Looks up the value for the key using the data in the LogEvent. * @param event The current LogEvent. diff --git a/log4j-docker/src/main/java/org/apache/logging/log4j/docker/DockerLookup.java b/log4j-docker/src/main/java/org/apache/logging/log4j/docker/DockerLookup.java index 6d0d2a97ad8..c52a5100b6c 100644 --- a/log4j-docker/src/main/java/org/apache/logging/log4j/docker/DockerLookup.java +++ b/log4j-docker/src/main/java/org/apache/logging/log4j/docker/DockerLookup.java @@ -95,7 +95,7 @@ public DockerLookup() { } @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { if (container == null) { return null; } diff --git a/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/WebLookup.java b/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/WebLookup.java index 18cbe26f8a8..35e47b821f8 100644 --- a/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/WebLookup.java +++ b/log4j-jakarta-web/src/main/java/org/apache/logging/log4j/web/WebLookup.java @@ -30,7 +30,7 @@ public class WebLookup extends AbstractLookup { private static final String INIT_PARAM_PREFIX = "initParam."; @Override - public String lookup(final LogEvent event, final String key) { + public String lookup(final LogEvent ignored, final String key) { final ServletContext ctx = WebLoggerContextUtils.getServletContext(); if (ctx == null) { return null; diff --git a/src/site/antora/modules/ROOT/examples/manual/lookups/MainArgsExample.java b/src/site/antora/modules/ROOT/examples/manual/lookups/MainArgsExample.java new file mode 100644 index 00000000000..3cb4b4af890 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/lookups/MainArgsExample.java @@ -0,0 +1,43 @@ +/* + * 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. + */ +package example; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public final class MainArgsExample implements Runnable { + + // tag::usage[] + private final Logger logger = LogManager.getLogger(); // <1> + + public static void main(final String[] args) { + try { // <2> + Class.forName("org.apache.logging.log4j.core.lookup.MainMapLookup") + .getDeclaredMethod("setMainArguments", String[].class) + .invoke(null, (Object) args); + } catch (final ReflectiveOperationException e) { + // Log4j Core is not used. + } + new MainArgsExample().run(); + } + // end::usage[] + + @Override + public void run() { + logger.info("Hello `main` lookup!"); + } +} diff --git a/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.json b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.json new file mode 100644 index 00000000000..1b731b0f494 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.json @@ -0,0 +1,31 @@ +{ + "Configuration": { + "Properties": { + "Property": [ // <1> + { + "name": "--logfile", + "value": "logs/app.log" + }, + { + "name": "--loglevel", + "value": "INFO" + } + ] + }, + "Appenders": { + "File": { + "fileName": "${main:\\--logfile}", // <2> + "name": "FILE", + "JsonTemplateLayout": {} + } + }, + "Loggers": { + "Root": { + "level": "${main:\\--loglevel", // <2> + "AppenderRef": { + "ref": "FILE" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.properties b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.properties new file mode 100644 index 00000000000..af488be152d --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.properties @@ -0,0 +1,29 @@ +# +# 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. +# +## +# <1> +property.--logfile = logs/app.log +property.--loglevel = INFO + +appender.0.type = File +# <2> +appender.0.fileName = ${main:\\--logfile} +appender.0.name = FILE + +# <2> +rootLogger.level = ${main:\\--loglevel} +rootLogger.appenderRef.0.ref = FILE diff --git a/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.xml b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.xml new file mode 100644 index 00000000000..7982925d596 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.yaml b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.yaml new file mode 100644 index 00000000000..dcbc3b1ab53 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/lookups/mainArgs.yaml @@ -0,0 +1,33 @@ +# +# 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: + Properties: # <1> + Property: + - name: "--logfile" + value: "logs/app.log" + - name: "--loglevel" + value: "INFO" + Appenders: + File: + fileName: "${main:\\--logfile}" # <2> + name: "FILE" + JsonTemplateLayout: {} + Loggers: + Root: + level: "${main:\\--loglevel}" # <2> + AppenderRef: + ref: "FILE" diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index d37ce1139f4..0700ff1c458 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -39,13 +39,16 @@ Appenders always have a name so that they can be referenced from Loggers. In the tables below, the "Type" column corresponds to the Java type expected. For non-JDK classes, these should usually be in link:../javadoc/log4j-core/index.html[Log4j Core] unless otherwise noted. +[#commons-concerns] +== Common concerns + [#common-properties] -== Common properties +=== Common properties These configuration attributes are shared by multiple appenders: [#immediateFlush] -=== `immediateFlush` +==== `immediateFlush` [cols="1h,5"] |=== @@ -69,6 +72,55 @@ This setting only guarantees that a byte representation of the log event is pass It does not ensure that the operating system writes the event to the underlying storage. ==== +[#runtime-evaluation] +=== Runtime evaluation of attributes + +The following configuration attributes are also evaluated at runtime, +so can contain escaped `$$+{...}+` expressions. + +.List of attributes evaluated at runtime +[cols="1,1,1,1"] +|=== +| Component | Parameter | Event type | Evaluation context + +| <> +| <> +| Log event +| xref:manual/lookups.adoc#global-context[_global_] + +| <> +| <> +| Log event +| xref:manual/lookups.adoc#event-context[_log event_] + +| <> +| <> +| Log event +| xref:manual/lookups.adoc#event-context[_log event_] + +| <> +| <> +| Log event +| xref:manual/lookups.adoc#global-context[_global_] + +| <> +| <> +| Rollover +| xref:manual/lookups.adoc#global-context[_global_] + +| <> +| `basePath` +| Rollover +| xref:manual/lookups.adoc#global-context[_global_] + +|=== + +The <> component of the <> is special: its children are evaluated at runtime, +but they are **not** evaluated at configuration time. +Inside the `Route` component you **should not** use escaped `$$+{...}+` expressions, but only unescaped `$+{...}+` expressions. + +See xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution] for more details. + [#collection] == Collection @@ -1541,7 +1593,7 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity { return this.id; } - public void setId(long id) { + public void setId(final long id) { this.id = id; } @@ -1611,8 +1663,14 @@ Optional, default is 0 (infinite timeout). |readTimeoutMillis |integer |The socket read timeout in milliseconds. Optional, default is 0 (infinite timeout). -|headers |Property[] |Additional HTTP headers to use. The values support -xref:manual/lookups.adoc[lookups]. +| [[HttpAppender-element-headers]]headers +| Property[] +| Additional HTTP headers to use. + +The values support +xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution] +and are evaluated in a +xref:manual/lookups.adoc#global-context[_global context_]. |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -1648,7 +1706,7 @@ Here is a sample HttpAppender configuration snippet: The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic. Each log event is sent as a Kafka record. -[width="100%",options="header"] +[cols="1m,1m,5"] |=== |Parameter Name |Type |Description @@ -1656,9 +1714,14 @@ Each log event is sent as a Kafka record. |String |The Kafka topic to use. Required. -|key +|[[KafkaAppender-attr-key]]key |String -|The key that will be sent to Kafka with every message. Optional value defaulting to `null`. Any of the xref:manual/lookups.adoc[Lookups] can be included. +|The key that will be sent to Kafka with every message. + +Supports +xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution] +and is evaluated in the +xref:manual/lookups.adoc#event-context[_context of the current event_]. |filter |Filter @@ -1852,6 +1915,22 @@ NoSQLObject>> |_Required._ The NoSQL provider that provides connections to the chosen NoSQL database. |======================================================================= +.`NoSqlAppender` -- nested elements +[cols="1m,1,4",id=NoSqlAppender-element-keyValuePairs] +|=== +| Type | Multiplicity | Description + +| xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-KeyValuePair[`KeyValuePair`] +| Zero or more +a| Adds a simple key/value field to the NoSQL object. + +The `value` attribute of the pair supports +xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution] +using the +xref:manual/lookups.adoc#event-context[current event as context]. + +|=== + You specify which NoSQL provider to use by specifying the appropriate configuration element within the `` element. The only type currently supported is ``. To create your custom provider, read the JavaDoc for the `NoSQLProvider`, `NoSQLConnection`, and `NoSQLObject` classes and the documentation about creating Log4j plugins. @@ -2391,6 +2470,7 @@ The following configuration shows a RewriteAppender configured to add a product ---- +[#PropertiesRewritePolicy] ===== PropertiesRewritePolicy PropertiesRewritePolicy will add properties configured on the policy to the ThreadContext Map being logged. @@ -2398,11 +2478,18 @@ The properties will not be added to the actual ThreadContext Map. The property values may contain variables that will be evaluated when the configuration is processed as well as when the event is logged. [cols="20%,20%,60%",options="header",] -|======================================================================= +|=== |Parameter Name |Type |Description -|properties |Property[] |One of more Property elements to define the -keys and values to be added to the ThreadContext Map. -|======================================================================= + +|[[PropertiesRewritePolicy-element-properties]]properties +|Property[] +|One of more Property elements to define the keys and values to be added to the ThreadContext Map. + +The `value` attribute of each `Property` element supports +xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution] +in the +xref:manual/lookups.adoc#global-context[_global context_]. +|=== The following configuration shows a RewriteAppender configured to add a product key and its value to the MapMessage: @@ -2524,15 +2611,32 @@ CompositeFilter. |fileName |String |The name of the file to write to. If the file, or any of its parent directories, do not exist, they will be created. -|filePattern |String |The pattern of the file name of the archived log -file. The format of the pattern is dependent on the `RolloverPolicy` that -is used. The DefaultRolloverPolicy will accept both a date/time pattern +| [[RollingFileAppender-attr-filePattern]]filePattern +| String +a| The pattern of the archived log filename. + +The format of the pattern is dependent on the `RolloverStrategy` that is used. +The standard rollover strategies accept: + +* xref:manual/configuration.adoc#lazy-property-substitution[runtime lookups], +which are evaluated in +xref:manual/lookups.adoc#global-context[a global context]. +* a `%d++{...}++` pattern, functionally identical to the +xref:manual/pattern-layout.adoc#converter-date[homonymous `PatternLayout` pattern] +except it uses the actual or inferred timestamp of the **previous** rollover. +* a `%i` pattern that expands to the computed index for the archived file. + +All patterns accept also format specifiers, e.g. `%03i` prints the index as zero-padded number with 3 digits. + +will accept both a date/time pattern compatible with https://docs.oracle.com/javase/{java-target-version}/docs/api/java/text/SimpleDateFormat.html[`SimpleDateFormat`] -and/or a %i which represents an integer counter. The integer counter +and/or a %i which represents an integer counter. +The integer counter allows specifying a padding, like %3i for space-padding the counter to 3 digits or (usually more useful) %03i for zero-padding the counter to -3 digits. The pattern also +3 digits. +The pattern also supports interpolation at runtime so any of the Lookups (such as the xref:manual/lookups.adoc#DateLookup[DateLookup]) can be included in the pattern. @@ -3703,6 +3807,15 @@ If the `Route` contains a ref attribute then the `Route` will reference an `Appe If the `Route` contains an `Appender` definition then an `Appender` will be created within the context of the `RoutingAppender` and will be reused each time a matching `Appender` name is referenced through a `Route`. +[WARNING] +==== +Lookups in the **children** of the `Route` component are **not** evaluated at configuration time. +The substitution is delayed until the `Route` element is evaluated. +This means that `$+{...}+` expression **should not** be escaped as `$$+{...}+`. + +See xref:manual/configuration.adoc#lazy-property-substitution[lazy property substitution] for more details. +==== + This script is passed the following variables: .RoutingAppender Routes Script Parameters diff --git a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc index dafbfeca443..b33897d4ff5 100644 --- a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc @@ -444,7 +444,7 @@ Logger -[#green,thickness=6]-> LoggerConfig : delegates `log()` @enduml .... -[#logger-hiearchy] +[#logger-hierarchy] === Logger hierarchy Log4j Core has a *hierarchical* model of ``LoggerConfig``s, and hence ``Logger``s. diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index fbb82f3a5db..e7264603aba 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -286,6 +286,7 @@ Properties:: include::example$manual/configuration/main-elements.properties[lines=17..-1] ---- ==== + <1> Configures a console appender named `CONSOLE` with a pattern layout. <2> Configures a file appender named `MAIN` with a JSON template layout. <3> Configures a file appender named `DEBUG_LOG` with a pattern layout. @@ -344,6 +345,7 @@ Users can add Components to loggers, appender references, appenders, or the glob + See xref:manual/filters.adoc[Filter configuration] for details. +[#global-properties] Properties:: + Represent a set of reusable configuration values for property substitution. @@ -618,8 +620,8 @@ Loggers can emit additional context data that will be integrated with other cont ==== The `value` of each property is subject to <> twice: -* when the configuration is loaded, -* each time a log event is generated. +* when the configuration is loaded, it is evaluated in the xref:manual/lookups.adoc#global-context[global context]. +* each time a log event is generated, it is evaluated in the xref:manual/lookups.adoc#event-context[context of the event]. Therefore, if you wish to insert a value that changes in time, you must double the `$` sign, as shown in the example below. ==== @@ -771,8 +773,8 @@ If `name` starts with a hyphen `-` (e.g. `-variable`), it must be escaped with a + The most common lookup prefixes are: + -* `sys` for Java system properties (see xref:manual/lookups.adoc#system-properties-lookup[System Properties lookup]), -* `env` for environment variables (see xref:manual/lookups.adoc#environment-lookup[Environment lookup]). +* `sys` for Java system properties (see xref:manual/lookups.adoc#SystemPropertiesLookup[System Properties lookup]), +* `env` for environment variables (see xref:manual/lookups.adoc#EnvironmentLookup[Environment lookup]). The above expansions have a version with an additional `default` value that is **expanded** if the lookup fails: @@ -862,9 +864,8 @@ and the OS environment variable `FOO` has a value of `environment`, Log4j will e [WARNING] ===== For security reasons, if the **expansion** of a `${...}` expression contains other expressions, these will **not** be expanded. -The only exception to this rule is the expansion of properties in the `Properties` container. -Properties defined in the `Properties` container can depend on each other. +Properties defined in the `Properties` container, however, can depend on each other. If your configuration contains, for example: [tabs] @@ -908,26 +909,44 @@ Therefore, the value of the `logging.file` property will be: ===== [id=lazy-property-substitution] -=== Lazy property substitution +=== Runtime property substitution -For most attributes, property substitution is performed only once at **configuration time**, but there are two categories of exceptions to this rule: +For most attributes, property substitution is performed only once at **configuration time**, +but there are exceptions to this rule: some attributes are **also** evaluated when a component-specific event occurs. -* Some attributes are **also** evaluated when a component-specific event occurs. -For example -<> -and the `pattern` attribute of the example below are evaluated at each log event, while the `filePattern` attribute of a -xref:manual/appenders.adoc#rollingfileappender[rolling file appender] -is evaluated at each rollover. -+ In this case: -** If you want property substitution to happen only once, use one dollar sign, e.g., `${date:HH:mm:ss}`. -** If you want property substitution to happen at each cyclic event, you use two dollar signs, e.g., `$${date:HH:mm:ss}` +** If you want property substitution to happen at configuration time, use one dollar sign, e.g., `${date:HH:mm:ss}`. +** If you want property substitution to happen at runtime, you use two dollar signs, e.g., `$${date:HH:mm:ss}` -* Other components defer the evaluation of their child components. -In this case, you only need one dollar `$` sign. -+ -This case happens for the children of the `Route` element below: +The list of attributes that support runtime property substitution is: + +* The `value` attribute of <> of a logger configuration. +* The +xref:manual/pattern-layout.adoc#plugin-attr-pattern[`pattern`] attribute of the xref:manual/pattern-layout.adoc[]. +* Event template attributes of xref:manual/json-template-layout.adoc[]. +See xref:manual/json-template-layout.adoc#property-substitution-in-template[property substitution in JSON Template Layout] +for more details. +* The appender attributes listed in xref:manual/appenders.adoc#runtime-evaluation[runtime property substitution in appenders]. + +[WARNING] +==== +Certain lookups might behave differently when they are expanded at runtime. +See xref:manual/lookups.adoc#evaluation-contexts[lookup evaluation contexts] for details. +==== + +[NOTE] +==== +The +xref:manual/appenders.adoc#Routes[`Route`] component of the +xref:manual/appenders.adoc#RoutingAppender[`RoutingAppender`] +is a different case altogether. +The attributes of its children are expanded at runtime, but are not expanded at configuration time. + +Inside the `Route` component you **should not** use escaped `$$+{...}+` expressions, but only unescaped `$+{...}+` expressions. +==== + +The complete spectrum of behaviors concerning runtime property substitution is given by the routing appender example below: [tabs] ==== @@ -964,9 +983,9 @@ include::example$manual/configuration/routing.properties[tag=appender] ---- ==== -<1> The `pattern` attribute is evaluated at configuration time and also each time a log event is routed. +<1> The `pattern` attribute is evaluated at configuration time, and also each time a log event is routed. Therefore, the dollar `$` sign needs to be escaped. -<2> All the attributes inside the `File` element have a **deferred** evaluation, therefore they need only one `$` sign. +<2> All the attributes of children of the `Route` element have a **deferred** evaluation. Therefore, they need only one `$` sign. [id=arbiters] == [[Arbiters]] Arbiters @@ -1066,6 +1085,7 @@ Properties:: include::example$manual/configuration/arbiters-select.properties[tag=select] ---- ==== + <1> If the Java system property `env` has a value of `dev`, a Pattern Layout will be used. <2> Otherwise, a JSON Template Layout will be used. diff --git a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc index 76aaecb77de..95be2ef55bd 100644 --- a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc @@ -16,69 +16,362 @@ //// = Lookups -Lookups provide a way to add values to the Log4j configuration at -arbitrary places. They are a particular type of Plugin that implements -the -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] -interface. Information on how to use Lookups in configuration files can -be found in the xref:manual/configuration.adoc#PropertySubstitution[Property -Substitution] section of the xref:manual/configuration.adoc[Configuration] -page. +Log4j Core provides a flexible and extensible property substitution system. -[#ContextMapLookup] -== Context Map Lookup +[#StrSubstitutor-diagram] +.Property substitution system +[plantuml] +.... +@startuml +class StrSubstitutor #line.bold { + Interpolator interpolator + String replace(String input) + String replace(LogEvent event, String input) +} -The ContextMapLookup allows applications to store data in the Log4j -ThreadContext Map and then retrieve the values in the Log4j -configuration. In the example below, the application would store the -current user's login id in the ThreadContext Map with the key "loginId". -During initial configuration processing the first '$' will be removed. -The PatternLayout supports interpolation with Lookups and will then -resolve the variable for each event. Note that the pattern -"%X\{loginId}" would achieve the same result. +StrSubstitutor --> Interpolator + +class Interpolator { + StrLookup[] lookups + String lookup(String key) + String lookup(LogEvent event, String key) +} + +Interpolator --> "0..*" StrLookup + +class StrLookup { + String lookup(String input) + String lookup(LogEvent event, String key) +} + +@enduml +.... + +The property substitution system is composed of these elements: + +* A string interpolation engine (xref:manual/architecture.adoc#StrSubstitutor[`StrSubstitutor`]) that evaluates `$+{...}+` expressions. +These expressions can contain recursive expressions and default values. ++ +See xref:manual/configuration.adoc#property-substitution[property substitution] for more details. + +* The +link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/Interpolator.html[`Interpolator`] +that evaluates simple `$\{name}` expressions. ++ +The Interpolator has two functions: + +** If `name` does not contain a colon `:` character, the Interpolator uses the +xref:manual/configuration.adoc#global-properties[`Properties` configuration element] to resolve its value. + +** If `name` is of the form `prefix:key`, the Interpolator delegates the lookup to a `StrLookup` associated with `prefix` and falls back to evaluating `$+{key}+` if the lookup was not successful. + +* A set of +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-StrLookup[`StrLookup`] +plugins, each one associated with a prefix, which retrieve data from external sources. + +`StrLookup` is a simple map-like interface. +The main difference between a map and `StrLookup` is that the latter can compute the value of a key dynamically in a global context or in the context of log event. + +[#common-concerns] +== Common concerns + +[#evaluation-contexts] +=== Evaluation contexts + +Each lookup has an associated prefix, and Log4j can evaluate it in one of the following ways: + +[#global-context] +Global context:: +In a global context Log4j evaluates `$+{prefix:key}+` expressions by calling +link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#lookup(java.lang.String)[`lookup("key")`] +on the lookup associated to `prefix`. +The result of this call only takes into account the global state of the system. ++ +The global context is used to expand the attributes of a +xref:manual/configuration.adoc[configuration file]. + +[#event-context] +Log event context:: +In the context of a log event `event`, Log4j evaluates `$+{prefix:key}+` expressions by calling +link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#lookup(org.apache.logging.log4j.core.LogEvent,java.lang.String)[`lookup(event, "key")`] on the lookup associated to `prefix`. +The result of this call might take into account the contents of the log event, besides the global state of the system. + +Some configuration attributes (e.g., xref:manual/pattern-layout.adoc#plugin-attr-pattern[the `pattern` attribute of Pattern Layout]) supports both evaluation contexts: + +* During the configuration process the `$+{...}+` expressions are evaluated using a global context. +The same process converts escaped `$$+{...}+` expressions to `$+{...}+` expressions. + +* For each log event, the remaining expressions are evaluated, using the log event as context. + +Lookups can choose to react differently depending on the execution context. +<> is such an example: + +* When used in a global context, it formats the **current** timestamp obtained through +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/lang/System.html#currentTimeMillis--[`System.currentTimeMillis()`]. +* When used in the context of an event, it formats the **event** timestamp obtained through +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html#getTimeMillis()[`LogEvent.getTimeMillis()`]. + +[#lookups-patterns] +=== Lazy lookups and pattern converters + +For historical reasons, the +xref:manual/pattern-layout.adoc#plugin-attr-pattern[`pattern` attribute of PatternLayout] +supports two similar string replacement mechanisms: + +* `+${...}+` property expressions. +* xref:manual/pattern-layout.adoc#converters[`%` pattern converters]. + +Both lazy `+$${...}+` property expressions and pattern converters have access to the value of the current `LogEvent` and can provide similar results. +There is, however, an important difference between them: + +* Pattern converters can be garbage-free. +See xref:manual/pattern-layout.adoc#garbage-free[Garbage-free pattern converters] for more details. +* Lazy lookups are **not** garbage-free and always create temporary `String` objects. + +[#collection] +== Collection + +Log4j Core provides many lookups out-of-the-box: + +Lookups operating on the global context:: A large group of lookups supports evaluation in a global context. +These lookups can be safely used in eagerly evaluated properties of a +xref:manual/configuration.adoc[configuration file] +using the `${prefix:key}` syntax: ++ +[#global-context-list] +.Lookups operating on the global context +[cols="1,2m,5"] +|=== +| Prefix | Dependency | Data source + +| <> +| +| A Java +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/ResourceBundle.html[resource bundle] + +| <> +| +| xref:manual/thread-context.adoc[] + +| <> +| +| Current timestamp + +| <> +| log4j-docker +| Docker container + +| <> +| +| Environment variables + +| <> +| +| JVM characteristics + +| <> +| +| JNDI + +| <> +| +| Location of Log4j configuration file + +| <> +| +| It converts the supplied key to lowercase + + +| <> +| +| JVM application arguments + +| <> +| +| Returns `key` if a marker named `key` exists + +| <> +| log4j-spring-boot +| Spring Boot 2.x environment. + +| <> +| +| Java system properties + +| <> +| +| It converts the supplied key to uppercase + +| <> +| log4j-jakarta-web +| Jakarta +https://jakarta.ee/specifications/servlet/6.0/apidocs/jakarta.servlet/jakarta/servlet/servletcontext[`ServletContext`]. + +|=== + +Lookups operating on the log event context:: +The following lookups only support evaluation in the context of a log event or behave differently, when evaluated in such a context: ++ +[#event-context-list] +.Lookups operating on the log event context +[cols="1,2m,5"] +|=== +| Prefix | Dependency | Data source + +| <> +| +| Log event +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html#getContextData()[context data] + +| <> +| +| Log event +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html#getTimeMillis()[timestamp] + +| <> +| +| link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[Log event] + +| <> +| +| xref:manual/messages.adoc#MapMessage[`MapMessage`] + +| <> +| +| Log event +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html#getMarker()[marker] + +| <> +| +| xref:manual/messages.adoc#StructuredDataMessage[`StructuredDataMessage`] + +|=== + +[#ResourceBundleLookup] +=== Resource Bundle Lookup + +[cols="1h,4"] +|=== +| Context | _global_ + +| Syntax +a| `bundle::` + +where: + +`baseName`:: +the base name of a resource bundle (see +https://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html[`ResourceBundle`]). + +`key`:: +the key for the resource string. +|=== + +The Resource Bundle Lookup retrieves strings from Java Resource bundles, e.g.: -[source,xml] ---- - - - %d %p %c{1.} [%t] $${ctx:loginId} %m%n - - +${bundle:org.example.Main:errorMessage} ---- +[TIP] +==== +Do you want to use the values in Spring Boot's `application.properties` file? +Use <> or <> instead. +==== + +[#ContextMapLookup] +=== Context Map Lookup + +[cols="1h,4"] +|=== +| Context | _global_ and _log event_ + +| Syntax +| `ctx:` + +where `` is any `String`. +|=== + +The Context Map Lookup can be used in two different contexts: + +Global context:: +If used in the global context, it uses the +xref:manual/thread-context.adoc[] +to retrieve data. ++ +[WARNING] +==== +When used in this context +xref:manual/thread-context.adoc#custom-ContextDataProvider[custom context data providers] +are not supported. +==== + +Log event context:: +In the context of an event, the Context Map lookup uses the Log event +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html#getContextData()[context map data] +of a log event to resolve the key. +xref:manual/thread-context.adoc#custom-ContextDataProvider[Custom context data providers] are therefore supported. ++ +[TIP] +==== +Don't use `$$+{ctx:key}+` in the xref:manual/pattern-layout.adoc[] conversion patterns! +Use xref:manual/pattern-layout.adoc#converter-thread-context-map[the `%X\{key}` pattern converter] instead. + +See <> for more information. +==== + [#DateLookup] -== Date Lookup +=== Date Lookup -The DateLookup is somewhat unusual from the other lookups as it doesn't -use the key to locate an item. Instead, the key can be used to specify a -date format string that is valid for -https://docs.oracle.com/javase/{java-target-version}/docs/api/java/text/SimpleDateFormat.html[`SimpleDateFormat`]. -The current date, or the date associated with the current log event will -be formatted as specified. +[cols="1h,4"] +|=== +| Context | _global_ and _log event_ -[source,xml] ----- - - - %d %p %c{1.} [%t] %m%n - - - ----- +| Syntax +| `date:` + +where `` is a +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/text/SimpleDateFormat.html[`SimpleDateFormat`] pattern + +|=== + +The Date Lookup formats a timestamp, using the supplied key as format. +The timestamp used depends on the context: + +Global context:: +When used in a global context, the timestamp used is the current system timestamp as returned by +https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#currentTimeMillis--[`System.currentTimeMillis()`]. + +Log event context:: +When used in the context of a log event, the timestamp of the log event is used. ++ +[TIP] +==== +Don't use `$$+{date:format}+` in the xref:manual/pattern-layout.adoc[] conversion patterns! +Use xref:manual/pattern-layout.adoc#converter-date[the `%d\{key}` pattern converter] instead. + +See <> for more information. +==== [#DockerLookup] -== Docker Lookup +=== Docker Lookup [cols="1h,4"] |=== -|Lookup ID |`docker` -|Dependency |xref:log4j-docker.adoc[] +| Context | _global_ + +| Syntax +| `docker:` + +where `` is one of the <>. +| Dependency | xref:log4j-docker.adoc[] |=== Docker Lookup queries https://docs.docker.com/engine/api/[the API of the Docker Engine] running your container. It supports the retrieval of following container attributes: -[%header,cols="1m,4"] +.Docker Lookup supported keys +[%header,cols="1m,4",id=DockerLookup-keys] |=== |Key |Description |containerId |Container ID @@ -89,561 +382,534 @@ It supports the retrieval of following container attributes: |shortImageId |The first 12 characters of the container image ID |=== -[id=environment-lookup] -== [[EnvironmentLookup]] Environment Lookup +Additional runtime dependencies are required for using Docker Lookup: -The EnvironmentLookup allows systems to configure environment variables, -either in global files such as /etc/profile or in the startup scripts -for applications, and then retrieve those variables from within the -logging configuration. The example below includes the name of the -currently logged in user in the application log. +include::partial$manual/dependencies-log4j-docker.adoc[] -[source,xml] ----- - - - %d %p %c{1.} [%t] $${env:USER} %m%n - - ----- +[#EnvironmentLookup] +=== Environment Lookup + +[cols="1h,4"] +|=== +| Context | _global_ -This lookup also supports default value syntax. In the sample below, -when the `USER` environment variable is undefined, the default value -`jdoe` is used: +| Syntax +| `env:` + +where `` is any `String` +|=== + +The Environment Lookup retrieves the value of the +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/lang/System.html#getenv-java.lang.String-[OS environment variable] +associated with the key. -[source,xml] ----- - - - %d %p %c{1.} [%t] $${env:USER:-jdoe} %m%n - - ----- [#EventLookup] -== Event Lookup +=== Event Lookup + +[cols="1h,4"] +|=== +| Context | _log event_ -The EventLookup provides access to fields within the log event from the configuration. +| Syntax +| `event:` -[cols="1m,4a"] +where `` is one of the <>. +|=== + +The Event Lookup provides access to fields of the current log event. +It supports the retrieval of the following event attributes: + +.Event Lookup supported keys +[cols="1m,4a",id=EventLookup-keys] |=== |Key |Description |Exception -|Returns the simple class name of the Exception, if one is included in the event. +|Simple class name of the exception, if one is present. |Level -|Returns the logging Level of the event. +|xref:manual/customloglevels.adoc[Logging level] of the event |Logger -|Returns the name of the Logger. +|Name of the logger |Marker -|Returns the name of the Marker associated with the log event, if one is present. +|xref:manual/markers.adoc[Marker] associated with the log event, if one is present. |Message -|Returns the formatted Message string. +|Formatted xref:manual/messages.adoc[`Message`] |ThreadId -|Returns the thread id associated with the log event. +|Thread id associated with the log event |ThreadName -|Returns the name of the thread associate with the log event. +|Name of the thread associated with the log event |Timestamp -|Returns the time in milliseconds when the event occurred. - +|UNIX timestamp in milliseconds of the log event |=== -In this example the RoutingAppender picks a route based on the presence of a Marker named "AUDIT" being -present in the log event. -[source,xml] ----- - - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - ----- +[TIP] +==== +Don't use `$$+{event:key}+` in the xref:manual/pattern-layout.adoc[] conversion patterns! +There is a xref:manual/pattern-layout.adoc#converters[specialized pattern converter replacement] for each of these lookups. + +See <> for more information. +==== [#JavaLookup] -== Java Lookup +=== Java Lookup -The JavaLookup allows Java environment information to be retrieved in -convenient preformatted strings using the `java:` prefix. +[cols="1h,4"] +|=== +| Context | _global_ -[cols="1m,4a"] +| Syntax +| `java:` + +where `` is one of the <>. |=== -|Key |Description -|version -|The short Java version, like: +The Java Lookup allows retrieving information about the Java environment the application is using. +The following keys are supported -`Java version 1.7.0_67` +.Java Lookup supported keys +[cols="1m,2,6m",id=JavaLookup-keys] +|=== +|Key |Description |Example -|runtime -|The Java runtime version, like: +|version +|Short Java version +|Java version 21.0.3 -`Java(TM) SE Runtime Environment (build 1.7.0_67-b01) from Oracle Corporation` +|runtime +|Java runtime version +|OpenJDK Runtime Environment (build 21.0.3+9-LTS) from Eclipse Adoptium |vm -|The Java VM version, like: - -`Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)` +|Java VM version +|OpenJDK 64-Bit Server VM (build 21.0.3+9-LTS, mixed mode, sharing) |os -|The OS version, like: - -`Windows 7 6.1 Service Pack 1, architecture: amd64-64` +|OS version +|Linux 6.1.0-18-amd64, architecture: amd64-64 |locale -|Hardware information, like: - -`default locale: en_US, platform encoding: Cp1252` +|System locale and file encoding +|default locale: en_US, platform encoding: UTF-8 |hw -|System locale and file encoding information, like: - -`processors: 4, architecture: amd64-64, instruction sets: amd64` +|Hardware information +|processors: 32, architecture: amd64-64, instruction sets: amd64` |=== -For example: +[#JndiLookup] +=== JNDI Lookup -[source,xml] ----- - - - %d %m%n - - ----- +[cols="1h,4"] +|=== +| Context | _global_ -[#JndiLookup] -== JNDI Lookup +| Syntax +| `jndi:` -As of Log4j 2.15.1 JNDI operations require that `log4j2.enableJndi=true` be set as a system property or the -corresponding environment variable for this lookup to function. See the -xref:manual/systemproperties.adoc#log4j2.enableJndiLookup[`log4j2.enableJndiLookup`] system property. +where `` is a JNDI https://docs.oracle.com/javase/{java-target-version}/docs/api/javax/naming/Name.html[`Name`]. +|=== -The JndiLookup allows variables to be retrieved via JNDI. By default the -key will be prefixed with java:comp/env/, however if the key contains a -":" no prefix will be added. +[IMPORTANT] +==== +As of Log4j `2.17.0` you need to enable the JNDI lookup **explicitly** by setting the +xref:manual/systemproperties.adoc#log4j2.enableJndiLookup[`log4j2.enableJndiLookup`] +configuration property to `true`. +==== -By default the JNDI Lookup only supports the java, ldap, and ldaps protocols or no protocol. Additional -protocols may be supported by specifying them on the ``log4j2.allowedJndiProtocols`` property. -When using LDAP Java classes that implement the Referenceable interface are not supported for security -reasons. Only the Java primative classes are supported by default as well as any classes specified by the -``log4j2.allowedLdapClasses`` property. When using LDAP only references to the local host name -or ip address are supported along with any hosts or ip addresses listed in the -``log4j2.allowedLdapHosts`` property. +The JNDI Lookup retrieves the value of an environment entry from JNDI. +Only the `java:` protocol is supported. +If the key does not have a protocol, `java:comp/env` is prepended. -[source,xml] +As an example, to retrieve the value of `java:comp/env/app_name` you can use: + +[source] ---- - - - %d %p %c{1.} [%t] $${jndi:logging/context-name} %m%n - - +$${jndi:app_name} ---- -*Java's JNDI module is not available on Android.* +[NOTE] +==== +Android does not support JNDI. +==== -[#JmxRuntimeInputArgumentsLookup] -== JVM Input Arguments Lookup (JMX) +[#Log4jLookup] +=== Configuration Location Lookup -Maps JVM input arguments -- but not _main_ arguments -- using JMX to -acquire the JVM arguments. +[cols="1h,4"] +|=== +| Context | _global_ -Use the prefix `jvmrunargs` to access JVM arguments. +| Syntax +| `log4j:` -See the Javadocs for -https://docs.oracle.com/javase/{java-target-version}/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[`java.lang.management.RuntimeMXBean.getInputArguments()`]. +where `` is one of the <>. +|=== -*Java's JMX module is not available on Android or on Google App Engine.* +The Configuration Location Lookup supports two keys: -[#KubernetesLookup] -== Kubernetes Lookup +.Configuration Location Lookup supported keys +[cols="1m,4",id=Log4jLookup-keys] +|=== +|Key |Description -[cols="1h,4"] +|configLocation +|Returns the location of the configuration file as an absolute file path or URI. + +|configParentLocation +|Returns the location of the folder containing the configuration file as an absolute file path or URI. |=== -|Lookup ID |`k8s` -|Dependency |{log4j-kubernetes-url}[Log4j Kubernetes of Fabric8] + +[#LowerLookup] +=== Lower Lookup + +[cols="1h,4"] |=== +| Context | _global_ -Kubernetes Lookup queries https://kubernetes.io/docs/concepts/overview/kubernetes-api/[the Kubernetes API] to retrieve certain information about the current container and its environment. -Kubernetes Lookup is distributed as a part of Fabric8's Kubernetes Client, refer to {log4j-kubernetes-url}[its website] for details. +| Syntax +| `lower:` -[#Log4jConfigLookup] -== Log4j Configuration Location Lookup +where `` is any `String`. +|=== -Log4j configuration properties. The expressions -`${log4j:configLocation}` and `${log4j:configParentLocation}` -respectively provide the absolute path to the log4j configuration file -and its parent folder. +The Lower Lookup converts the passed in argument to lowercase. -The example below uses this lookup to place log files in a directory -relative to the log4j configuration file. +Presumably, the value will be the result of a nested lookup as in the example: -[source,xml] +[source] ---- - - - %d %p %c{1.} [%t] %m%n - - +${lower:${sys:appname}} ---- -[#LowerLookup] -== Lower Lookup +[#MainMapLookup] +=== Main Arguments Lookup + +[cols="1h,4"] +|=== +| Context | _global_ -The LowerLookup converts the passed in argument to lower case. Presumably the value will be the -result of a nested lookup. +| Syntax +| `main:` -[source,xml] ----- - - - %d %p %c{1.} [%t] $${lower:${spring:spring.application.name}} %m%n - - ----- +wherre `` either a non-negative `int` or a `String`. +|=== -[#AppMainArgsLookup] -== Main Arguments Lookup (Application) +[IMPORTANT] +==== +This lookup requires a setup step: +your application needs to call +link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/MainMapLookup.html#setMainArguments(java.lang.String...)[`MainMapLookup#setMainArguments()`] +and pass as argument the arguments received by the application. +==== + +The Main Arguments Lookup provides a way to query the arguments received by your application. +It supports two kinds of keys: + +* if the key is an integer, e.g. `${main:0}`, it is interpreted as 0-based index in the argument array. +* if the key is a `String`, e.g. `${main:foo}`, the argument that follows `foo` in the argument array is returned. + +.Lookup results for "foo bar baz" arguments +[cols="1m,1m"] +|=== +| Lookup | Expansion +| ${main:0} | foo +| ${main:1} | bar +| ${main:2} | baz +| ${main:foo} | bar +| ${main:bar} | baz +|=== -This lookup requires that you manually provide the main arguments of the -application to Log4j: +You can use this lookup to provide a primitive argument parsing mechanism to your application: -[source,java] +* First, you need to pass your application's arguments to the `MainMapLookup#setMainArguments` method: ++ +[source,java,indent=0] ---- -import org.apache.logging.log4j.core.lookup.MainMapLookup; -public class Main { - public static void main(String[] args) { - MainMapLookup.setMainArguments(args); - // ... - } -} +include::example$manual/lookups/MainArgsExample.java[tag=usage] ---- ++ +<1> Use an **instance** logger field instead of a static one, to prevent Log4j Core initialization before `main()` is called. +<2> Call `MainMapLookup#setMainArguments` by reflection to allow your application to run with a different Log4j API implementation. -If the main arguments have been set, this lookup allows applications to -retrieve these main argument values from within the logging -configuration. The key that follows the `main:` prefix can either be a -0-based index into the argument list, or a string, where -`${main:myString}` is substituted with the value that follows `myString` -in the main argument list. +* Now you can use `$+{main:...}+` lookups in your configuration file to support the usage of a `--logfile ` CLI argument to specify the log file and `--loglevel ` CLI argument to specify the log level. ++ +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/lookups/mainArgs.xml[lines=1;18..-1] +---- -Note: Many applications use leading dashes to identify command arguments. Specifying -`${main:--file}` would result in the lookup failing because it would look for a variable -named "main" with a default value of "-file". To avoid this the ":" separating the Lookup name from the -key must be followed by a backslash as an escape character as in `${main:\--file}`. +JSON:: ++ +[source,json] +---- +include::example$manual/lookups/mainArgs.json[] +---- -For example, suppose the static void main String[] arguments are: +YAML:: ++ +[source,yaml] +---- +include::example$manual/lookups/mainArgs.yaml[lines=17..-1] +---- -.... ---file foo.txt --verbose -x bar -.... +Properties:: ++ +[source,properties] +---- +include::example$manual/lookups/mainArgs.properties[lines=18..-1] +---- +==== ++ +<1> Provide default values for the CLI arguments if they are not specified. +<2> Escape the special `:-` sequence using `:\-`. -Then the following substitutions are possible: +[#MapLookup] +=== Map Lookup -[cols="m,m"] +[cols="1h,4"] |=== -|Expression |Result +| Context | _log event_ -|${main:0} -|--file +| Syntax +| `map:` -|${main:1} -|foo.txt +where `` is any `String`. +|=== -|${main:2} -|--verbose +The Map Lookup retrieves the value assigned to the given key in a +xref:manual/messages.adoc#MapMessage[`MapMessage`]. -|${main:3} -|-x +[TIP] +==== +Don't use `$$+{map:key}+` in the xref:manual/pattern-layout.adoc[] conversion patterns! +Use xref:manual/pattern-layout.adoc#converter-map[the `%K\{key}` pattern converter] instead. -|${main:4} -|bar +See <> for more information. +==== -|${main:\--file} -|foo.txt +[#MarkerLookup] +=== Marker Lookup -|${main:\-x} -|bar +[cols="1h,4"] +|=== +| Context | _global_ or _log event_ -|${main:bar} -|null +| Syntax +| `marker:` -|${main:\--quiet:-true} -|true +where `` is any `String` |=== -Example usage: +The Marker Lookup can be used in two different ways: -[source,xml] +Global context:: +When used in a global context, it returns `key` if there is a marker named `key` or `null` otherwise. +For example: ++ ---- - - - %d %m%n - - +${marker:AUDIT:-NO_AUDIT} ---- ++ +will expand to `AUDIT` if a marker with that name exists or `NO_AUDIT` otherwise. + +Log event context:: +When used in the context of a log event, it returns the +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[log event marker] if it exists. ++ +[TIP] +==== +Don't use `$$+{marker:}+` in the xref:manual/pattern-layout.adoc[] conversion patterns! +Use xref:manual/pattern-layout.adoc#converter-marker[the `%markerSimpleName` pattern converter] instead. -[#MapLookup] -== Map Lookup - -The MapLookup serves several purposes. - -1. Provide the base for Properties declared in the configuration file. -2. Retrieve values from MapMessages in LogEvents. -3. Retrieve values set with -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String%5B%5D%29[`MapLookup.setMainArguments(String[])`] - -The first item simply means that the MapLookup is used to substitute -properties that are defined in the configuration file. These variables -are specified without a prefix - e.g. `$\{name}`. The second usage allows -a value from the current -link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[`MapMessage`], -if one is part of the current log event, to be substituted. In the -example below the RoutingAppender will use a different -RollingFileAppender for each unique value of the key named "type" in the -MapMessage. Note that when used this way a value for "type" should be -declared in the properties declaration to provide a default value in -case the message is not a MapMessage or the MapMessage does not contain -the key. See the xref:manual/configuration.adoc#PropertySubstitution[Property -Substitution] section of the xref:manual/configuration.adoc[Configuration] -page for information on how to set the default values. +See <> for more information. +==== -[source,xml] ----- - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - ----- +[#SpringBootLookup] +=== Spring Boot 2 Lookup -[#marker-lookup] -== Marker Lookup +[cols="1h,4"] +|=== +| Context | _global_ -The marker lookup allows you to use markers in interesting -configurations like a routing appender. Consider the following YAML -configuration and code that logs to different files based on markers: +| Syntax +| `spring:` -[source,yaml] ----- -Configuration: - status: debug - - Appenders: - Console: - RandomAccessFile: - - name: SQL_APPENDER - fileName: logs/sql.log - PatternLayout: - Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n" - - name: PAYLOAD_APPENDER - fileName: logs/payload.log - PatternLayout: - Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n" - - name: PERFORMANCE_APPENDER - fileName: logs/performance.log - PatternLayout: - Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n" - - Routing: - name: ROUTING_APPENDER - Routes: - pattern: "$${marker:}" - Route: - - key: PERFORMANCE - ref: PERFORMANCE_APPENDER - - key: PAYLOAD - ref: PAYLOAD_APPENDER - - key: SQL - ref: SQL_APPENDER - - Loggers: - Root: - level: trace - AppenderRef: - - ref: ROUTING_APPENDER ----- +where `` is one of the <>. -[source,java] ----- -public static final Marker SQL = MarkerFactory.getMarker("SQL"); -public static final Marker PAYLOAD = MarkerFactory.getMarker("PAYLOAD"); -public static final Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE"); +| Dependency | xref:log4j-spring-boot.adoc[] +|=== -final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); +[IMPORTANT] +==== +If you are using Spring Boot 2, you should use the third party <> instead. +==== -logger.info(SQL, "Message in Sql.log"); -logger.info(PAYLOAD, "Message in Payload.log"); -logger.info(PERFORMANCE, "Message in Performance.log"); ----- +The Spring Boot 2 Lookup allows user to query Spring Boot's +https://docs.spring.io/spring-boot/reference/features/external-config.html[externalized configuration files]. +It supports the following keys: -Note the key part of the configuration is `pattern: "$${marker:}"`. This -will produce three log files, each with a log event for a specific -marker. Log4j will route the log event with the `SQL` marker to -`sql.log`, the log event with the `PAYLOAD` marker to `payload.log`, and -so on. +.Spring Boot 2 Lookup supported keys +[cols="1m,4",id=SpringBootLookup-keys] +|=== +|Key |Description -You can use the notation `"${marker:name}"` and `"$${marker:name}"` to -check for the existence of a marker where `name` is the marker name. If -the marker exists, the expression returns the name, otherwise `null`. +|profiles.active +|Comma-separated list of active profiles. -== Resource Bundle Lookup -The resource bundle lookup retrieves values from Resource Bundles (see Java documentation). The format is `${bundle:BundleName:BundleKey}`. The bundle name follows package naming conventions, for example: `${bundle:com.domain.Messages:MyKey}`. +|profiles.active[] +|The active profile with 0-based index ``. -[source, xml] ----- - - -%d %p %c{1.} [%t] $${bundle:MyBundle:MyKey} %m%n - - ----- +|profiles.default +|Comma-separated list of default profiles. -== Spring Boot Lookup -The Spring Boot Lookup retrieves the values of Spring properties from the Spring configuration as well as values of the active and default profiles. Specifying a key of "profiles.active" will return the active profiles while a key of "profiles.default" will return the default profiles. The default and active profiles can be an array. If more than one profile is present they will be returned as a comma separated list. To retrieve a single item from the array append "[\{index}]" to the key. For example, to return the first active profile in the list specify "profiles.active[0]". +|profiles.default[] +|The default profile with 0-based index ``. -This Lookup will return null values until Spring Boot initializes application logging. The Spring Boot Lookup requires the log4j-spring-boot jar be included as a dependency. +| +|The value associated with `` in Spring's +https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/env/Environment.html[`Environment`]. +|=== -[source, xml] ----- - - -%d %p %c{1.} [%t] $${spring:spring.application.name} %m%n - - ----- +[WARNING] +==== +Spring Boot 2 initializes Log4j Core at least **twice**: + +* Log4j Core is initialized the first time using +xref:manual/configuration.adoc#automatic-configuration[its own automatic configuration procedure]. +At this point, the lookup will always return `null`. +Configuration files that use the standard `log4j2.` naming convention, should provide default values for all Spring lookups. + +* As soon as Spring's `Environment` is ready, the lookup becomes **available** and a reconfiguration is triggered. +If you want to provide a configuration file specifically for this phase, call it `log4j2-spring.`. +==== + +Additional runtime dependencies are required for using Spring Boot Lookup: -This Lookup requires log4j-spring-cloud-config-client be included in the application. +include::partial$manual/dependencies-log4j-spring-boot.adoc[] [#StructuredDataLookup] -== Structured Data Lookup +=== Structured Data Lookup -The StructuredDataLookup is very similar to the MapLookup in that it -will retrieve values from StructuredDataMessages. In addition to the Map -values it will also return the name portion of the id (not including the -enterprise number) and the type field. The main difference between the -example below and the example for MapMessage is that the "type" is an -attribute of the -link:../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html[`StructuredDataMessage`] -while "type" would have to be an item in the Map in a MapMessage. +[cols="1h,4"] +|=== +| Context | _log event_ -[source,xml] ----- - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - ----- +| Syntax +| `sd:` -[id=system-properties-lookup] -== [[SystemPropertiesLookup]] System Properties Lookup +where `` is either one of the <> or any `String` +|=== -As it is quite common to define values inside and outside the -application by using System Properties, it is only natural that they -should be accessible via a Lookup. As system properties are often -defined outside the application it would be quite common to see -something like: +The Structured Data Lookup is very similar to <> and retrieves the value assigned to the given key in a +xref:manual/messages.adoc#StructuredDataMessage[`StructuredDataMessage`]. +Additionally, the following virtual keys are supported: -[source,xml] ----- - - - ----- +.Structured Data Lookup virtual keys +[cols="1m,1,4",id=StructuredDataLookup-keys] +|=== +| Key | RFC5424 field | Description -This lookup also supports default value syntax. In the sample below, -when the `logPath` system property is undefined, the default value -`/var/logs` is used: +| id +| https://datatracker.ietf.org/doc/html/rfc5424#section-6.3.2[`SD-ID`] +| The +link:../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html#getId()[`id` field] +of the `StructuredDataMessage`. -[source,xml] ----- - - - ----- +| type +| https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.7[`MSGID`] +| The +link:../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html#getType()[`type` field] +of a `StructuredDataMessage`. + +|=== + +[TIP] +==== +Except `++$${sd:id}++` and `++$${sd:type}++`, don't use other `++$${sd:key}++` expressions in the xref:manual/pattern-layout.adoc[] conversion patterns! +Use xref:manual/pattern-layout.adoc#converter-map[the `%K\{key}` pattern converter] instead. + +See <> for more information. +==== + +[#SystemPropertiesLookup] +=== System Properties Lookup + +[cols="1h,4"] +|=== +| Context | _global_ + +| Syntax +| `sys:` + +where `` is any `String` +|=== + +The System Properties Lookup retrieves the value of the +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/lang/System.html#getProperties--[Java system property] +associated with the key. [#UpperLookup] -== Upper Lookup +=== Upper Lookup -The LowerLookup converts the passed in argument to upper case. Presumably the value will be the -result of a nested lookup. +[cols="1h,4"] +|=== +| Context | _global_ -[source,xml] +| Syntax +| `upper:` + +where `` wi any `String` +|=== + +The Upper Lookup converts the passed in argument to uppercase. + +Presumably, the value will be the result of a nested lookup as in the example: + +[source] ---- - - - %d %p %c{1.} [%t] $${upper:{${spring:spring.application.name}} %m%n - - +${upper:${sys:appname}} ---- [#WebLookup] -== Web Lookup +=== Web Lookup -The WebLookup allows applications to retrieve variables that are -associated with the ServletContext. In addition to being able to -retrieve various fields in the ServletContext, WebLookup supports -looking up values stored as attributes or configured as initialization -parameters. The following table lists various keys that can be -retrieved: +[cols="1h,4"] +|=== +| Context | _global_ + +| Syntax +| `web:` + +where `` is one of the <>. + +| Dependency | `log4j-jakarta-web` +|=== + +The Web Lookup allows applications to retrieve variables that are associated with the Jakarta +https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/servlet/servletcontext[`ServletContext`] +of the web application. + +The following table lists various keys that can be retrieved: -[cols="1m,4"] +.Web Lookup supported keys +[cols="1m,4",id=WebLookup-keys] |=== |Key |Description -|attr._name_ -|Returns the ServletContext attribute with the specified name +|attr. +|Returns the `ServletContext` attribute with the specified ``. |contextPath |The context path of the web application @@ -659,8 +925,8 @@ represented by this ServletContext is based on. |Gets the minor version of the Servlet specification that the application represented by this ServletContext is based on. -|initParam._name_ -|Returns the ServletContext initialization parameter with the specified name +|initParam. +|Returns the ServletContext initialization parameter with the specified ``. |majorVersion |Returns the major version of the Servlet API that this servlet container supports. @@ -676,12 +942,12 @@ represented by this ServletContext is based on. |servletContextName |Returns the name of the web application as defined in the display-name element of the deployment descriptor + +| +|Return the first of `attr.` and `initParam.` that is defined. |=== -Any other key names specified will first be checked to see if a -ServletContext attribute exists with that name and then will be checked -to see if an initialization parameter of that name exists. If the key is -located then the corresponding value will be returned. +Using the Web Lookup, you can, for example, place the log file in the application's root directory: [source,xml] ---- @@ -694,6 +960,42 @@ Additional runtime dependencies are required for using web lookup: include::partial$manual/dependencies-log4j-jakarta-web.adoc[] +[#third-party] +== Third-party lookups + +The following additional lookups are available from third-party vendors: + +[#KubernetesLookup] +=== Kubernetes Lookup + +[cols="1h,4"] +|=== +| Syntax | `k8s:` +| Dependency | {log4j-kubernetes-url}[Log4j Kubernetes of Fabric8] +|=== + +Kubernetes Lookup queries https://kubernetes.io/docs/concepts/overview/kubernetes-api/[the Kubernetes API] to retrieve certain information about the current container and its environment. +Kubernetes Lookup is distributed as a part of Fabric8's Kubernetes Client, refer to {log4j-kubernetes-url}[its website] for details. + +[#SpringBootLookup3] +=== Spring Boot 3 Lookup + +[cols="1h,4"] +|=== +| Syntax | `spring:` +| Dependency | _integrated in Spring Boot 3_ +|=== + +Starting with Spring Boot 3 a `$+{spring:...}+` lookup is available out-of-the-box. +https://docs.spring.io/spring-boot/reference/features/logging.html#features.logging.log4j2-extensions.environment-properties-lookup[Spring Boot documentation] +for more details. + +[WARNING] +==== +The Spring Boot 3 Lookup conflicts with the <<#SpringBootLookup>>. +If you are upgrading to Spring Boot 3, make sure to remove the latter from your classpath. +==== + [#extending] == Extending @@ -720,7 +1022,7 @@ While annotating your lookup with `@Plugin`, you need to make sure that * It has a unique `name` attribute across all available `StrLookup` plugins * The `category` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#CATEGORY[`StrLookup.CATEGORY`] -You can check out following files for examples: +You can check out the following files for examples: * {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DateLookup.java[`LowerLookup.java`] – <> lower-cases its input * {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EventLookup.java[`EventLookup.java`] – <> extracts specified fields from the effective `LogEvent` in the context 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 5a6d655e2a2..d6795079c1a 100644 --- a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc @@ -135,6 +135,11 @@ Pattern Layout plugin configuration accepts the following attributes: A composite pattern string of one or more <>. `pattern` and <> are mutually exclusive, that is, only one can be specified. +This attribute supports +xref:manual/configuration.adoc#lazy-property-substitution[runtime property substitution] +using an +xref:manual/lookups.adoc#event-context[event evaluation context]. + [WARNING] ==== If the provided pattern does not contain an exception converter and <> is not disabled, an implicit <> is appended to the pattern. diff --git a/src/site/antora/modules/ROOT/partials/manual/dependencies-log4j-docker.adoc b/src/site/antora/modules/ROOT/partials/manual/dependencies-log4j-docker.adoc new file mode 100644 index 00000000000..d59733aea24 --- /dev/null +++ b/src/site/antora/modules/ROOT/partials/manual/dependencies-log4j-docker.adoc @@ -0,0 +1,39 @@ +//// + 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. +//// + +[tabs] +==== +Maven:: ++ +[source,xml] +---- + + + org.apache.logging.log4j + log4j-docker + runtime + +---- + +Gradle:: ++ +[source,groovy] +---- +// We assume you use `log4j-bom` for dependency management +runtimeOnly 'org.apache.logging.log4j:log4j-docker' +---- +==== diff --git a/src/site/antora/modules/ROOT/partials/manual/dependencies-log4j-spring-boot.adoc b/src/site/antora/modules/ROOT/partials/manual/dependencies-log4j-spring-boot.adoc new file mode 100644 index 00000000000..f98da777c5f --- /dev/null +++ b/src/site/antora/modules/ROOT/partials/manual/dependencies-log4j-spring-boot.adoc @@ -0,0 +1,39 @@ +//// + 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. +//// + +[tabs] +==== +Maven:: ++ +[source,xml] +---- + + + org.apache.logging.log4j + log4j-spring-boot + runtime + +---- + +Gradle:: ++ +[source,groovy] +---- +// We assume you use `log4j-bom` for dependency management +runtimeOnly 'org.apache.logging.log4j:log4j-spring-boot' +---- +====