From 47ce519a7f37dcc8c2624eea0658c6a576bf4617 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 30 Apr 2024 13:59:38 +0200 Subject: [PATCH 01/24] New configuration page --- .../modules/ROOT/pages/manual/appenders.adoc | 8 +- .../ROOT/pages/manual/configuration.adoc | 2118 +++-------------- .../ROOT/pages/manual/configuration_old.adoc | 1719 +++++++++++++ .../ROOT/pages/manual/installation.adoc | 72 +- .../modules/ROOT/pages/manual/layouts.adoc | 4 +- .../modules/ROOT/pages/manual/migration.adoc | 2 +- .../modules/ROOT/pages/manual/webapp.adoc | 1 + .../configuration-file-format-deps.adoc | 88 + 8 files changed, 2161 insertions(+), 1851 deletions(-) create mode 100644 src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc create mode 100644 src/site/antora/modules/ROOT/partials/configuration-file-format-deps.adoc diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index f473f73483e..72b579961c8 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -339,8 +339,8 @@ CREATE TABLE logs ( ); ---- -[#ConsoleAppender] -== ConsoleAppender +[id=consoleappender] +== [[ConsoleAppender]] ConsoleAppender As one might expect, the ConsoleAppender writes its output to either System.out or System.err with System.out being the default target. A @@ -466,8 +466,8 @@ A Failover configuration might look like: ---- -[#FileAppender] -== FileAppender +[id=fileappender] +== [[FileAppender]] FileAppender The FileAppender is an OutputStreamAppender that writes to the File named in the fileName parameter. The FileAppender uses a FileManager diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 66a6b516881..e8fc3615de5 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -14,1856 +14,428 @@ See the License for the specific language governing permissions and limitations under the License. //// -[#configuration] = Configuration -Ralph Goers -Inserting log requests into the application code requires a fair amount -of planning and effort. Observation shows that approximately 4 percent -of code is dedicated to logging. Consequently, even moderately sized -applications will have thousands of logging statements embedded within -their code. Given their number, it becomes imperative to manage these -log statements without the need to modify them manually. +Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. -Configuration of Log4j 2 can be accomplished in 1 of 4 ways: +In order to decide which of these statements will be logged and where, users need to configure Log4j Core. -1. Through a configuration file written in XML, JSON, YAML, or -properties format. -2. Programmatically, by creating a ConfigurationFactory and -Configuration implementation. -3. Programmatically, by calling the APIs exposed in the Configuration -interface to add components to the default configuration. -4. Programmatically, by calling methods on the internal Logger class. +Log4j Core can be configured in two ways: -This page focuses primarily on configuring Log4j through a configuration -file. Information on programmatically configuring Log4j can be found at -xref:manual/extending.adoc[Extending Log4j 2] and -xref:manual/customconfig.adoc[Programmatic Log4j Configuration]. +* through a <>. +Since version 2.0 the configuration file format is considered as part of the public API, and it remains stable even across major version upgrades. -All available formats are functionally equivalent. For example, a -configuration file in XML can be rewritten using the properties format -(and the opposite) without any loss of functionality. However, the -hierarchical nature of a Log4j configuration can be captured better in -formats which naturally support nesting so XML, JSON, and YAML files, -are usually easier to use. +* through <>, which provides a larger spectrum of possible customizations, but might require code changes even for minor version upgrades, according to https://semver.org/[semantic versioning] rules. -Note that unlike Log4j 1.x, the public Log4j 2 API does not expose -methods to add, modify or remove appenders and filters or manipulate the -configuration in any way. +[NOTE] +==== +To prevent a chicken-and-egg problem some configuration options, such as the location of the configuration file can be supplied only through <>. +==== -[#Architecture] -== Architecture +[#log4j-core-configuration-file] +== Configuration file -In part because support for XML was added first, Log4j's configuration is reflected as a tree structure. -In fact every configuration dialect, including the ConfigurationBuilder, generates a Node for every -configuration element. A node is a fairly simple structure that contains a set of attributes, a set of -child nodes and a PluginType. It is important to note that every Node must have a corresponding plugn, -as the plugin is the component that actually performs the work represented by the node. +TIP: For a quick example of configuration file see the xref:manual/installation.adoc#impl-core-config[Configuring Log4j Core section]. -Every document type supported by Log4j has a ConfigurationFactory. The factory itself is a Log4j plugin -that declares what file extensions it supports and what its priority is. Properties have the highest -precedence with a value of 8, followed by yaml, json and xml. When autoconfiguration is performed Log4j -will call each of these factories in order to determine which, if any, support the specified configuration -file format. If one is found that factory will create the corresponding Configuratoin object and pass the -reference to the configuration data to it. +Log4j Core can be configured using multiple configuration file formats. +Configuration factories for the XML, JSON, YAML and Java properties format are included in the `log4j-core` artifact. -Every configuration implementation, such as XMLConfiguration, YamlConfiguration, JsonConfiguration, etc. -has the primary task of converting the configuration text into the Node tree, typically by parsing the -text with whatever tool is available for that document type. It should be noted that while most of the -supported document types are inherintly tree structured, the Java properties syntax is not. Because of the -need to convert the syntax into a Node tree the Java properties syntax used by Log4j required all properties -follow a naming pattern that made the tree structure clear. As a consequence, the Java Properties format -tends to be more verbose than using a different document type. +Some configuration formats require additional dependencies to be present on the classpath, according to the table below. -Once the Node tree is created control is delegated to AbstractConfiguration, which convertes the Nodes into -their respective Java objects using Log4j's Plugin system and provides all the common functionality. +include::partial$configuration-file-format-deps.adoc[] -[#Arbiters] -== Arbiters +[WARNING] +==== +The format of the configuration file changed between Log4j{nbsp}1 and Log4j{nbsp}2. +Files in the Log4j{nbsp}1 formats are ignored by default. -In some situations it is desirable to have a single logging configuration that can be used in any -deployment environment. For example, it may be necessary to have a different default logging level in -production then in development. Another case might be where one type of appender is used when running -natively but another is used when deployed to a docker container. One way to handle that is to use -a tool such as Spring Cloud Config Server that can be environment aware and serve a different file for -each environment. Another option is to include Arbiters in the configuration. +To enable partial support for old configuration formats see xref:manual/migration.adoc#enabling-the-log4j-1-x-bridge[Enabling the Log4j{nbsp}1 bridge]. +==== -An Arbiter is a Log4j plugin that has the job of determining whether other configured elements should be -included in the generated configuration. While all other "Core" plugins are designed to execute as part of -Log4j's runtime logic Arbiters execute after the Node tree has been constructed but before the tree is -converted to a configuration. An Arbiter is a Node itself which is always removed from the Node tree -before it the tree is processed. All an arbiter really does is provide a method that returns a boolean -result that determines whether the child nodes of the arbiter should remain in the configuration or be -pruned. +[id=automatic-configuration] +=== Configuration file location -Arbiters may occur anywhere an element is allowed in the configuration. So an Aribiter could encapsulate -something as simple as a single property declaration or a whole set of Appenders or Loggers. Arbiters -may also be nested although Arbiters that are the descendant of another arbiter will only be evalued if the -ancestor returned true. The child elements of an Arbiter must be valid elements for whatever element is -the parent of the Arbiter. +Upon initialization of a new logger context, Log4j assigns it a context name and scans the following **classpath** locations for a configuration file: -This example shows two Arbiters configured that will include either a Console Appender or a List Appender -depending on whether the value of the env System Property is "dev" or "prod". +. Files named `log4j2-test.` +. Files named `log4j2-test.`, +. Files named `log4j2.` +. Files named `log4j2.`, +. If no configuration file could be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. +The default configuration prints all messages less specific than <> to the console. -[source,xml] ----- - - - - - - - - - - - - - - - - - - - - - - - ----- - -Normally Arbiters act in isolation from other Arbiters. That is, the outcome of one Arbiter will not -impact any other Arbiters. This can be cumbersome when you simply want to use one of a set of choices. A -special plugin named "Select" can be used in this case. Each element under the Select is required to be -an Arbiter. The first Arbiter that returns a true value will be the one used while others are ignored. -If no Arbiter returns true a DefaultAtrbiter may be configured with the default configuration elements. -The DefaultArbiter is an Arbiter that always returns true, so using it outside of a Select would result in -its configured elements always being included just as if it hadn't been present. - -This example shows an Arbiter that uses Javascript residing in a separate file to determine whether to -include the Console Appender. If the result is false then a List Appender will be included. +The `` and `` placeholders above have the following meaning -[source,xml] ----- - - - - - - - - - - - - - ----- - -Natively Log4j contains the SystemProperty Arbiter that can evaluate whether to include elements based on -whether a SystemProperty is non-null or has a specific value, a ClassArbiter that makes its decision -based on whether the specified class is present, and a ScriptArbiter that makes its decision based -on the result of the script configured with it. +:: depends on the runtime environment in which Log4j runs: -For Spring Boot users an Arbiter named SpringProfile has been provided. The specified profiles -are evaluated by Spring's Environment.acceptsProfiles() method, so any expressions it supports -may be used as the name attribute. - -This example will use a Console Appender when the Spring profile is "dev" or "staging" and a List -Appender when the active profile is "prod". - -[source,xml] ----- - - +* for standalone Java SE application it is a random identifier, +* for web applications it is derived from the application descriptor. +See xref:manual/webapp.adoc#configuration[Log4j + Web application configuration] for more details. - - - - - - - - - +:: must be one of the file extensions assigned to a configuration file format: ++ +[cols="1,1"] +|=== +| Configuration file format | Extension - - - - - - - - - - ----- +| XML +| `xml` -[#AutomaticConfiguration] -== Automatic Configuration +| JSON +| `json` or `jsn` -Log4j has the ability to automatically configure itself during -initialization. When Log4j starts it will locate all the -ConfigurationFactory plugins and arrange them in weighted order from -highest to lowest. As delivered, Log4j contains four -ConfigurationFactory implementations: one for JSON, one for YAML, one -for properties, and one for XML. +| YAML +| `yaml` or `yml` -1. Log4j will inspect the <> system property and, if set, will attempt to load the configuration using the `ConfigurationFactory` that matches the file extension. -Note that this is not restricted to a location on the local file system and may contain a URL. -2. If no system property is set the properties ConfigurationFactory -will look for `log4j2-test.properties` in the classpath. -3. If no such file is found the YAML ConfigurationFactory will look for -`log4j2-test.yaml` or `log4j2-test.yml` in the classpath. -4. If no such file is found the JSON ConfigurationFactory will look for -`log4j2-test.json` or `log4j2-test.jsn` in the classpath. -5. If no such file is found the XML ConfigurationFactory will look for -`log4j2-test.xml` in the classpath. -6. If a test file cannot be located the properties ConfigurationFactory -will look for `log4j2.properties` on the classpath. -7. If a properties file cannot be located the YAML ConfigurationFactory -will look for `log4j2.yaml` or `log4j2.yml` on the classpath. -8. If a YAML file cannot be located the JSON ConfigurationFactory will -look for `log4j2.json` or `log4j2.jsn` on the classpath. -9. If a JSON file cannot be located the XML ConfigurationFactory will -try to locate `log4j2.xml` on the classpath. -10. If no configuration file could be located the `DefaultConfiguration` -will be used. This will cause logging output to go to the console. +|Java properties +| `properties` +|=== -An example application named `MyApp` that uses log4j can be used to -illustrate how this is done. +[NOTE] +==== +It is also possible to override the location of the configuration file using the <> +configuration property. + +In this case Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. +See <> for details. +==== + +=== Syntax + +All configuration files are parsed into a tree of link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node[Node]s, each representing a different Log4j component. +The root of the tree creates a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration[Configuration] object. + +A node is a fairly simple structure that represents a single Log4j plugin (cf. xref:plugin-reference.adoc[] for a complete list) such as an appender, layout or logger configuration. +Each node has: + +* a set of simple string key value pairs called **attributes**. +Attributes are **matched by name** against the list of available configuration options of a Log4j plugin. + +* one distinguished attribute called **plugin type** specifies the kind of Log4j plugin we want to instantiate. + +* a set of child nodes called **nested elements**. +They are **matched by type** against the list of nested components that a Log4j plugin accepts. + +Log4j maps the concepts above to the specifics of the configuration format as follows: + +[tabs] +===== +XML:: ++ +Since XML was the original configuration format developed, the mapping from configuration nodes and XML elements is trivial: ++ +[id=configuration-with-xml] +==== +* Each configuration node is represented by an XML element. +* Each configuration attribute is represented by an XML attribute. +* The **plugin type** of a node is equal to the name of the XML tag. +* Each configuration nested element is represented by a nested XML element. +==== ++ +[NOTE] +==== +There is an alternative XML configuration format called "XML strict format" that is activated by setting the `strict` attribute of the main `` element to `true`. + +It allows users to use arbitrary tag names as long as they provide the plugin type using a `type` property. +It was conceived as a simplified XML format that can be validated by an XML schema. + +Nowadays, the automatically generated schemas published at https://logging.apache.org/xml/ns/ offer a better alternative and allow users to use the more concise syntax. +==== + +JSON:: ++ +In the JSON configuration format: ++ +[id=configuration-with-json] +==== +* Each configuration node is represented by a JSON object, +* JSON properties of type string, number or boolean are mapped to node attributes. +* JSON properties of type object or array are used to represent nested configuration elements. +* The **plugin type** of a JSON object is given by: +** the value of the `type` key, if present, +** or the key associated with the JSON object otherwise, +** if the JSON object representing the node is part of an array, the key associated to the JSON array is used. +==== ++ +[TIP] +==== +If you need to specify multiple plugins of the same type, you can use JSON arrays. +The snippet below represents two plugins of type `File`. -[source,java] +[source,json] ---- -import com.foo.Bar; - -// Import log4j classes. -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -public class MyApp { - - // Define a static logger variable so that it references the - // Logger instance named "MyApp". - private static final Logger logger = LogManager.getLogger(MyApp.class); - - public static void main(final String... args) { - - // Set up a simple configuration that logs on the console. - - logger.trace("Entering application."); - Bar bar = new Bar(); - if (!bar.doIt()) { - logger.error("Didn't do it."); - } - logger.trace("Exiting application."); +{ + "File": [ + { + "name": "file1" + }, + { + "name": "file2" } + ] } ---- +==== + +YAML:: ++ +In the YAML configuration format: ++ +[id=configuration-with-yaml] +==== +* Each configuration node is represented by a YAML mapping, +* YAML properties of scalar type are mapped to node attributes. +* YAML properties of collection type are used to represent nested configuration elements. +* The **plugin type** of a YAML mapping is given by: +** the value of the `type` key, if present, +** or the key associated with the YAML mapping otherwise, +** if the YAML mapping representing the node is part of a YAML block sequence, the key associated to the YAML sequence is used. +==== ++ +[TIP] +==== +If you need to specify multiple plugins of the same type, you can use YAML block sequences. +The snippet below represents two plugins of type `File`. -`MyApp` begins by importing log4j related classes. It then defines a -static logger variable with the name `MyApp` which happens to be the -fully qualified name of the class. - -`MyApp` uses the `Bar` class defined in the package`com.foo`. - -[source,java] ----- -package com.foo; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -public class Bar { - static final Logger logger = LogManager.getLogger(Bar.class.getName()); - - public boolean doIt() { - logger.entry(); - logger.error("Did it again!"); - return logger.exit(false); - } -} ----- - -Log4j will provide a default configuration if it cannot locate a -configuration file. The default configuration, provided in the -DefaultConfiguration class, will set up: - -* A -link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/ConsoleAppender.html[`ConsoleAppender`] -attached to the root logger. -* A -link:../javadoc/log4j-core/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`] -set to the pattern "%d\{HH:mm:ss.SSS} [%t] %-5level %logger\{36} - -%msg%n" attached to the ConsoleAppender - -Note that by default Log4j assigns the root logger to `Level.ERROR`. - -The output of MyApp would be similar to: - -.... -17:13:01.540 [main] ERROR com.foo.Bar - Did it again! -17:13:01.540 [main] ERROR MyApp - Didn't do it. -.... - -As was described previously, Log4j will first attempt to configure -itself from configuration files. A configuration equivalent to the -default would look like: - -[source,xml] ----- - - - - - - - - - - - - - ----- - -Once the file above is placed into the classpath as log4j2.xml you will -get results identical to those listed above. Changing the root level to -trace will result in results similar to: - -.... -17:13:01.540 [main] TRACE MyApp - Entering application. -17:13:01.540 [main] TRACE com.foo.Bar - entry -17:13:01.540 [main] ERROR com.foo.Bar - Did it again! -17:13:01.540 [main] TRACE com.foo.Bar - exit with (false) -17:13:01.540 [main] ERROR MyApp - Didn't do it. -17:13:01.540 [main] TRACE MyApp - Exiting application. -.... - -Note that status logging is disabled when the default configuration is -used. - -[#Configuration_From_a_URI] -== Configuration From a URI - -When `log4j2.configurationFile` references a URL, Log4j will first determine if the URL reference -a file using the file protocol. If it does Log4j will validate that the file URL is valid and continue -processing as previously described. If it contains a protocol other than file then Log4j will inspect -the value of the <> system property. If the provided list -contains the protocol specified then Log4j will use the URI to locate the specified configuration file. If -not an exception will be thrown and an error message will be logged. If no value is provided for the -system property it will default to "https". Use of any protocol other than "file" can be prevented by -setting the system property value to "_none". This value would be an invalid protocol so cannot conflict -with any custom protocols that may be present. - -Log4j supports access to remote URLs that require authentication. Log4j supports basic authentication -out of the box. If the `log4j2.Configuration.username` and `log4j2.Configuration.password` -are specified those values will be used to perform the authentication. If the password is encrypted a custom -password decryptor may be supplied by specifying the fully qualified class name in the -<> system property. A custom -`AuthenticationProvider` may be used by setting the -`<> system property to the fully qualified class name -of the provider. - -[#Additivity] -== Additivity - -Perhaps it is desired to eliminate all the TRACE output from everything -except `com.foo.Bar`. Simply changing the log level would not accomplish -the task. Instead, the solution is to add a new logger definition to the -configuration: - -[source,xml] ----- - - - - - - - ----- - -With this configuration all log events from `com.foo.Bar` will be -recorded while only error events will be recorded from all other -components. - -In the previous example all the events from `com.foo.Bar` were still -written to the Console. This is because the logger for `com.foo.Bar` did -not have any appenders configured while its parent did. In fact, the -following configuration - -[source,xml] ----- - - - - - - - - - - - - - - - - +[source,yaml] ---- - -would result in - -.... -17:13:01.540 [main] TRACE com.foo.Bar - entry -17:13:01.540 [main] TRACE com.foo.Bar - entry -17:13:01.540 [main] ERROR com.foo.Bar - Did it again! -17:13:01.540 [main] TRACE com.foo.Bar - exit (false) -17:13:01.540 [main] TRACE com.foo.Bar - exit (false) -17:13:01.540 [main] ERROR MyApp - Didn't do it. -.... - -Notice that the trace messages from `com.foo.Bar` appear twice. This is -because the appender associated with logger `com.foo.Bar` is first used, -which writes the first instance to the Console. Next, the parent of -`com.foo.Bar`, which in this case is the root logger, is referenced. The -event is then passed to its appender, which is also writes to the -Console, resulting in the second instance. This is known as additivity. -While additivity can be quite a convenient feature (as in the first -previous example where no appender reference needed to be configured), -in many cases this behavior is considered undesirable and so it is -possible to disable it by setting the additivity attribute on the logger -to false: - +File: + - name: file1 + - name: file2 +---- +==== + +Java properties:: ++ +The Java properties format is not well suited to represent hierarchical structures. +In the Java properties configuration format: ++ +[id=configuration-with-properties] +==== +* Properties that share a common prefix (e.g. `appender.foo`) are mapped to a subtree of the configuration node tree. +* Configuration attributes are specified by appending the name of the property (e.g. `name`) to the prefix of the node, separated by a dot (e.g. `appender.foo.name`). +* The **plugin type** must necessarily be specified as an attribute named `type`. +* Nested elements are created by: +** choosing an arbitrary id for the nested component (e.g. `<0>`), +** appending the id to the prefix of the parent component (e.g. `appender.foo.<0>`), +** specifying the type of the nested plugin by assigning a `type` attribute (e.g. `appender.foo.<0>.type`). +==== ++ +[NOTE] +==== +The id assigned to nested components is only used for sorting purposes. +However, some components assign a special meaning to some ids. +See a list of exceptions below: +==== ++ +.Properties format quirks +[%collapsible,#properties-format-quirks] +==== +The Java properties configuration format is by far the most verbose of the available formats. +In order to make it more usable a series of exceptions to the rules in <> have been introduced over time: + +. The following direct children of `Configuration` have predefined prefixes and do not require to specify a `type` +attribute: +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-AppendersPlugin[Appender container] has a predefined `appender` prefix. +* The xref:plugin-reference.adoc##org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevels[Custom levels container] has a predefined `customLevel` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggersPlugin[Loggers container] has a predefined `logger` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-PropertiesPlugin[Properties container] has a predefined `property` prefix. +* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-ScriptsPlugin[Scripts container] has a predefined `script` prefix. +. Properties that start with `property` are used for <>. +Their syntax is `property. = `. +. The root logger can be configured using properties that start with `rootLogger`. +. A shorthand notation is available that allows users to write: ++ +---- +rootLogger = INFO, APPENDER +---- ++ +instead of: ++ +---- +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = APPENDER +---- +. All the keys of the form `logger..appenderRef.`, where `` and `` are arbitrary, are considered appender references. +==== +===== + +=== Main configuration elements + +Log4j Core's logging pipeline is quite complex (see xref:manual/architecture.adoc[Architecture]), but most users only require these elements: + +Loggers:: ++ +Loggers are the entry point of the logging pipeline, directly used in code. +Their configuration must specify which level of messages they log and to which appenders they send the messages. + +Appenders:: ++ +Appenders are the exit point of the logging pipeline. +They decide to which resource (console, file, database, etc.) the log event is sent. +For a complete list see xref:manual/appenders.adoc[Appenders]. +In this chapter we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender] in the examples. + +Layouts:: ++ +Layouts tell appenders how they should format the log event: text, JSON, XML, etc. +For a complete list see xref:manual/layouts.adoc[Layouts]. +In this chapter we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] and xref:manual/json-template-layout.adoc[JSON template layout] in the examples. + +A moderately complex configuration might look like this: + +[tabs] +==== +XML:: ++ [source,xml] ---- - + - - + + - - - - - - - - - - ----- - -Once an event reaches a logger with its additivity set to false the -event will not be passed to any of its parent loggers, regardless of -their additivity setting. - -[#AutomaticReconfiguration] -== Automatic Reconfiguration - -When configured from a File, Log4j has the ability to automatically -detect changes to the configuration file and reconfigure itself. If the -`monitorInterval` attribute is specified on the configuration element -and is set to a non-zero value then the file will be checked the next -time a log event is evaluated and/or logged and the monitorInterval has -elapsed since the last check. The example below shows how to configure -the attribute so that the configuration file will be checked for changes -only after at least 30 seconds have elapsed. The minimum interval is 5 -seconds. - -[source,xml] ----- - - -... - ----- - -[#ChainsawSupport] -== Chainsaw can automatically process your log files (Advertising appender configurations) - -Log4j provides the ability to 'advertise' appender configuration details -for all file-based appenders as well as socket-based appenders. For -example, for file-based appenders, the file location and the pattern -layout in the file are included in the advertisement. Chainsaw and other -external systems can discover these advertisements and use that -information to intelligently process the log file. - -The mechanism by which an advertisement is exposed, as well as the -advertisement format, is specific to each Advertiser implementation. An -external system which would like to work with a specific Advertiser -implementation must understand how to locate the advertised -configuration as well as the format of the advertisement. For example, a -'database' Advertiser may store configuration details in a database -table. An external system can read that database table in order to -discover the file location and the file format. - -Log4j provides one Advertiser implementation, a 'multicastdns' -Advertiser, which advertises appender configuration details via IP -multicast using the http://jmdns.sourceforge.net library. - -Chainsaw automatically discovers log4j's multicastdns-generated -advertisements and displays those discovered advertisements in -Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's -classpath). To begin parsing and tailing a log file provided in an -advertisement, just double-click the advertised entry in Chainsaw's -Zeroconf tab. Currently, Chainsaw only supports FileAppender -advertisements. - -To advertise an appender configuration: - -* Add the JmDns library from http://jmdns.sourceforge.net to the -application classpath -* Set the 'advertiser' attribute of the configuration element to -'multicastdns' -* Set the 'advertise' attribute on the appender element to 'true' -* If advertising a FileAppender-based configuration, set the -'advertiseURI' attribute on the appender element to an appropriate URI - -FileAppender-based configurations require an additional 'advertiseURI' -attribute to be specified on the appender. The 'advertiseURI' attribute -provides Chainsaw with information on how the file can be accessed. For -example, the file may be remotely accessible to Chainsaw via ssh/sftp by -specifying a Commons VFS (http://commons.apache.org/proper/commons-vfs/) -sftp:// URI, an http:// URI may be used if the file is accessible -through a web server, or a file:// URI can be specified if accessing the -file from a locally-running instance of Chainsaw. - -Here is an example advertisement-enabled appender configuration which -can be used by a locally-running Chainsaw to automatically tail the log -file (notice the file:// advertiseURI): - -*Please note, you must add the JmDNS library mentioned above.* - -[source,xml] ----- - - - ... - - - ... + + + + + - - ----- - -[#ConfigurationSyntax] -== Configuration Syntax - -As of version 2.9, for security reasons, Log4j does not process DTD in -XML files. If you want to split the configuration in multiple files, use -link:#XInclude[XInclude] or link:#CompositeConfiguration[Composite -Configuration]. - -As the previous examples have shown as well as those to follow, Log4j -allows you to easily redefine logging behavior without needing to modify -your application. It is possible to disable logging for certain parts of -the application, log only when specific criteria are met such as the -action being performed for a specific user, route output to Flume or a -log reporting system, etc. Being able to do this requires understanding -the syntax of the configuration files. - -The configuration element in the XML file accepts several attributes: - -[cols="1m,5a"] -|=== -|Attribute Name |Description - -|advertiser -|(Optional) The Advertiser plugin name which will be used to -advertise individual FileAppender or SocketAppender configurations. The -only Advertiser plugin provided is "multicastdns". - -|dest -|Either "err" for stderr, "out" for stdout, a file path, or a URL. - -|monitorInterval -|The minimum amount of time, in seconds, that must -elapse before the file configuration is checked for changes. - -|name -|The name of the configuration. - -|schema -|Identifies the location for the classloader to located the XML -Schema to use to validate the configuration. Only valid when strict is -set to true. If not set no schema validation will take place. - -|shutdownHook -|Specifies whether or not Log4j should automatically -shutdown when the JVM shuts down. The shutdown hook is enabled by -default but may be disabled by setting this attribute to "disable" - -|shutdownTimeout -|Specifies how many milliseconds appenders and -background tasks will get to shutdown when the JVM shuts down. Default -is zero which mean that each appender uses its default timeout, and -don't wait for background tasks. Not all appenders will honor this, it -is a hint and not an absolute guarantee that the shutdown procedure will -not take longer. Setting this too low increase the risk of losing -outstanding log events not yet written to the final destination. See -link:../javadoc/log4j-core/org/apache/logging/log4j/core/LoggerContext.html$%7Besc.hash%7Dstop(long,%20java.util.concurrent.TimeUnit)[LoggerContext.stop(long, -java.util.concurrent.TimeUnit)]. (Not used if `shutdownHook` is set to -"disable".) - -|status -|The level of internal Log4j events that should be logged to the console. -Valid values for this attribute are "off", "trace", "debug", "info", "warn", -"error", "fatal", and "all". Log4j will log details about initialization, -rollover and other internal actions to the status logger. Setting -`status="trace"` is one of the first tools available to you if you need -to troubleshoot log4j. - -(Alternatively, setting system property <> will also print -internal Log4j2 logging to the console, including internal logging that -took place before the configuration file was found.) - -|strict -|Enables the use of the strict XML format. Not supported in JSON -configurations. - -|verbose -|Enables diagnostic information while loading plugins. -|=== - -[[XML]] -=== Configuration with XML - -Log4j can be configured using two XML flavors; concise and strict. - -=== Concise Syntax - -The concise format makes configuration very easy as the element names match -the components they represent however it cannot be validated with an XML -schema. For example, the ConsoleAppender is configured by declaring an -XML element named Console under its parent appenders element. However, -element and attribute names are not case sensitive. In addition, -attributes can either be specified as an XML attribute or as an XML -element that has no attributes and has a text value. So - -[source,xml] ----- - ----- - -and - -[source,xml] ----- - - %m%n - ----- - -are equivalent. - -The file below represents the structure of an XML configuration, but -note that the elements in italics below represent the concise element -names that would appear in their place. - -[source,xml] ----- -; - - - value - - - - - - - - ... - - - - - - ... - - - - - ----- - -See the many examples on this page for sample appender, filter and -logger declarations. - -=== Strict XML - -In addition to the concise XML format above, Log4j allows configurations -to be specified in a more "normal" XML manner that can be validated -using an XML Schema. This is accomplished by replacing the friendly -element names above with their object type as shown below. For example, -instead of the ConsoleAppender being configured using an element named -Console it is instead configured as an appender element with a type -attribute containing "Console". - -[source,xml] ----- - - - - value - - - - - - - - ... - - - - ... - - + + + - - ----- - -Below is a sample configuration using the strict format. - -[source,xml] ----- - - - - target/test.log - - - - - - - - - - - - - - - - - - - - - %d %p %C{1.} [%t] %m%n - - - - - - - - - - + + - - - - - - - - - ---- -[#JSON] -=== Configuration with JSON - -In addition to XML, Log4j can be configured using JSON. The JSON format -is very similar to the concise XML format. Each key represents the name -of a plugin and the key/value pairs associated with it are its -attributes. Where a key contains more than a simple value it itself will -be a subordinate plugin. In the example below, ThresholdFilter, Console, -and PatternLayout are all plugins while the Console plugin will be -assigned a value of STDOUT for its name attribute and the -ThresholdFilter will be assigned a level of debug. - +JSON:: ++ [source,json] ---- -{ "configuration": { "status": "error", "name": "RoutingTest", - "packages": "org.apache.logging.log4j.test", - "properties": { - "property": { "name": "filename", - "value" : "target/rolling1/rollingtest-$${sd:type}.log" } - }, - "ThresholdFilter": { "level": "debug" }, - "appenders": { - "Console": { "name": "STDOUT", - "PatternLayout": { "pattern": "%m%n" }, - "ThresholdFilter": { "level": "debug" } - }, - "Routing": { "name": "Routing", - "Routes": { "pattern": "$${sd:type}", - "Route": [ - { - "RollingFile": { - "name": "Rolling-${sd:type}", "fileName": "${filename}", - "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", - "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, - "SizeBasedTriggeringPolicy": { "size": "500" } - } - }, - { "AppenderRef": "STDOUT", "key": "Audit"} - ] +{ + "Configuration": { + "Appenders": { + "Console": { + "name": "CONSOLE", + "target": "SYSTEM_OUT", + "PatternLayout": { + "pattern": "%p - %m%n" } - } - }, - "loggers": { - "logger": { "name": "EventLogger", "level": "info", "additivity": "false", - "AppenderRef": { "ref": "Routing" }}, - "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} - } - } -} ----- - -Note that in the RoutingAppender the Route element has been declared as -an array. This is valid because each array element will be a Route -component. This won't work for elements such as appenders and filters, -where each element has a different name in the concise format. Appenders -and filters can be defined as array elements if each appender or filter -declares an attribute named "type" that contains the type of the -appender. The following example illustrates this as well as how to -declare multiple loggers as an array. - -[source,json] ----- -{ "configuration": { "status": "debug", "name": "RoutingTest", - "packages": "org.apache.logging.log4j.test", - "properties": { - "property": { "name": "filename", - "value" : "target/rolling1/rollingtest-$${sd:type}.log" } }, - "ThresholdFilter": { "level": "debug" }, - "appenders": { - "appender": [ - { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }}, - { "type": "Routing", "name": "Routing", - "Routes": { "pattern": "$${sd:type}", - "Route": [ - { - "RollingFile": { - "name": "Rolling-${sd:type}", "fileName": "${filename}", - "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", - "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, - "SizeBasedTriggeringPolicy": { "size": "500" } - } - }, - { "AppenderRef": "STDOUT", "key": "Audit"} - ] + "File": [ + { + "name": "AUDIT", + "fileName": "logs/audit.log", + "JsonTemplateLayout": {} + }, + { + "name": "MAIN", + "fileName": "logs/main.log", + "PatternLayout": { + "pattern": "%d [%t] %p %c - %m%n" } } ] }, - "loggers": { - "logger": [ - { "name": "EventLogger", "level": "info", "additivity": "false", - "AppenderRef": { "ref": "Routing" }}, - { "name": "com.foo.bar", "level": "error", "additivity": "false", - "AppenderRef": { "ref": "STDOUT" }} - ], - "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} + "Loggers": { + "Root": { + "level": "WARN", + "AppenderRef": [ + { + "ref": "CONSOLE" + }, + { + "ref": "MAIN" + } + ] + }, + "Logger": { + "name": "org.example.audit", + "level": "INFO", + "AppenderRef": { + "ref": "AUDIT" + } + } } } } ---- -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using JSON configuration files. - -[#YAML] -=== Configuration with YAML - -Log4j also supports using YAML for configuration files. The structure -follows the same pattern as both the XML and YAML configuration formats. -For example: - +YAML:: ++ [source,yaml] ---- Configuration: - status: warn - name: YAMLConfigTest - properties: - property: - name: filename - value: target/test-yaml.log - thresholdFilter: - level: debug - appenders: + Appenders: Console: - name: STDOUT - target: SYSTEM_OUT - PatternLayout: - Pattern: "%m%n" + - name: "CONSOLE" + target: "SYSTEM_OUT" + PatternLayout: + pattern: "%p - %m%n" File: - name: File - fileName: ${filename} - PatternLayout: - Pattern: "%d %p %C{1.} [%t] %m%n" - Filters: - ThresholdFilter: - level: error - + - name: "AUDIT" + fileName: "logs/audit.log" + JsonTemplateLayout: { } + - name: "MAIN" + fileName: "logs/main.log" + PatternLayout: + pattern: "%d [%t] %p %c - %m%n" Loggers: - logger: - - - name: org.apache.logging.log4j.test1 - level: debug - additivity: false - ThreadContextMapFilter: - KeyValuePair: - key: test - value: 123 - AppenderRef: - ref: STDOUT - - - name: org.apache.logging.log4j.test2 - level: debug - additivity: false - AppenderRef: - ref: File Root: - level: error + level: "WARN" AppenderRef: - ref: STDOUT - ----- - -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using YAML configuration files. - -[#Properties] -=== Configuration with Properties - -As of version 2.4, Log4j now supports configuration via properties -files. Note that the property syntax is NOT the same as the syntax used -in Log4j 1. Like the XML and JSON configurations, properties -configurations define the configuration in terms of plugins and -attributes to the plugins. - -Prior to version 2.6, the properties configuration requires that you -list the identifiers of the appenders, filters and loggers, in a comma -separated list in properties with those names. Each of those components -will then be expected to be defined in sets of properties that begin -with _component.<.identifier>._. The identifier does not have to match -the name of the component being defined but must uniquely identify all -the attributes and subcomponents that are part of the component. If the -list of identifiers is not present the identifier must not contain a '.'. -Each individual component MUST have a "type" attribute specified that -identifies the component's Plugin type. - -As of version 2.6, this list of identifiers is no longer required as -names are inferred upon first usage, however if you wish to use more -complex identifies you must still use the list. If the list is present -it will be used. - -Unlike the base components, when creating subcomponents you cannot -specify an element containing a list of identifiers. Instead, you must -define the wrapper element with its type as is shown in the policies -definition in the rolling file appender below. You then define each of -the subcomponents below that wrapper element, as the -TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are defined -below. - -As of version 2.17.2, `rootLogger` and `logger._key_` properties can be specified to set the -level and zero or more appender refs to create for that logger. The level and appender refs are -separated by comma `,` characters with optional whitespace surrounding the comma. The -following example demonstrates how the shorthand is expanded when reading properties configurations. - -[source,properties] ----- -appender.stdout.type = Console -# ... other appender properties -appender.file.type = File -# ... other appender properties -logger.app = INFO, stdout, file -logger.app.name = com.example.app - -# is equivalent to: -# appender.stdout.type = Console -# appender.stdout.name = stdout -# ... -appender.file.type = File -appender.file.name = file -# ... -logger.app.name = com.example.app -logger.app.level = INFO -logger.app.appenderRef.$1.ref = stdout -logger.app.appenderRef.$2.ref = file + - ref: "CONSOLE" + - ref: "MAIN" + Logger: + name: "org.example.audit" + level: "INFO" + AppenderRef: + ref: "AUDIT" ---- -Properties configuration files support the advertiser, monitorInterval, -name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest -attributes. See link:#ConfigurationSyntax[Configuration Syntax] for the -definitions of these attributes. - +Java properties:: ++ [source,properties] ---- -status = error -dest = err -name = PropertiesConfig - -property.filename = target/rolling/rollingtest.log - -filter.threshold.type = ThresholdFilter -filter.threshold.level = debug - -appender.console.type = Console -appender.console.name = STDOUT -appender.console.layout.type = PatternLayout -appender.console.layout.pattern = %m%n -appender.console.filter.threshold.type = ThresholdFilter -appender.console.filter.threshold.level = error - -appender.rolling.type = RollingFile -appender.rolling.name = RollingFile -appender.rolling.fileName = ${filename} -appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz -appender.rolling.layout.type = PatternLayout -appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n -appender.rolling.policies.type = Policies -appender.rolling.policies.time.type = TimeBasedTriggeringPolicy -appender.rolling.policies.time.interval = 2 -appender.rolling.policies.time.modulate = true -appender.rolling.policies.size.type = SizeBasedTriggeringPolicy -appender.rolling.policies.size.size=100MB -appender.rolling.strategy.type = DefaultRolloverStrategy -appender.rolling.strategy.max = 5 - -logger.rolling.name = com.example.my.app -logger.rolling.level = debug -logger.rolling.additivity = false -logger.rolling.appenderRef.rolling.ref = RollingFile - -rootLogger.level = info -rootLogger.appenderRef.stdout.ref = STDOUT - ----- - - -[#Loggers] -=== Configuring Loggers - -An understanding of how loggers work in Log4j is critical before trying -to configure them. Please reference the Log4j -xref:manual/architecture.adoc[architecture] if more information is required. -Trying to configure Log4j without understanding those concepts will lead -to frustration. - -A LoggerConfig is configured using the `logger` element. The `logger` -element must have a name attribute specified, will usually have a level -attribute specified and may also have an additivity attribute specified. -The level may be configured with one of TRACE, DEBUG, INFO, WARN, ERROR, -ALL or OFF. If no level is specified it will default to ERROR. The -additivity attribute may be assigned a value of true or false. If the -attribute is omitted the default value of true will be used. - -Capturing location information (the class name, file name, method name, and line number of the caller) -can be slow. Log4j tries to optimize this by reducing the size of the stack that must be traversed -to find the caller of the logging method. It does this by determining if any component that might -be accessed requires location information. This can cause performance issues if a logger is configured -at a level like trace or debug with the expectation that most logs will be filtered on an Appender -reference or Appender as Log4j will calculate the location information even though the log event -is going to be discarded. To disable this behavior the `includeLocation` attribute -can be set to false on the LoggerConfig. This will cause Log4j to defer calculating the location -information until absolutely necessary. - -A LoggerConfig (including the root LoggerConfig) can be configured with -properties that will be added to the properties copied from the -ThreadContextMap. These properties can be referenced from Appenders, -Filters, Layouts, etc just as if they were part of the ThreadContext -Map. The properties can contain variables that will be resolved either -when the configuration is parsed or dynamically when each event is -logged. See link:#PropertySubstitution[Property Substitution] for more -information on using variables. - -The LoggerConfig may also be configured with one or more AppenderRef -elements. Each appender referenced will become associated with the -specified LoggerConfig. If multiple appenders are configured on the -LoggerConfig each of them be called when processing logging events. - -*_Every configuration must have a root logger_*. If one is not -configured the default root LoggerConfig, which has a level of ERROR and -has a Console appender attached, will be used. The main differences -between the root logger and other loggers are - -1. The root logger does not have a name attribute. -2. The root logger does not support the additivity attribute since it -has no parent. - -[#Appenders] -=== Configuring Appenders - -An appender is configured either using the specific appender plugin's -name or with an appender element and the type attribute containing the -appender plugin's name. In addition each appender must have a name -attribute specified with a value that is unique within the set of -appenders. The name will be used by loggers to reference the appender as -described in the previous section. - -Most appenders also support a layout to be configured (which again may -be specified either using the specific Layout plugin's name as the -element or with "layout" as the element name along with a type attribute -that contains the layout plugin's name. The various appenders will -contain other attributes or elements that are required for them to -function properly. - -[#Filters] -=== Configuring Filters - -Log4j allows a filter to be specified in any of 4 places: - -1. At the same level as the appenders, loggers and properties elements. -These filters can accept or reject events before they have been passed -to a LoggerConfig. -2. In a logger element. These filters can accept or reject events for -specific loggers. -3. In an appender element. These filters can prevent or cause events to -be processed by the appender. -4. In an appender reference element. These filters are used to -determine if a Logger should route the event to an appender. - -Although only a single `filter` element can be configured, that element -may be the `filters` element which represents the CompositeFilter. The -`filters` element allows any number of `filter` elements to be -configured within it. The following example shows how multiple filters -can be configured on the ConsoleAppender. - -[source,xml] ----- - - - - target/test.log - - - - - - - - - - - - - - - - - - %d %p %C{1.} [%t] %m%n - - - - - - - - - - - - - - ${sys:user.name} - - - - - - - - - - - - - - ----- - -[#PropertySubstitution] -== Property Substitution - -Log4j 2 supports the ability to specify tokens in the configuration as -references to properties defined elsewhere. Some of these properties -will be resolved when the configuration file is interpreted while others -may be passed to components where they will be evaluated at runtime. To -accomplish this, Log4j uses variations of -https://commons.apache.org/proper/commons-lang/[Apache Commons Lang]'s -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`] -and -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] -classes. In a manner similar to Ant or Maven, this allows variables -declared as `$\{name}` to be resolved using properties declared in the -configuration itself. For example, the following example shows the -filename for the rolling file appender being declared as a property. - -[source,xml] ----- - - - - target/rolling1/rollingtest-$${sd:type}.log - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - ----- - -While this is useful, there are many more places properties can -originate from. To accommodate this, Log4j also supports the syntax -`${prefix:name}` where the prefix identifies tells Log4j that variable -name should be evaluated in a specific context. See the -xref:manual/lookups.adoc[Lookups] manual page for more details. The contexts -that are built in to Log4j are: - -[cols="1m,5"] -|=== -|Prefix |Context - - - base64 - - Base64 encoded data. The format is ${base64:Base64_encoded_data}. - For example: - ${base64:SGVsbG8gV29ybGQhCg==} yields Hello World!. - - - -|base64 -|Base64 encoded data. The format is `${base64:Base64_encoded_data}`. -For example: `${base64:SGVsbG8gV29ybGQhCg==}` yields `Hello World!`. - -|bundle -|Resource bundle. The format is `${bundle:BundleName:BundleKey}`. -The bundle name follows package naming conventions, for example: -`${bundle:com.domain.Messages:MyKey}`. - -|ctx -|Thread Context Map (MDC) - -|date -|Inserts the current date and/or time using the specified format - -|docker -| Returns attributes from the Docker container the application is running in. The format is ${docker:some.attribute}. See xref:log4j-docker.adoc[Docker documentation] for requirements and a list of available attributes. - -|env -|System environment variables. The formats are `${env:ENV_NAME}` and `${env:ENV_NAME:-default_value}`. - -| event -| Retrieves values from fields within the log event. The format is ${event:some.field}. See the Lookups manual page for a list of available fields. -| java -| Retrieves information about the Java environment the application is running in. The format is ${java:some.property}. See the Lookups manual page for a list of available properties. - -|jndi -|A value set in the default JNDI Context. - -|jvmrunargs -|A JVM input argument accessed through JMX, but not a main argument; see -https://docs.oracle.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[RuntimeMXBean.getInputArguments()]. -Not available on Android. - -| k8s -| Returns attributes from the Kubernetes environment the application is running in. The format is ${k8s:some.attribute}. See the Lookups manual page for a list of available attributes. - -|log4j -|Log4j configuration properties. The expressions -`${log4j:configLocation}` and `${log4j:configParentLocation}` -respectively provide the absolute path to the log4j configuration file -and its parent folder. - -| lower -| Converts the passed in argument to lower case (usually used with nested lookups). The format is ${lower:argument}. - -|main -|A value set with -../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments-java.lang.String:A-[MapLookup.setMainArguments(String[])] - -|map -|A value from a MapMessage - -| marker -| Allows use of markers in configurations. The formats are ${marker:} and ${marker:some.name}. See the Lookups manual page for further details. - -|sd -|A value from a StructuredDataMessage. The key "id" will return the -name of the StructuredDataId without the enterprise number. The key -"type" will return the message type. Other keys will retrieve individual -elements from the Map. - -| spring -| Returns values of Spring properties from the Spring configuration. The format is ${spring:some.property}. See the Lookups manual page for requirements and details. - -|sys -|System properties. The formats are `${sys:some.property}` and -`${sys:some.property:-default_value}`. - -| upper -| Converts the passed in argument to upper case (usually used with nested lookups). The format is ${upper:argument}. -| web -| Returns values of variables associated with the Servlet Context. The format is ${spring:some.key}. See the Lookups manual page for a list of available keys. -|=== - -[#DefaultProperties] -== Default Properties -A default property map can be declared in the configuration file by placing a Properties -element directly after the Configuration element and before any Loggers, Filters, -Appenders, etc. are declared. If the value cannot be located in the specified lookup the -value in the default property map will be used. The default map is pre-populated with a value -for "hostName" that is the current system's host name or IP address and -the "contextName" with is the value of the current logging context. See many places -a Properties element is used in this section for examples. - -Default properties may also be specified in the Lookup by using the syntax `${lookupName:key:-defaultValue}`. -In some cases the key might contain a leading '-'. When this is the case an escape character must be -included, such as ``${main:\--file:-app.properties}`. This would use the -`MainMapLookup` for a key named `--file`. If the key is not found then -app.properties would be used as the default value. - -[#EnablingMessagePatternLookups] -== Enabling Message Pattern Lookups -A message is processed (by default) without using lookups, for example if you defined -`FOO_BAR`, then `logger.info("${foo.bar}")` will output `${foo.bar}` instead of `FOO_BAR`. -You could enable message pattern lookups by defining the message pattern using `%m\{lookups}`. - -[#RuntimeLookup] -== Lookup Variables with Multiple Leading '$' Characters - -An interesting feature of StrLookup processing is that when a variable -reference is declared with multiple leading '$' characters each time the -variable is resolved the leading '$' is simply removed. In the previous -example the "Routes" element is capable of resolving the variable at -runtime. To allow this the prefix value is specified as a variable with -two leading '$' characters. When the configuration file is first -processed the first '$' character is simply removed. Thus, when the -Routes element is evaluated at runtime it is the variable declaration -"$\{sd:type}" which causes the event to be inspected for a -StructuredDataMessage and if one is present the value of its type -attribute to be used as the routing key. Not all elements support -resolving variables at runtime. Components that do will specifically -call that out in their documentation. - -If no value is found for the key in the Lookup associated with the -prefix then the value associated with the key in the properties -declaration in the configuration file will be used. If no value is found -the variable declaration will be returned as the value. Default values -may be declared in the configuration by doing: - -[source,xml] ----- - - - - Audit - - ... - ----- - -_As a footnote, it is worth pointing out that the variables in the -RollingFile appender declaration will also not be evaluated when the -configuration is processed. This is simply because the resolution of the -whole RollingFile element is deferred until a match occurs. See -xref:manual/appenders.adoc#RoutingAppender[RoutingAppender] for more -information._ - -[#Scripts] -== Scripts - -Log4j provides support for -https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR -223] scripting languages to be used in some of its components. Any -language that provides support for the JSR 223 scripting engine may be -used. A list of the languages and bindings for them can be found at the -https://java.net/projects/scripting/sources/svn/show/trunk/engines[Scripting -Engine] web site. However, some of the languages listed there, such as -JavaScript, Groovy and Beanshell, directly support the JSR 223 scripting -framework and only require that the jars for that language be installed. - -As of Log4j 2.17.2 the languages to be supported must be specified as a comma separated list in the -`log4j2.Script.enableLanguages` system property. - -The components that support using scripts do so by allowing a ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -If the status attribute on the Configuration element is set to DEBUG the -list of script engines currently installed and their attributes will be -listed. Although some engines may say they are not thread safe, Log4j -takes steps to insure that the scripts will run in a thread-safe manner -if the engine advertises that it is not thread safe. - -.... -2015-09-27 16:13:22,925 main DEBUG Installed script engines -2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe, - Compile: false, Names: {AppleScriptEngine, AppleScript, OSA} -2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED, - Compile: true, Names: {groovy, Groovy} -2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED, - Compile: true, Names: {beanshell, bsh, java} -2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED, - Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript} -.... - -When the scripts are executed they will be provided with a set of -variables that should allow them to accomplish whatever task they are -expected to perform. See the documentation for the individual components -for the list of variables that are available to the script. - -The components that support scripting expect a return value to be passed -back to the calling Java code. This is not a problem for several of the -scripting languages, but Javascript does not allow a return statement -unless it is within a function. However, Javascript will return the -value of the last statement executed in the script. As a consequence, -code such as that shown below will result in the desired behavior. - -[source,javascript] ----- -var result; -if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { - result = "NoLocation"; -} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { - result = "Flow"; -} -result; ----- - -=== A special note on Beanshell - -JSR 223 scripting engines are supposed to identify that they support the -Compilable interface if they support compiling their scripts. Beanshell -does this. However, whenever the compile method is called it throws an -Error (not an Exception). Log4j catches this but will log the warning -shown below for each Beanshell script when it tries to compile them. All -Beanshell scripts will then be interpreted on each execution. - -.... -2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable -2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented - at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175) - at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154) - at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.(ScriptManager.java:125) - at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94) - -.... - -[#XInclude] -== XInclude - -XML configuration files can include other files with -http://www.xml.com/lpt/a/1009[XInclude]. Here is an example log4j2.xml -file that includes two other files: - -.log4j2.xml -[source,xml] ----- - - - - xinclude-demo.log - - - - - ----- - -.log4j-xinclude-appenders.xml -[source,xml] ----- - - - - - - - - %d %p %C{1.} [%t] %m%n - - - ----- - -.log4j-xinclude-loggers.xml -[source,xml] ----- - - - - - - - - - - - - - - - - - ----- - -[#CompositeConfiguration] -== Composite Configuration - -Log4j allows multiple configuration files to be used by specifying them -as a list of comma separated file paths on log4j2.configurationFile or, -when using URLs, by adding secondary configuration locations as query -parameters named "override". The merge logic can be controlled by specifying -a class that implements the MergeStrategy interface on the log4j.mergeStrategy -property. The default merge strategy will merge the files using the following rules: - -1. The global configuration attributes are aggregated with those in -later configurations replacing those in previous configurations, with -the exception that the highest status level and the lowest -monitorInterval greater than 0 will be used. -2. Properties from all configurations are aggregated. Duplicate -properties replace those in previous configurations. -3. Filters are aggregated under a CompositeFilter if more than one -Filter is defined. Since Filters are not named duplicates may be -present. -4. Scripts and ScriptFile references are aggregated. Duplicate -definitions replace those in previous configurations. -5. Appenders are aggregated. Appenders with the same name are replaced -by those in later configurations, including all of the Appender's -subcomponents. -6. Loggers are all aggregated. Logger attributes are individually -merged with duplicates being replaced by those in later configurations. -Appender references on a Logger are aggregated with duplicates being -replaced by those in later configurations. Filters on a Logger are -aggregated under a CompositeFilter if more than one Filter is defined. -Since Filters are not named duplicates may be present. Filters under -Appender references included or discarded depending on whether their -parent Appender reference is kept or discarded. - -[#StatusMessages] -== Status Messages - -**** -*Troubleshooting tip for the impatient:* - -From log4j-2.9 onward, log4j2 will print all internal logging to the -console if system property `log4j2.debug` is either defined empty or its value -equals to `true` (ignoring case). - -Prior to log4j-2.9, there are two places where internal logging can be -controlled: - -* Before a configuration is found, status logger level can be controlled -with system property -`org.apache.logging.log4j.simplelog.StatusLogger.level`. -* After a configuration is found, status logger level can be controlled -in the configuration file with the "status" attribute, for example: -``. -**** - -Just as it is desirable to be able to diagnose problems in applications, -it is frequently necessary to be able to diagnose problems in the -logging configuration or in the configured components. Since logging has -not been configured, "normal" logging cannot be used during -initialization. In addition, normal logging within appenders could -create infinite recursion which Log4j will detect and cause the -recursive events to be ignored. To accomodate this need, the Log4j 2 API -includes a -link:../javadoc/log4j-api/org/apache/logging/log4j/status/StatusLogger.html[`StatusLogger`]. -Components declare an instance of the StatusLogger similar to: - -[source,java] ----- -protected final static Logger logger = StatusLogger.getLogger(); ----- - -Since StatusLogger implements the Log4j 2 API's Logger interface, all -the normal Logger methods may be used. - -When configuring Log4j it is sometimes necessary to view the generated status events. -This can be accomplished by adding the status attribute to the configuration element or a default value can be provided by setting the xref:statusLoggerLevel["log4j2.statusLoggerLevel"] system property. -Valid values of the status attribute are "trace", "debug", "info", "warn", "error" and "fatal". -The following configuration has the status attribute set to debug. - -[source,xml] ----- - - - - target/rolling1/rollingtest-$${sd:type}.log - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - ----- - -During startup this configuration produces: - -.... -2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds -2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${sd:type}.log") -2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${sd:type}.log}) -2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds -2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") -2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null") -2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds -2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null") -2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") -2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route) -2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route) -2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit')}) -2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null) -2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing}) -2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing") -2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null) -2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT") -2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null) -2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root}) -2011-11-23 17:08:00,834 DEBUG Reconfiguration completed -2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null") -2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500") -2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null") -2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds -2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher$AppClassLoader@37b90b39 -2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds -2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds -2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds -2011-11-23 17:08:00,965 WARN No Loggers were configured, using default -2011-11-23 17:08:00,976 DEBUG Reconfiguration completed -.... +appender.0.type = Console +appender.0.name = CONSOLE +appender.0.target = SYSTEM_OUT +appender.0.layout.type = PatternLayout +appender.0.layout.pattern = %p - %m%n -If the status attribute is set to error then only error messages will be -written to the console. This makes troubleshooting configuration errors -possible. As an example, if the configuration above is changed to have -the status set to error and the logger declaration is: +appender.1.type = File +appender.1.name = AUDIT +appender.1.fileName = logs/audit.log +appender.1.layout.type = JsonTemplateLayout -[source,xml] ----- - - - ----- - -the following error message will be produced. +appender.2.type = File +appender.2.name = MAIN +appender.2.fileName = logs/main.log +appender.2.layout.type = PatternLayout +appender.2.layout.pattern = %d [%t] %p %c - %m%n -.... -2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger -.... +rootLogger.level = WARN +rootLogger.appenderRef.0.ref = CONSOLE +rootLogger.appenderRef.1.ref = MAIN -Applications may wish to direct the status output to some other -destination. This can be accomplished by setting the dest attribute to -either "err" to send the output to stderr or to a file location or URL. -This can also be done by insuring the configured status is set to OFF -and then configuring the application programmatically such as: - -[source,java] ----- -StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR); -StatusLogger.getLogger().registerListener(listener); +logger.0.name = org.example.audit +logger.0.level = INFO +logger.0.appenderRef.0.ref = AUDIT ---- +==== -[#UnitTestingInMaven] -== Testing in Maven - -Maven can run unit and functional tests during the build cycle. By -default, any files placed in `src/test/resources` are automatically -copied to target/test-classes and are included in the classpath during -execution of any tests. As such, placing a log4j2-test.xml into this -directory will cause it to be used instead of a log4j2.xml or -log4j2.json that might be present. Thus a different log configuration -can be used during testing than what is used in production. +[id=property-substitution] +=== Property substitution -A second approach, which is extensively used by Log4j 2, is to set the -log4j2.configurationFile property in the method annotated with -@BeforeClass in the junit test class. This will allow an arbitrarily -named file to be used during the test. - -A third approach, also used extensively by Log4j 2, is to use the -`LoggerContextRule` JUnit test rule which provides additional -convenience methods for testing. This requires adding the `log4j-core` -`test-jar` dependency to your test scope dependencies. For example: - -[source,java] ----- -public class AwesomeTest { - @Rule - public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml"); - - @Test - public void testSomeAwesomeFeature() { - final LoggerContext ctx = init.getLoggerContext(); - final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger"); - final Configuration cfg = init.getConfiguration(); - final ListAppender app = init.getListAppender("List"); - logger.warn("Test message"); - final List events = app.getEvents(); - // etc. - } -} ----- +[#log4j-core-programmatic-configuration] +== Programmatic configuration -include::_properties.adoc[leveloffset=+1] +include::_properties.adoc[leveloffset=+1] \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc new file mode 100644 index 00000000000..50403d926a7 --- /dev/null +++ b/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc @@ -0,0 +1,1719 @@ +//// + 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] += Configuration +Ralph Goers + +[#Arbiters] +== Arbiters + +In some situations it is desirable to have a single logging configuration that can be used in any +deployment environment. For example, it may be necessary to have a different default logging level in +production then in development. Another case might be where one type of appender is used when running +natively but another is used when deployed to a docker container. One way to handle that is to use +a tool such as Spring Cloud Config Server that can be environment aware and serve a different file for +each environment. Another option is to include Arbiters in the configuration. + +An Arbiter is a Log4j plugin that has the job of determining whether other configured elements should be +included in the generated configuration. While all other "Core" plugins are designed to execute as part of +Log4j's runtime logic Arbiters execute after the Node tree has been constructed but before the tree is +converted to a configuration. An Arbiter is a Node itself which is always removed from the Node tree +before it the tree is processed. All an arbiter really does is provide a method that returns a boolean +result that determines whether the child nodes of the arbiter should remain in the configuration or be +pruned. + +Arbiters may occur anywhere an element is allowed in the configuration. So an Aribiter could encapsulate +something as simple as a single property declaration or a whole set of Appenders or Loggers. Arbiters +may also be nested although Arbiters that are the descendant of another arbiter will only be evalued if the +ancestor returned true. The child elements of an Arbiter must be valid elements for whatever element is +the parent of the Arbiter. + +This example shows two Arbiters configured that will include either a Console Appender or a List Appender +depending on whether the value of the env System Property is "dev" or "prod". + +[source,xml] +---- + + + + + + + + + + + + + + + + + + + + + + + +---- + +Normally Arbiters act in isolation from other Arbiters. That is, the outcome of one Arbiter will not +impact any other Arbiters. This can be cumbersome when you simply want to use one of a set of choices. A +special plugin named "Select" can be used in this case. Each element under the Select is required to be +an Arbiter. The first Arbiter that returns a true value will be the one used while others are ignored. +If no Arbiter returns true a DefaultAtrbiter may be configured with the default configuration elements. +The DefaultArbiter is an Arbiter that always returns true, so using it outside of a Select would result in +its configured elements always being included just as if it hadn't been present. + +This example shows an Arbiter that uses Javascript residing in a separate file to determine whether to +include the Console Appender. If the result is false then a List Appender will be included. + +[source,xml] +---- + + + + + + + + + + + + + +---- + +Natively Log4j contains the SystemProperty Arbiter that can evaluate whether to include elements based on +whether a SystemProperty is non-null or has a specific value, a ClassArbiter that makes its decision +based on whether the specified class is present, and a ScriptArbiter that makes its decision based +on the result of the script configured with it. + +For Spring Boot users an Arbiter named SpringProfile has been provided. The specified profiles +are evaluated by Spring's Environment.acceptsProfiles() method, so any expressions it supports +may be used as the name attribute. + +This example will use a Console Appender when the Spring profile is "dev" or "staging" and a List +Appender when the active profile is "prod". + +[source,xml] +---- + + + + + + + + + + + + + + + + + + + + + + + +---- + +* A +link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/ConsoleAppender.html[`ConsoleAppender`] +attached to the root logger. +* A +link:../javadoc/log4j-core/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`] +set to the pattern "%d\{HH:mm:ss.SSS} [%t] %-5level %logger\{36} - +%msg%n" attached to the ConsoleAppender + +Note that by default Log4j assigns the root logger to `Level.ERROR`. + +The output of MyApp would be similar to: + +.... +17:13:01.540 [main] ERROR com.foo.Bar - Did it again! +17:13:01.540 [main] ERROR MyApp - Didn't do it. +.... + +As was described previously, Log4j will first attempt to configure +itself from configuration files. A configuration equivalent to the +default would look like: + +[source,xml] +---- + + + + + + + + + + + + + +---- + +Once the file above is placed into the classpath as log4j2.xml you will +get results identical to those listed above. Changing the root level to +trace will result in results similar to: + +.... +17:13:01.540 [main] TRACE MyApp - Entering application. +17:13:01.540 [main] TRACE com.foo.Bar - entry +17:13:01.540 [main] ERROR com.foo.Bar - Did it again! +17:13:01.540 [main] TRACE com.foo.Bar - exit with (false) +17:13:01.540 [main] ERROR MyApp - Didn't do it. +17:13:01.540 [main] TRACE MyApp - Exiting application. +.... + +Note that status logging is disabled when the default configuration is +used. + +[#Configuration_From_a_URI] +== Configuration From a URI + +When `log4j2.configurationFile` references a URL, Log4j will first determine if the URL reference +a file using the file protocol. If it does Log4j will validate that the file URL is valid and continue +processing as previously described. If it contains a protocol other than file then Log4j will inspect +the value of the <> system property. If the provided list +contains the protocol specified then Log4j will use the URI to locate the specified configuration file. If +not an exception will be thrown and an error message will be logged. If no value is provided for the +system property it will default to "https". Use of any protocol other than "file" can be prevented by +setting the system property value to "_none". This value would be an invalid protocol so cannot conflict +with any custom protocols that may be present. + +Log4j supports access to remote URLs that require authentication. Log4j supports basic authentication +out of the box. If the `log4j2.Configuration.username` and `log4j2.Configuration.password` +are specified those values will be used to perform the authentication. If the password is encrypted a custom +password decryptor may be supplied by specifying the fully qualified class name in the +<> system property. A custom +`AuthenticationProvider` may be used by setting the +`<> system property to the fully qualified class name +of the provider. + +[#Additivity] +== Additivity + +Perhaps it is desired to eliminate all the TRACE output from everything +except `com.foo.Bar`. Simply changing the log level would not accomplish +the task. Instead, the solution is to add a new logger definition to the +configuration: + +[source,xml] +---- + + + + + + + +---- + +With this configuration all log events from `com.foo.Bar` will be +recorded while only error events will be recorded from all other +components. + +In the previous example all the events from `com.foo.Bar` were still +written to the Console. This is because the logger for `com.foo.Bar` did +not have any appenders configured while its parent did. In fact, the +following configuration + +[source,xml] +---- + + + + + + + + + + + + + + + + +---- + +would result in + +.... +17:13:01.540 [main] TRACE com.foo.Bar - entry +17:13:01.540 [main] TRACE com.foo.Bar - entry +17:13:01.540 [main] ERROR com.foo.Bar - Did it again! +17:13:01.540 [main] TRACE com.foo.Bar - exit (false) +17:13:01.540 [main] TRACE com.foo.Bar - exit (false) +17:13:01.540 [main] ERROR MyApp - Didn't do it. +.... + +Notice that the trace messages from `com.foo.Bar` appear twice. This is +because the appender associated with logger `com.foo.Bar` is first used, +which writes the first instance to the Console. Next, the parent of +`com.foo.Bar`, which in this case is the root logger, is referenced. The +event is then passed to its appender, which is also writes to the +Console, resulting in the second instance. This is known as additivity. +While additivity can be quite a convenient feature (as in the first +previous example where no appender reference needed to be configured), +in many cases this behavior is considered undesirable and so it is +possible to disable it by setting the additivity attribute on the logger +to false: + +[source,xml] +---- + + + + + + + + + + + + + + + + +---- + +Once an event reaches a logger with its additivity set to false the +event will not be passed to any of its parent loggers, regardless of +their additivity setting. + +[#AutomaticReconfiguration] +== Automatic Reconfiguration + +When configured from a File, Log4j has the ability to automatically +detect changes to the configuration file and reconfigure itself. If the +`monitorInterval` attribute is specified on the configuration element +and is set to a non-zero value then the file will be checked the next +time a log event is evaluated and/or logged and the monitorInterval has +elapsed since the last check. The example below shows how to configure +the attribute so that the configuration file will be checked for changes +only after at least 30 seconds have elapsed. The minimum interval is 5 +seconds. + +[source,xml] +---- + + +... + +---- + +[#ChainsawSupport] +== Chainsaw can automatically process your log files (Advertising appender configurations) + +Log4j provides the ability to 'advertise' appender configuration details +for all file-based appenders as well as socket-based appenders. For +example, for file-based appenders, the file location and the pattern +layout in the file are included in the advertisement. Chainsaw and other +external systems can discover these advertisements and use that +information to intelligently process the log file. + +The mechanism by which an advertisement is exposed, as well as the +advertisement format, is specific to each Advertiser implementation. An +external system which would like to work with a specific Advertiser +implementation must understand how to locate the advertised +configuration as well as the format of the advertisement. For example, a +'database' Advertiser may store configuration details in a database +table. An external system can read that database table in order to +discover the file location and the file format. + +Log4j provides one Advertiser implementation, a 'multicastdns' +Advertiser, which advertises appender configuration details via IP +multicast using the http://jmdns.sourceforge.net library. + +Chainsaw automatically discovers log4j's multicastdns-generated +advertisements and displays those discovered advertisements in +Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's +classpath). To begin parsing and tailing a log file provided in an +advertisement, just double-click the advertised entry in Chainsaw's +Zeroconf tab. Currently, Chainsaw only supports FileAppender +advertisements. + +To advertise an appender configuration: + +* Add the JmDns library from http://jmdns.sourceforge.net to the +application classpath +* Set the 'advertiser' attribute of the configuration element to +'multicastdns' +* Set the 'advertise' attribute on the appender element to 'true' +* If advertising a FileAppender-based configuration, set the +'advertiseURI' attribute on the appender element to an appropriate URI + +FileAppender-based configurations require an additional 'advertiseURI' +attribute to be specified on the appender. The 'advertiseURI' attribute +provides Chainsaw with information on how the file can be accessed. For +example, the file may be remotely accessible to Chainsaw via ssh/sftp by +specifying a Commons VFS (http://commons.apache.org/proper/commons-vfs/) +sftp:// URI, an http:// URI may be used if the file is accessible +through a web server, or a file:// URI can be specified if accessing the +file from a locally-running instance of Chainsaw. + +Here is an example advertisement-enabled appender configuration which +can be used by a locally-running Chainsaw to automatically tail the log +file (notice the file:// advertiseURI): + +*Please note, you must add the JmDNS library mentioned above.* + +[source,xml] +---- + + + ... + + + ... + + + +---- + +[#ConfigurationSyntax] +== Configuration Syntax + +As of version 2.9, for security reasons, Log4j does not process DTD in +XML files. If you want to split the configuration in multiple files, use +link:#XInclude[XInclude] or link:#CompositeConfiguration[Composite +Configuration]. + +As the previous examples have shown as well as those to follow, Log4j +allows you to easily redefine logging behavior without needing to modify +your application. It is possible to disable logging for certain parts of +the application, log only when specific criteria are met such as the +action being performed for a specific user, route output to Flume or a +log reporting system, etc. Being able to do this requires understanding +the syntax of the configuration files. + +The configuration element in the XML file accepts several attributes: + +[cols="1m,5a"] +|=== +|Attribute Name |Description + +|advertiser +|(Optional) The Advertiser plugin name which will be used to +advertise individual FileAppender or SocketAppender configurations. The +only Advertiser plugin provided is "multicastdns". + +|dest +|Either "err" for stderr, "out" for stdout, a file path, or a URL. + +|monitorInterval +|The minimum amount of time, in seconds, that must +elapse before the file configuration is checked for changes. + +|name +|The name of the configuration. + +|schema +|Identifies the location for the classloader to located the XML +Schema to use to validate the configuration. Only valid when strict is +set to true. If not set no schema validation will take place. + +|shutdownHook +|Specifies whether or not Log4j should automatically +shutdown when the JVM shuts down. The shutdown hook is enabled by +default but may be disabled by setting this attribute to "disable" + +|shutdownTimeout +|Specifies how many milliseconds appenders and +background tasks will get to shutdown when the JVM shuts down. Default +is zero which mean that each appender uses its default timeout, and +don't wait for background tasks. Not all appenders will honor this, it +is a hint and not an absolute guarantee that the shutdown procedure will +not take longer. Setting this too low increase the risk of losing +outstanding log events not yet written to the final destination. See +link:../javadoc/log4j-core/org/apache/logging/log4j/core/LoggerContext.html$%7Besc.hash%7Dstop(long,%20java.util.concurrent.TimeUnit)[LoggerContext.stop(long, +java.util.concurrent.TimeUnit)]. (Not used if `shutdownHook` is set to +"disable".) + +|status +|The level of internal Log4j events that should be logged to the console. +Valid values for this attribute are "off", "trace", "debug", "info", "warn", +"error", "fatal", and "all". Log4j will log details about initialization, +rollover and other internal actions to the status logger. Setting +`status="trace"` is one of the first tools available to you if you need +to troubleshoot log4j. + +(Alternatively, setting system property <> will also print +internal Log4j2 logging to the console, including internal logging that +took place before the configuration file was found.) + +|strict +|Enables the use of the strict XML format. Not supported in JSON +configurations. + +|verbose +|Enables diagnostic information while loading plugins. +|=== + +[[XML]] +=== Configuration with XML + +Log4j can be configured using two XML flavors; concise and strict. + +=== Concise Syntax + +The concise format makes configuration very easy as the element names match +the components they represent however it cannot be validated with an XML +schema. For example, the ConsoleAppender is configured by declaring an +XML element named Console under its parent appenders element. However, +element and attribute names are not case sensitive. In addition, +attributes can either be specified as an XML attribute or as an XML +element that has no attributes and has a text value. So + +[source,xml] +---- + +---- + +and + +[source,xml] +---- + + %m%n + +---- + +are equivalent. + +The file below represents the structure of an XML configuration, but +note that the elements in italics below represent the concise element +names that would appear in their place. + +[source,xml] +---- +; + + + value + + + + + + + + ... + + + + + + ... + + + + + +---- + +See the many examples on this page for sample appender, filter and +logger declarations. + +=== Strict XML + +In addition to the concise XML format above, Log4j allows configurations +to be specified in a more "normal" XML manner that can be validated +using an XML Schema. This is accomplished by replacing the friendly +element names above with their object type as shown below. For example, +instead of the ConsoleAppender being configured using an element named +Console it is instead configured as an appender element with a type +attribute containing "Console". + +[source,xml] +---- + + + + value + + + + + + + + ... + + + + + + ... + + + + + +---- + +Below is a sample configuration using the strict format. + +[source,xml] +---- + + + + target/test.log + + + + + + + + + + + + + + + + + + + + + %d %p %C{1.} [%t] %m%n + + + + + + + + + + + + + + + + + + + + + + +---- + +[#JSON] +=== Configuration with JSON + +In addition to XML, Log4j can be configured using JSON. The JSON format +is very similar to the concise XML format. Each key represents the name +of a plugin and the key/value pairs associated with it are its +attributes. Where a key contains more than a simple value it itself will +be a subordinate plugin. In the example below, ThresholdFilter, Console, +and PatternLayout are all plugins while the Console plugin will be +assigned a value of STDOUT for its name attribute and the +ThresholdFilter will be assigned a level of debug. + +[source,json] +---- +{ "configuration": { "status": "error", "name": "RoutingTest", + "packages": "org.apache.logging.log4j.test", + "properties": { + "property": { "name": "filename", + "value" : "target/rolling1/rollingtest-$${sd:type}.log" } + }, + "ThresholdFilter": { "level": "debug" }, + "appenders": { + "Console": { "name": "STDOUT", + "PatternLayout": { "pattern": "%m%n" }, + "ThresholdFilter": { "level": "debug" } + }, + "Routing": { "name": "Routing", + "Routes": { "pattern": "$${sd:type}", + "Route": [ + { + "RollingFile": { + "name": "Rolling-${sd:type}", "fileName": "${filename}", + "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", + "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, + "SizeBasedTriggeringPolicy": { "size": "500" } + } + }, + { "AppenderRef": "STDOUT", "key": "Audit"} + ] + } + } + }, + "loggers": { + "logger": { "name": "EventLogger", "level": "info", "additivity": "false", + "AppenderRef": { "ref": "Routing" }}, + "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} + } + } +} +---- + +Note that in the RoutingAppender the Route element has been declared as +an array. This is valid because each array element will be a Route +component. This won't work for elements such as appenders and filters, +where each element has a different name in the concise format. Appenders +and filters can be defined as array elements if each appender or filter +declares an attribute named "type" that contains the type of the +appender. The following example illustrates this as well as how to +declare multiple loggers as an array. + +[source,json] +---- +{ "configuration": { "status": "debug", "name": "RoutingTest", + "packages": "org.apache.logging.log4j.test", + "properties": { + "property": { "name": "filename", + "value" : "target/rolling1/rollingtest-$${sd:type}.log" } + }, + "ThresholdFilter": { "level": "debug" }, + "appenders": { + "appender": [ + { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }}, + { "type": "Routing", "name": "Routing", + "Routes": { "pattern": "$${sd:type}", + "Route": [ + { + "RollingFile": { + "name": "Rolling-${sd:type}", "fileName": "${filename}", + "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", + "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, + "SizeBasedTriggeringPolicy": { "size": "500" } + } + }, + { "AppenderRef": "STDOUT", "key": "Audit"} + ] + } + } + ] + }, + "loggers": { + "logger": [ + { "name": "EventLogger", "level": "info", "additivity": "false", + "AppenderRef": { "ref": "Routing" }}, + { "name": "com.foo.bar", "level": "error", "additivity": "false", + "AppenderRef": { "ref": "STDOUT" }} + ], + "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} + } + } +} +---- + +Additional xref:runtime-dependencies.adoc[runtime dependencies] are +required for using JSON configuration files. + +[#YAML] +=== Configuration with YAML + +Log4j also supports using YAML for configuration files. The structure +follows the same pattern as both the XML and YAML configuration formats. +For example: + +[source,yaml] +---- +Configuration: + status: warn + name: YAMLConfigTest + properties: + property: + name: filename + value: target/test-yaml.log + thresholdFilter: + level: debug + appenders: + Console: + name: STDOUT + target: SYSTEM_OUT + PatternLayout: + Pattern: "%m%n" + File: + name: File + fileName: ${filename} + PatternLayout: + Pattern: "%d %p %C{1.} [%t] %m%n" + Filters: + ThresholdFilter: + level: error + + Loggers: + logger: + - + name: org.apache.logging.log4j.test1 + level: debug + additivity: false + ThreadContextMapFilter: + KeyValuePair: + key: test + value: 123 + AppenderRef: + ref: STDOUT + - + name: org.apache.logging.log4j.test2 + level: debug + additivity: false + AppenderRef: + ref: File + Root: + level: error + AppenderRef: + ref: STDOUT + +---- + +Additional xref:runtime-dependencies.adoc[runtime dependencies] are +required for using YAML configuration files. + +[#Properties] +=== Configuration with Properties + +As of version 2.4, Log4j now supports configuration via properties +files. Note that the property syntax is NOT the same as the syntax used +in Log4j 1. Like the XML and JSON configurations, properties +configurations define the configuration in terms of plugins and +attributes to the plugins. + +Prior to version 2.6, the properties configuration requires that you +list the identifiers of the appenders, filters and loggers, in a comma +separated list in properties with those names. Each of those components +will then be expected to be defined in sets of properties that begin +with _component.<.identifier>._. The identifier does not have to match +the name of the component being defined but must uniquely identify all +the attributes and subcomponents that are part of the component. If the +list of identifiers is not present the identifier must not contain a '.'. +Each individual component MUST have a "type" attribute specified that +identifies the component's Plugin type. + +As of version 2.6, this list of identifiers is no longer required as +names are inferred upon first usage, however if you wish to use more +complex identifies you must still use the list. If the list is present +it will be used. + +Unlike the base components, when creating subcomponents you cannot +specify an element containing a list of identifiers. Instead, you must +define the wrapper element with its type as is shown in the policies +definition in the rolling file appender below. You then define each of +the subcomponents below that wrapper element, as the +TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are defined +below. + +As of version 2.17.2, `rootLogger` and `logger._key_` properties can be specified to set the +level and zero or more appender refs to create for that logger. The level and appender refs are +separated by comma `,` characters with optional whitespace surrounding the comma. The +following example demonstrates how the shorthand is expanded when reading properties configurations. + +[source,properties] +---- +appender.stdout.type = Console +# ... other appender properties +appender.file.type = File +# ... other appender properties +logger.app = INFO, stdout, file +logger.app.name = com.example.app + +# is equivalent to: +# appender.stdout.type = Console +# appender.stdout.name = stdout +# ... +appender.file.type = File +appender.file.name = file +# ... +logger.app.name = com.example.app +logger.app.level = INFO +logger.app.appenderRef.$1.ref = stdout +logger.app.appenderRef.$2.ref = file +---- + +Properties configuration files support the advertiser, monitorInterval, +name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest +attributes. See link:#ConfigurationSyntax[Configuration Syntax] for the +definitions of these attributes. + +[source,properties] +---- +status = error +dest = err +name = PropertiesConfig + +property.filename = target/rolling/rollingtest.log + +filter.threshold.type = ThresholdFilter +filter.threshold.level = debug + +appender.console.type = Console +appender.console.name = STDOUT +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = %m%n +appender.console.filter.threshold.type = ThresholdFilter +appender.console.filter.threshold.level = error + +appender.rolling.type = RollingFile +appender.rolling.name = RollingFile +appender.rolling.fileName = ${filename} +appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz +appender.rolling.layout.type = PatternLayout +appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n +appender.rolling.policies.type = Policies +appender.rolling.policies.time.type = TimeBasedTriggeringPolicy +appender.rolling.policies.time.interval = 2 +appender.rolling.policies.time.modulate = true +appender.rolling.policies.size.type = SizeBasedTriggeringPolicy +appender.rolling.policies.size.size=100MB +appender.rolling.strategy.type = DefaultRolloverStrategy +appender.rolling.strategy.max = 5 + +logger.rolling.name = com.example.my.app +logger.rolling.level = debug +logger.rolling.additivity = false +logger.rolling.appenderRef.rolling.ref = RollingFile + +rootLogger.level = info +rootLogger.appenderRef.stdout.ref = STDOUT + +---- + + +[#Loggers] +=== Configuring Loggers + +An understanding of how loggers work in Log4j is critical before trying +to configure them. Please reference the Log4j +xref:manual/architecture.adoc[architecture] if more information is required. +Trying to configure Log4j without understanding those concepts will lead +to frustration. + +A LoggerConfig is configured using the `logger` element. The `logger` +element must have a name attribute specified, will usually have a level +attribute specified and may also have an additivity attribute specified. +The level may be configured with one of TRACE, DEBUG, INFO, WARN, ERROR, +ALL or OFF. If no level is specified it will default to ERROR. The +additivity attribute may be assigned a value of true or false. If the +attribute is omitted the default value of true will be used. + +Capturing location information (the class name, file name, method name, and line number of the caller) +can be slow. Log4j tries to optimize this by reducing the size of the stack that must be traversed +to find the caller of the logging method. It does this by determining if any component that might +be accessed requires location information. This can cause performance issues if a logger is configured +at a level like trace or debug with the expectation that most logs will be filtered on an Appender +reference or Appender as Log4j will calculate the location information even though the log event +is going to be discarded. To disable this behavior the `includeLocation` attribute +can be set to false on the LoggerConfig. This will cause Log4j to defer calculating the location +information until absolutely necessary. + +A LoggerConfig (including the root LoggerConfig) can be configured with +properties that will be added to the properties copied from the +ThreadContextMap. These properties can be referenced from Appenders, +Filters, Layouts, etc just as if they were part of the ThreadContext +Map. The properties can contain variables that will be resolved either +when the configuration is parsed or dynamically when each event is +logged. See link:#PropertySubstitution[Property Substitution] for more +information on using variables. + +The LoggerConfig may also be configured with one or more AppenderRef +elements. Each appender referenced will become associated with the +specified LoggerConfig. If multiple appenders are configured on the +LoggerConfig each of them be called when processing logging events. + +*_Every configuration must have a root logger_*. If one is not +configured the default root LoggerConfig, which has a level of ERROR and +has a Console appender attached, will be used. The main differences +between the root logger and other loggers are + +1. The root logger does not have a name attribute. +2. The root logger does not support the additivity attribute since it +has no parent. + +[#Appenders] +=== Configuring Appenders + +An appender is configured either using the specific appender plugin's +name or with an appender element and the type attribute containing the +appender plugin's name. In addition each appender must have a name +attribute specified with a value that is unique within the set of +appenders. The name will be used by loggers to reference the appender as +described in the previous section. + +Most appenders also support a layout to be configured (which again may +be specified either using the specific Layout plugin's name as the +element or with "layout" as the element name along with a type attribute +that contains the layout plugin's name. The various appenders will +contain other attributes or elements that are required for them to +function properly. + +[#Filters] +=== Configuring Filters + +Log4j allows a filter to be specified in any of 4 places: + +1. At the same level as the appenders, loggers and properties elements. +These filters can accept or reject events before they have been passed +to a LoggerConfig. +2. In a logger element. These filters can accept or reject events for +specific loggers. +3. In an appender element. These filters can prevent or cause events to +be processed by the appender. +4. In an appender reference element. These filters are used to +determine if a Logger should route the event to an appender. + +Although only a single `filter` element can be configured, that element +may be the `filters` element which represents the CompositeFilter. The +`filters` element allows any number of `filter` elements to be +configured within it. The following example shows how multiple filters +can be configured on the ConsoleAppender. + +[source,xml] +---- + + + + target/test.log + + + + + + + + + + + + + + + + + + %d %p %C{1.} [%t] %m%n + + + + + + + + + + + + + + ${sys:user.name} + + + + + + + + + + + + + + +---- + +[#PropertySubstitution] +== Property Substitution + +Log4j 2 supports the ability to specify tokens in the configuration as +references to properties defined elsewhere. Some of these properties +will be resolved when the configuration file is interpreted while others +may be passed to components where they will be evaluated at runtime. To +accomplish this, Log4j uses variations of +https://commons.apache.org/proper/commons-lang/[Apache Commons Lang]'s +link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`] +and +link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] +classes. In a manner similar to Ant or Maven, this allows variables +declared as `$\{name}` to be resolved using properties declared in the +configuration itself. For example, the following example shows the +filename for the rolling file appender being declared as a property. + +[source,xml] +---- + + + + target/rolling1/rollingtest-$${sd:type}.log + + + + + + + + + + + + + + %d %p %c{1.} [%t] %m%n + + + + + + + + + + + + + + + + + + + + +---- + +While this is useful, there are many more places properties can +originate from. To accommodate this, Log4j also supports the syntax +`${prefix:name}` where the prefix identifies tells Log4j that variable +name should be evaluated in a specific context. See the +xref:manual/lookups.adoc[Lookups] manual page for more details. The contexts +that are built in to Log4j are: + +[cols="1m,5"] +|=== +|Prefix |Context + + + base64 + + Base64 encoded data. The format is ${base64:Base64_encoded_data}. + For example: + ${base64:SGVsbG8gV29ybGQhCg==} yields Hello World!. + + + +|base64 +|Base64 encoded data. The format is `${base64:Base64_encoded_data}`. +For example: `${base64:SGVsbG8gV29ybGQhCg==}` yields `Hello World!`. + +|bundle +|Resource bundle. The format is `${bundle:BundleName:BundleKey}`. +The bundle name follows package naming conventions, for example: +`${bundle:com.domain.Messages:MyKey}`. + +|ctx +|Thread Context Map (MDC) + +|date +|Inserts the current date and/or time using the specified format + +|docker +| Returns attributes from the Docker container the application is running in. The format is ${docker:some.attribute}. See xref:log4j-docker.adoc[Docker documentation] for requirements and a list of available attributes. + +|env +|System environment variables. The formats are `${env:ENV_NAME}` and `${env:ENV_NAME:-default_value}`. + +| event +| Retrieves values from fields within the log event. The format is ${event:some.field}. See the Lookups manual page for a list of available fields. +| java +| Retrieves information about the Java environment the application is running in. The format is ${java:some.property}. See the Lookups manual page for a list of available properties. + +|jndi +|A value set in the default JNDI Context. + +|jvmrunargs +|A JVM input argument accessed through JMX, but not a main argument; see +https://docs.oracle.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[RuntimeMXBean.getInputArguments()]. +Not available on Android. + +| k8s +| Returns attributes from the Kubernetes environment the application is running in. The format is ${k8s:some.attribute}. See the Lookups manual page for a list of available attributes. + +|log4j +|Log4j configuration properties. The expressions +`${log4j:configLocation}` and `${log4j:configParentLocation}` +respectively provide the absolute path to the log4j configuration file +and its parent folder. + +| lower +| Converts the passed in argument to lower case (usually used with nested lookups). The format is ${lower:argument}. + +|main +|A value set with +../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments-java.lang.String:A-[MapLookup.setMainArguments(String[])] + +|map +|A value from a MapMessage + +| marker +| Allows use of markers in configurations. The formats are ${marker:} and ${marker:some.name}. See the Lookups manual page for further details. + +|sd +|A value from a StructuredDataMessage. The key "id" will return the +name of the StructuredDataId without the enterprise number. The key +"type" will return the message type. Other keys will retrieve individual +elements from the Map. + +| spring +| Returns values of Spring properties from the Spring configuration. The format is ${spring:some.property}. See the Lookups manual page for requirements and details. + +|sys +|System properties. The formats are `${sys:some.property}` and +`${sys:some.property:-default_value}`. + +| upper +| Converts the passed in argument to upper case (usually used with nested lookups). The format is ${upper:argument}. +| web +| Returns values of variables associated with the Servlet Context. The format is ${spring:some.key}. See the Lookups manual page for a list of available keys. +|=== + +[#DefaultProperties] +== Default Properties +A default property map can be declared in the configuration file by placing a Properties +element directly after the Configuration element and before any Loggers, Filters, +Appenders, etc. are declared. If the value cannot be located in the specified lookup the +value in the default property map will be used. The default map is pre-populated with a value +for "hostName" that is the current system's host name or IP address and +the "contextName" with is the value of the current logging context. See many places +a Properties element is used in this section for examples. + +Default properties may also be specified in the Lookup by using the syntax `${lookupName:key:-defaultValue}`. +In some cases the key might contain a leading '-'. When this is the case an escape character must be +included, such as ``${main:\--file:-app.properties}`. This would use the +`MainMapLookup` for a key named `--file`. If the key is not found then +app.properties would be used as the default value. + +[#EnablingMessagePatternLookups] +== Enabling Message Pattern Lookups +A message is processed (by default) without using lookups, for example if you defined +`FOO_BAR`, then `logger.info("${foo.bar}")` will output `${foo.bar}` instead of `FOO_BAR`. +You could enable message pattern lookups by defining the message pattern using `%m\{lookups}`. + +[#RuntimeLookup] +== Lookup Variables with Multiple Leading '$' Characters + +An interesting feature of StrLookup processing is that when a variable +reference is declared with multiple leading '$' characters each time the +variable is resolved the leading '$' is simply removed. In the previous +example the "Routes" element is capable of resolving the variable at +runtime. To allow this the prefix value is specified as a variable with +two leading '$' characters. When the configuration file is first +processed the first '$' character is simply removed. Thus, when the +Routes element is evaluated at runtime it is the variable declaration +"$\{sd:type}" which causes the event to be inspected for a +StructuredDataMessage and if one is present the value of its type +attribute to be used as the routing key. Not all elements support +resolving variables at runtime. Components that do will specifically +call that out in their documentation. + +If no value is found for the key in the Lookup associated with the +prefix then the value associated with the key in the properties +declaration in the configuration file will be used. If no value is found +the variable declaration will be returned as the value. Default values +may be declared in the configuration by doing: + +[source,xml] +---- + + + + Audit + + ... + +---- + +_As a footnote, it is worth pointing out that the variables in the +RollingFile appender declaration will also not be evaluated when the +configuration is processed. This is simply because the resolution of the +whole RollingFile element is deferred until a match occurs. See +xref:manual/appenders.adoc#RoutingAppender[RoutingAppender] for more +information._ + +[#Scripts] +== Scripts + +Log4j provides support for +https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR +223] scripting languages to be used in some of its components. Any +language that provides support for the JSR 223 scripting engine may be +used. A list of the languages and bindings for them can be found at the +https://java.net/projects/scripting/sources/svn/show/trunk/engines[Scripting +Engine] web site. However, some of the languages listed there, such as +JavaScript, Groovy and Beanshell, directly support the JSR 223 scripting +framework and only require that the jars for that language be installed. + +As of Log4j 2.17.2 the languages to be supported must be specified as a comma separated list in the +`log4j2.Script.enableLanguages` system property. + +The components that support using scripts do so by allowing a ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +---- + +If the status attribute on the Configuration element is set to DEBUG the +list of script engines currently installed and their attributes will be +listed. Although some engines may say they are not thread safe, Log4j +takes steps to insure that the scripts will run in a thread-safe manner +if the engine advertises that it is not thread safe. + +.... +2015-09-27 16:13:22,925 main DEBUG Installed script engines +2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe, + Compile: false, Names: {AppleScriptEngine, AppleScript, OSA} +2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED, + Compile: true, Names: {groovy, Groovy} +2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED, + Compile: true, Names: {beanshell, bsh, java} +2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED, + Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript} +.... + +When the scripts are executed they will be provided with a set of +variables that should allow them to accomplish whatever task they are +expected to perform. See the documentation for the individual components +for the list of variables that are available to the script. + +The components that support scripting expect a return value to be passed +back to the calling Java code. This is not a problem for several of the +scripting languages, but Javascript does not allow a return statement +unless it is within a function. However, Javascript will return the +value of the last statement executed in the script. As a consequence, +code such as that shown below will result in the desired behavior. + +[source,javascript] +---- +var result; +if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { + result = "NoLocation"; +} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { + result = "Flow"; +} +result; +---- + +=== A special note on Beanshell + +JSR 223 scripting engines are supposed to identify that they support the +Compilable interface if they support compiling their scripts. Beanshell +does this. However, whenever the compile method is called it throws an +Error (not an Exception). Log4j catches this but will log the warning +shown below for each Beanshell script when it tries to compile them. All +Beanshell scripts will then be interpreted on each execution. + +.... +2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable +2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented + at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175) + at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154) + at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.(ScriptManager.java:125) + at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94) + +.... + +[#XInclude] +== XInclude + +XML configuration files can include other files with +http://www.xml.com/lpt/a/1009[XInclude]. Here is an example log4j2.xml +file that includes two other files: + +.log4j2.xml +[source,xml] +---- + + + + xinclude-demo.log + + + + + +---- + +.log4j-xinclude-appenders.xml +[source,xml] +---- + + + + + + + + %d %p %C{1.} [%t] %m%n + + + +---- + +.log4j-xinclude-loggers.xml +[source,xml] +---- + + + + + + + + + + + + + + + + + +---- + +[#CompositeConfiguration] +== Composite Configuration + +Log4j allows multiple configuration files to be used by specifying them +as a list of comma separated file paths on log4j2.configurationFile or, +when using URLs, by adding secondary configuration locations as query +parameters named "override". The merge logic can be controlled by specifying +a class that implements the MergeStrategy interface on the log4j.mergeStrategy +property. The default merge strategy will merge the files using the following rules: + +1. The global configuration attributes are aggregated with those in +later configurations replacing those in previous configurations, with +the exception that the highest status level and the lowest +monitorInterval greater than 0 will be used. +2. Properties from all configurations are aggregated. Duplicate +properties replace those in previous configurations. +3. Filters are aggregated under a CompositeFilter if more than one +Filter is defined. Since Filters are not named duplicates may be +present. +4. Scripts and ScriptFile references are aggregated. Duplicate +definitions replace those in previous configurations. +5. Appenders are aggregated. Appenders with the same name are replaced +by those in later configurations, including all of the Appender's +subcomponents. +6. Loggers are all aggregated. Logger attributes are individually +merged with duplicates being replaced by those in later configurations. +Appender references on a Logger are aggregated with duplicates being +replaced by those in later configurations. Filters on a Logger are +aggregated under a CompositeFilter if more than one Filter is defined. +Since Filters are not named duplicates may be present. Filters under +Appender references included or discarded depending on whether their +parent Appender reference is kept or discarded. + +[#StatusMessages] +== Status Messages + +**** +*Troubleshooting tip for the impatient:* + +From log4j-2.9 onward, log4j2 will print all internal logging to the +console if system property `log4j2.debug` is either defined empty or its value +equals to `true` (ignoring case). + +Prior to log4j-2.9, there are two places where internal logging can be +controlled: + +* Before a configuration is found, status logger level can be controlled +with system property +`org.apache.logging.log4j.simplelog.StatusLogger.level`. +* After a configuration is found, status logger level can be controlled +in the configuration file with the "status" attribute, for example: +``. +**** + +Just as it is desirable to be able to diagnose problems in applications, +it is frequently necessary to be able to diagnose problems in the +logging configuration or in the configured components. Since logging has +not been configured, "normal" logging cannot be used during +initialization. In addition, normal logging within appenders could +create infinite recursion which Log4j will detect and cause the +recursive events to be ignored. To accomodate this need, the Log4j 2 API +includes a +link:../javadoc/log4j-api/org/apache/logging/log4j/status/StatusLogger.html[`StatusLogger`]. +Components declare an instance of the StatusLogger similar to: + +[source,java] +---- +protected final static Logger logger = StatusLogger.getLogger(); +---- + +Since StatusLogger implements the Log4j 2 API's Logger interface, all +the normal Logger methods may be used. + +When configuring Log4j it is sometimes necessary to view the generated status events. +This can be accomplished by adding the status attribute to the configuration element or a default value can be provided by setting the xref:statusLoggerLevel["log4j2.statusLoggerLevel"] system property. +Valid values of the status attribute are "trace", "debug", "info", "warn", "error" and "fatal". +The following configuration has the status attribute set to debug. + +[source,xml] +---- + + + + target/rolling1/rollingtest-$${sd:type}.log + + + + + + + + + + + + + + %d %p %c{1.} [%t] %m%n + + + + + + + + + + + + + + + + + + + + +---- + +During startup this configuration produces: + +.... +2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds +2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${sd:type}.log") +2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${sd:type}.log}) +2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds +2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") +2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null") +2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds +2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null") +2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") +2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route) +2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route) +2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit')}) +2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null) +2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing}) +2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing") +2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null) +2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT") +2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null) +2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root}) +2011-11-23 17:08:00,834 DEBUG Reconfiguration completed +2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null") +2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500") +2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null") +2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds +2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher$AppClassLoader@37b90b39 +2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds +2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds +2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds +2011-11-23 17:08:00,965 WARN No Loggers were configured, using default +2011-11-23 17:08:00,976 DEBUG Reconfiguration completed +.... + +If the status attribute is set to error then only error messages will be +written to the console. This makes troubleshooting configuration errors +possible. As an example, if the configuration above is changed to have +the status set to error and the logger declaration is: + +[source,xml] +---- + + + +---- + +the following error message will be produced. + +.... +2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger +.... + +Applications may wish to direct the status output to some other +destination. This can be accomplished by setting the dest attribute to +either "err" to send the output to stderr or to a file location or URL. +This can also be done by insuring the configured status is set to OFF +and then configuring the application programmatically such as: + +[source,java] +---- +StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR); +StatusLogger.getLogger().registerListener(listener); +---- + +[#UnitTestingInMaven] +== Testing in Maven + +Maven can run unit and functional tests during the build cycle. By +default, any files placed in `src/test/resources` are automatically +copied to target/test-classes and are included in the classpath during +execution of any tests. As such, placing a log4j2-test.xml into this +directory will cause it to be used instead of a log4j2.xml or +log4j2.json that might be present. Thus a different log configuration +can be used during testing than what is used in production. + +A second approach, which is extensively used by Log4j 2, is to set the +log4j2.configurationFile property in the method annotated with +@BeforeClass in the junit test class. This will allow an arbitrarily +named file to be used during the test. + +A third approach, also used extensively by Log4j 2, is to use the +`LoggerContextRule` JUnit test rule which provides additional +convenience methods for testing. This requires adding the `log4j-core` +`test-jar` dependency to your test scope dependencies. For example: + +[source,java] +---- +public class AwesomeTest { + @Rule + public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml"); + + @Test + public void testSomeAwesomeFeature() { + final LoggerContext ctx = init.getLoggerContext(); + final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger"); + final Configuration cfg = init.getConfiguration(); + final ListAppender app = init.getListAppender("List"); + logger.warn("Test message"); + final List events = app.getEvents(); + // etc. + } +} +---- + diff --git a/src/site/antora/modules/ROOT/pages/manual/installation.adoc b/src/site/antora/modules/ROOT/pages/manual/installation.adoc index 5ced130c91a..c2d46c7d452 100644 --- a/src/site/antora/modules/ROOT/pages/manual/installation.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/installation.adoc @@ -634,77 +634,7 @@ rootLogger.appenderRef.0.ref = CONSOLE In order to use these formats, the following additional dependencies are required: -[tabs] -==== - -Maven:: -+ -[tabs] -===== - -log4j2.xml:: -+ -No dependency required. - -log4j2.json:: -+ -[source,xml,subs="+attributes"] ----- - - com.fasterxml.jackson.core - jackson-databind - {jackson-version} - runtime - ----- - -log4j2.yaml:: -+ -[source,xml,subs="+attributes"] ----- - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - {jackson-version} - runtime - ----- - -log4j2.properties:: -+ -No dependency required. - -===== - -Gradle:: -+ -[tabs] -===== - -log4j2.xml:: -+ -No dependency required. - -log4j2.json:: -+ -[source,groovy,subs="+attributes"] ----- -runtimeOnly 'com.fasterxml.jackson.core:jackson-databind:{jackson-version}' ----- - -log4j2.yaml:: -+ -[source,groovy,subs="+attributes"] ----- -runtimeOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:{jackson-version}' ----- - -log4j2.properties:: -+ -No dependency required. - -===== -==== +include::partial$configuration-file-format-deps.adoc[] [#impl-jul] === Installing JUL diff --git a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc index 87ee914bea9..1b16a5eddf5 100644 --- a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc @@ -512,8 +512,8 @@ JSON Template Layout will render JSON documents as follows: See xref:manual/json-template-layout.adoc[JSON Template Layout] page for the complete documentation. -[#PatternLayout] -== Pattern Layout +[id=pattern-layout] +== [[PatternLayout]] Pattern Layout A flexible layout configurable with pattern string. The goal of this class is to format a LogEvent and return the results. The format of the diff --git a/src/site/antora/modules/ROOT/pages/manual/migration.adoc b/src/site/antora/modules/ROOT/pages/manual/migration.adoc index 202cae8d919..6bb50d23060 100644 --- a/src/site/antora/modules/ROOT/pages/manual/migration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/migration.adoc @@ -39,7 +39,7 @@ image:whichjar-log4j-1.2-api.png[Using log4j 2 via the log4j 1.x API] For most applications this is sufficient. This is a low-effort way to migrate, and may also allow for migration to proceed gradually over time. -[#EnablingLog4j12Bridge] +[id=enabling-the-log4j-1-x-bridge] === Enabling the Log4j 1.x bridge Enable the Log4j 1.x bridge via one of the following steps: diff --git a/src/site/antora/modules/ROOT/pages/manual/webapp.adoc b/src/site/antora/modules/ROOT/pages/manual/webapp.adoc index 2ec1cef20f5..2c5faf85494 100644 --- a/src/site/antora/modules/ROOT/pages/manual/webapp.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/webapp.adoc @@ -30,6 +30,7 @@ In either case, you'll need to add the `log4j-web` module to your deployment. To avoid problems, the Log4j shutdown hook will automatically be disabled when the log4j-web jar is included. ==== +[id=configuration] === Configuration Log4j allows the configuration file to be specified in web.xml using the `log4jConfiguration` context parameter. Log4j will search for configuration files by: diff --git a/src/site/antora/modules/ROOT/partials/configuration-file-format-deps.adoc b/src/site/antora/modules/ROOT/partials/configuration-file-format-deps.adoc new file mode 100644 index 00000000000..9b5e4c2ad51 --- /dev/null +++ b/src/site/antora/modules/ROOT/partials/configuration-file-format-deps.adoc @@ -0,0 +1,88 @@ +//// + 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:: ++ +[tabs] +===== + +log4j2.xml:: ++ +No dependency required. + +log4j2.json:: ++ +[source,xml,subs="+attributes"] +---- + + com.fasterxml.jackson.core + jackson-databind + {jackson-version} + runtime + +---- + +log4j2.yaml:: ++ +[source,xml,subs="+attributes"] +---- + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + {jackson-version} + runtime + +---- + +log4j2.properties:: ++ +No dependency required. + +===== + +Gradle:: ++ +[tabs] +===== + +log4j2.xml:: ++ +No dependency required. + +log4j2.json:: ++ +[source,groovy,subs="+attributes"] +---- +runtimeOnly 'com.fasterxml.jackson.core:jackson-databind:{jackson-version}' +---- + +log4j2.yaml:: ++ +[source,groovy,subs="+attributes"] +---- +runtimeOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:{jackson-version}' +---- + +log4j2.properties:: ++ +No dependency required. + +===== +==== \ No newline at end of file From f6c630885dce21ca35fe868dd46c3578da182cf4 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Fri, 10 May 2024 23:36:29 +0200 Subject: [PATCH 02/24] Revamp configuration page --- .../ROOT/examples/configuration/filters.json | 37 + .../examples/configuration/filters.properties | 23 + .../ROOT/examples/configuration/filters.xml | 24 + .../ROOT/examples/configuration/filters.yaml | 26 + .../configuration/logger-properties.json | 29 + .../logger-properties.properties | 15 + .../configuration/logger-properties.xml | 19 + .../configuration/logger-properties.yaml | 18 + .../examples/configuration/main-elements.json | 48 + .../configuration/main-elements.properties | 25 + .../examples/configuration/main-elements.xml | 25 + .../examples/configuration/main-elements.yaml | 27 + .../examples/configuration/properties.json | 17 + .../configuration/properties.properties | 3 + .../examples/configuration/properties.xml | 12 + .../examples/configuration/properties.yaml | 8 + .../ROOT/examples/configuration/routing.json | 34 + .../examples/configuration/routing.properties | 20 + .../ROOT/examples/configuration/routing.xml | 27 + .../ROOT/examples/configuration/routing.yaml | 20 + .../modules/ROOT/pages/manual/appenders.adoc | 4 +- .../ROOT/pages/manual/architecture.adoc | 1 + .../ROOT/pages/manual/configuration.adoc | 534 +++++++-- .../properties.adoc} | 0 .../ROOT/pages/manual/configuration_old.adoc | 1004 ----------------- .../modules/ROOT/pages/manual/filters.adoc | 89 +- .../modules/ROOT/pages/manual/lookups.adoc | 8 +- .../modules/ROOT/pages/plugin-reference.adoc | 765 +++++++++++++ .../properties-configuration-factory.adoc | 2 + .../properties-transport-security.adoc | 2 +- 30 files changed, 1716 insertions(+), 1150 deletions(-) create mode 100644 src/site/antora/modules/ROOT/examples/configuration/filters.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/filters.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/filters.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/filters.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/logger-properties.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/logger-properties.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/logger-properties.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/main-elements.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/main-elements.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/main-elements.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/properties.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/properties.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/properties.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/properties.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/routing.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/routing.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/routing.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/routing.yaml rename src/site/antora/modules/ROOT/pages/manual/{_properties.adoc => configuration/properties.adoc} (100%) diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.json b/src/site/antora/modules/ROOT/examples/configuration/filters.json new file mode 100644 index 00000000000..62401f52d77 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.json @@ -0,0 +1,37 @@ +{ + "Configuration": { + "Appenders": { + "Console": { + "name": "CONSOLE", + "ThresholdFilter": { + "level": "WARN" // <6> + } + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "ThresholdFilter": { // <3> + "level": "DEBUG" + }, + "AppenderRef": { + "ref": "CONSOLE", + "level": "WARN", // <5> + "MarkerFilter": { // <4> + "marker": "ALERT", + "onMatch": "NEUTRAL", + "onMismatch": "DENY" + } + } + }, + "Logger": { + "name": "org.example", + "level": "TRACE" // <2> + } + } + }, + "MarkerFilter": { // <1> + "marker": "PRIVATE", + "onMismatch": "NEUTRAL" + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.properties b/src/site/antora/modules/ROOT/examples/configuration/filters.properties new file mode 100644 index 00000000000..8f0dd88e9d4 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.properties @@ -0,0 +1,23 @@ +appender.0.type = Console +appender.0.name = CONSOLE +appender.0.filter.type = ThresholdFilter # <6> +appender.0.filter.level = WARN + +rootLogger.level = INFO +rootLogger.filter.type = ThresholdFilter # <3> +rootLogger.filter.level = DEBUG +rootLogger.appenderRef.0.ref = CONSOLE +rootLogger.appenderRef.0.level = WARN # <5> +rootLogger.appenderRef.0.filter.type = MarkerFilter # <4> +rootLogger.appenderRef.0.filter.marker = ALERT +rootLogger.appenderRef.0.filter.onMatch = NEUTRAL +rootLogger.appenderRef.0.filter.onMismatch = DENY + +logger.0.name = org.example +logger.0.level = DEBUG # <2> +logger.0.filter.type = ThresholdFilter # <3> +logger.0.filter.level = TRACE + +filter.type = MarkerFilter # <1> +filter.marker = PRIVATE +filter.onMismatch = NEUTRAL diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.xml b/src/site/antora/modules/ROOT/examples/configuration/filters.xml new file mode 100644 index 00000000000..4a8cb288b3d --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.yaml b/src/site/antora/modules/ROOT/examples/configuration/filters.yaml new file mode 100644 index 00000000000..738166b9a2c --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.yaml @@ -0,0 +1,26 @@ +Configuration: + Appenders: + Console: + name: "CONSOLE" + ThresholdFilter: # <6> + level: "WARN" + Loggers: + Root: + level: "INFO" + ThreadsholdFilter: # <3> + level: "DEBUG" + AppenderRef: + ref: "CONSOLE" + level: "WARN" # <5> + MarkerFilter: # <4> + marker: "ALERT" + onMatch: "NEUTRAL" + onMismatch: "DENY" + Logger: + name: "org.example" + level: "TRACE" # <2> + ThresholdFilter: + level: "TRACE" # <3> + MarkerFilter: # <1> + marker: "PRIVATE" + onMismatch: "NEUTRAL" \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.json b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.json new file mode 100644 index 00000000000..725de4263b7 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.json @@ -0,0 +1,29 @@ +{ + "Configuration": { + "Appenders": {}, + "Loggers": { + // tag::loggers[] + "Root": { + "Property": { + "name": "client.address", + "value": "$${web:request.remoteAddress}" + } + }, + "Logger": [ + { + "name": "org.hibernate", + "Property": { + "subsystem": "Database" + } + }, + { + "name": "io.netty", + "Property": { + "subsystem": "Networking" + } + } + ] + // end::loggers[] + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.properties b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.properties new file mode 100644 index 00000000000..252408fb3ff --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.properties @@ -0,0 +1,15 @@ +# tag::loggers[] +rootLogger.property.type = Property +rootLogger.name = client.address +rootLogger.value = $${web:request.remoteAddress} + +logger.0.name = org.hibernate +logger.0.property.type = Property +logger.0.property.name = subsystem +logger.0.property.value = Database + +logger.1.name = io.netty +logger.1.property.type = Property +logger.1.property.name = subsystem +logger.1.property.value = Networking +# end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml new file mode 100644 index 00000000000..a48f4e43679 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.yaml b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.yaml new file mode 100644 index 00000000000..74a90caa886 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.yaml @@ -0,0 +1,18 @@ +Configuration: + Appenders: {} + Loggers: + # tag::loggers[] + Root: + Property: + name: "client.address" + value: "$${web:request.remoteAddress}" + Logger: + - name: "org.hibernate" + Property: + name: "subsystem" + value: "Database" + - name: "io.netty" + Property: + name: "subsystem" + value: "Networking" + # end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.json b/src/site/antora/modules/ROOT/examples/configuration/main-elements.json new file mode 100644 index 00000000000..1ab763c201e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.json @@ -0,0 +1,48 @@ +{ + "Configuration": { + "Appenders": { + "Console": { // <1> + "name": "CONSOLE", + "target": "SYSTEM_OUT", + "PatternLayout": { + "pattern": "%p - %m%n" + } + }, + "File": [ + { // <2> + "name": "MAIN", + "fileName": "logs/main.log", + "JsonTemplateLayout": {} + }, + { // <3> + "name": "DEBUG_LOG", + "fileName": "logs/debug.log", + "PatternLayout": { + "pattern": "%d [%t] %p %c - %m%n" + } + } + ] + }, + "Loggers": { + "Root": { // <4> + "level": "INFO", + "AppenderRef": [ + { + "ref": "CONSOLE", + "level": "WARN" + }, + { + "ref": "MAIN" + } + ] + }, + "Logger": { // <5> + "name": "org.example", + "level": "DEBUG", + "AppenderRef": { + "ref": "DEBUG_LOG" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties b/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties new file mode 100644 index 00000000000..18e74222ea6 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties @@ -0,0 +1,25 @@ +appender.0.type = Console # <1> +appender.0.name = CONSOLE +appender.0.target = SYSTEM_OUT +appender.0.layout.type = PatternLayout +appender.0.layout.pattern = %p - %m%n + +appender.1.type = File # <2> +appender.1.name = MAIN +appender.1.fileName = logs/main.log +appender.1.layout.type = JsonTemplateLayout + +appender.2.type = File # <3> +appender.2.name = DEBUG_LOG +appender.2.fileName = logs/debug.log +appender.2.layout.type = PatternLayout +appender.2.layout.pattern = %d [%t] %p %c - %m%n + +rootLogger.level = INFO # <4> +rootLogger.appenderRef.0.ref = CONSOLE +rootLogger.appenderRef.0.level = WARN +rootLogger.appenderRef.1.ref = MAIN + +logger.0.name = org.example # <5> +logger.0.level = DEBUG +logger.0.appenderRef.0.ref = DEBUG_LOG \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml b/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml new file mode 100644 index 00000000000..3b911efb696 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml b/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml new file mode 100644 index 00000000000..65855bf4ca9 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml @@ -0,0 +1,27 @@ +Configuration: + Appenders: + Console: # <1> + name: "CONSOLE" + target: "SYSTEM_OUT" + PatternLayout: + pattern: "%p - %m%n" + File: + - name: "MAIN" # <2> + fileName: "logs/main.log" + JsonTemplateLayout: { } + - name: "DEBUG_LOG" # <3> + fileName: "logs/debug.log" + PatternLayout: + pattern: "%d [%t] %p %c - %m%n" + Loggers: + Root: # <4> + level: "INFO" + AppenderRef: + - ref: "CONSOLE" + level: "WARN" + - ref: "MAIN" + Logger: # <5> + name: "org.example" + level: "DEBUG" + AppenderRef: + ref: "DEBUG_LOG" \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.json b/src/site/antora/modules/ROOT/examples/configuration/properties.json new file mode 100644 index 00000000000..c3fb1911b27 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/properties.json @@ -0,0 +1,17 @@ +{ + "Configuration": { + "Properties": { + "Property": [ + { + "name": "log.dir", + "value": "/var/log" + }, + { + "name": "log.file", + "value": "${log.dir}/app.log" + } + ] + } + // ... + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.properties b/src/site/antora/modules/ROOT/examples/configuration/properties.properties new file mode 100644 index 00000000000..47d6bd93b10 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/properties.properties @@ -0,0 +1,3 @@ +property.log.dir = /var/log +property.log.file = ${log.dir}/app.log +# ... \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.xml b/src/site/antora/modules/ROOT/examples/configuration/properties.xml new file mode 100644 index 00000000000..01852b2166d --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/properties.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.yaml b/src/site/antora/modules/ROOT/examples/configuration/properties.yaml new file mode 100644 index 00000000000..519d6e4ee07 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/properties.yaml @@ -0,0 +1,8 @@ +Configuration: + Properties: + Property: + - name: "log.dir" + value: "/var/log" + - name: "log.file" + value: "${log.dir}/app.log" +# ... \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.json b/src/site/antora/modules/ROOT/examples/configuration/routing.json new file mode 100644 index 00000000000..cc6ab3b5e63 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/routing.json @@ -0,0 +1,34 @@ +{ + "Configuration": { + "Appenders": { + // tag::appender[] + "Routing": { + "name": "ROUTING", + "Routes": { + "pattern": "$${sd:type}", // <1> + "Route": { + "File": { + "name": "ROUTING-${sd:type}", // <2> + "fileName": "logs/${sd:type}.log", // <2> + "JsonTemplateLayout": { + "EventTemplateAdditionalField": { + "name": "type", + "value": "${sd:type}" // <2> + } + } + } + } + } + } + // end::appender[] + }, + "Loggers": { + "Root": { + "AppenderRef": { + "level": "INFO", + "ref": "ROUTING" + } + } + } + } +} diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.properties b/src/site/antora/modules/ROOT/examples/configuration/routing.properties new file mode 100644 index 00000000000..e860c5e9da9 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/routing.properties @@ -0,0 +1,20 @@ +# tag::appender[] +appender.0.type = Routing +appender.0.name = ROUTING + +appender.0.routes.type = Routes +appender.0.routes.pattern = $${sd:type} # <1> + +appender.0.routes.route.type = Route + +appender.0.routes.route.file.type = File +appender.0.routes.route.file.name = ROUTING-${sd:type} # <2> +appender.0.routes.route.file.fileName = logs/${sd:type}.log # <2> +appender.0.routes.route.file.layout.type = JsonTemplateLayout +appender.0.routes.route.file.layout.field.type = EventTemplateAdditionalField +appender.0.routes.route.file.layout.field.name = type +appender.0.routes.route.file.layout.field.value = ${sd:type} # <2> +# end::appender[] + +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = ROUTING diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.xml b/src/site/antora/modules/ROOT/examples/configuration/routing.xml new file mode 100644 index 00000000000..65e7b5df55d --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/routing.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.yaml b/src/site/antora/modules/ROOT/examples/configuration/routing.yaml new file mode 100644 index 00000000000..767247939a9 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/routing.yaml @@ -0,0 +1,20 @@ +Configuration: + Appenders: + # tag::appender[] + Routing: + name: "ROUTING" + Routes: + pattern: "$${sd:type}" # <1> + Route: + File: + name: "ROUTING-${sd:type}" # <2> + fileName: "logs/${sd:type}.log" # <2> + JsonTemplateLayout: + EventTemplateAdditionalField: + name: "type" + value: "${sd:type}" # <2> + # end::appender[] + Loggers: + Root: + level: "INFO" + AppenderRef: "ROUTING" diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index 72b579961c8..95e7c6fea8d 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -2445,8 +2445,8 @@ with `com.foo.bar`. ---- -[#RollingFileAppender] -== RollingFileAppender +[id=rollingfileappender] +== [[RollingFileAppender]] RollingFileAppender The RollingFileAppender is an OutputStreamAppender that writes to the File named in the fileName parameter and rolls the file over according diff --git a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc index 02b4d24c97d..8cdaf8aab33 100644 --- a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc @@ -32,6 +32,7 @@ the root LoggerConfig. LoggerConfig objects are created from Logger declarations in the configuration. The LoggerConfig is associated with the Appenders that actually deliver the LogEvents. +[id=logger-hierarchy] === Logger Hierarchy The first and foremost advantage of any logging API over plain diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index e8fc3615de5..770694bd8b9 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -64,6 +64,16 @@ Upon initialization of a new logger context, Log4j assigns it a context name and . If no configuration file could be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. The default configuration prints all messages less specific than <> to the console. +[CAUTION] +==== +The configuration files prefixed by `log4j2-test` should only be used on the test classpath. + +If multiple configuration files in the same category are found, Log4j uses a deterministic order to choose one of them (cf. link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Order[@Order]). +Nevertheless, application developers are advised not to use multiple configuration files that differ only by the extension. + +Most libraries should not contain Log4j configuration files in their default location to allow applications to define their own. +==== + The `` and `` placeholders above have the following meaning :: depends on the runtime environment in which Log4j runs: @@ -238,7 +248,7 @@ In order to make it more usable a series of exceptions to the rules in < - - - - - - - - - - - - - - - - - - - - - - +include::example$configuration/main-elements.xml[] ---- JSON:: + [source,json] ---- -{ - "Configuration": { - "Appenders": { - "Console": { - "name": "CONSOLE", - "target": "SYSTEM_OUT", - "PatternLayout": { - "pattern": "%p - %m%n" - } - }, - "File": [ - { - "name": "AUDIT", - "fileName": "logs/audit.log", - "JsonTemplateLayout": {} - }, - { - "name": "MAIN", - "fileName": "logs/main.log", - "PatternLayout": { - "pattern": "%d [%t] %p %c - %m%n" - } - } - ] - }, - "Loggers": { - "Root": { - "level": "WARN", - "AppenderRef": [ - { - "ref": "CONSOLE" - }, - { - "ref": "MAIN" - } - ] - }, - "Logger": { - "name": "org.example.audit", - "level": "INFO", - "AppenderRef": { - "ref": "AUDIT" - } - } - } - } -} +include::example$configuration/main-elements.json[] ---- YAML:: + [source,yaml] ---- -Configuration: - Appenders: - Console: - - name: "CONSOLE" - target: "SYSTEM_OUT" - PatternLayout: - pattern: "%p - %m%n" - File: - - name: "AUDIT" - fileName: "logs/audit.log" - JsonTemplateLayout: { } - - name: "MAIN" - fileName: "logs/main.log" - PatternLayout: - pattern: "%d [%t] %p %c - %m%n" - Loggers: - Root: - level: "WARN" - AppenderRef: - - ref: "CONSOLE" - - ref: "MAIN" - Logger: - name: "org.example.audit" - level: "INFO" - AppenderRef: - ref: "AUDIT" +include::example$configuration/main-elements.yaml[] ---- Java properties:: + [source,properties] ---- -appender.0.type = Console -appender.0.name = CONSOLE -appender.0.target = SYSTEM_OUT -appender.0.layout.type = PatternLayout -appender.0.layout.pattern = %p - %m%n +include::example$configuration/main-elements.properties[] +---- +==== + +<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. +<4> Configures the root logger at level `INFO` and connects it to the `CONSOLE` and `MAIN` appenders. +The `CONSOLE` appender will only log messages less specific than `WARN`. +<5> Configures a logger named `"org.example"` at level `DEBUG` and connects it to the `DEBUG_LOG` appender. +The logger is configured to forward messages to its parent (the root appender). + +[cols="2m,2m,5"] +|=== +| Logger name | Log event level | Appenders + +| org.example.foo +| WARN +| `CONSOLE`, `MAIN`, `DEBUG_LOG` + +| org.example.foo +| DEBUG +| `MAIN`, `DEBUG_LOG` + +| org.example.foo +| TRACE +| _none_ + +| com.example +| WARN +| `CONSOLE`, `MAIN` + +| com.example +| INFO +| `MAIN` + +| com.example +| DEBUG +| _none_ + +|=== + +=== Global configuration attributes + +The main `Configuration` element has a set of attributes that can be used to tune the way the configuration file itself is used. +The principal attributes are listed below. +See xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Configuration[Plugin reference] for a complete list. + +[id=configuration-attribute-monitorInterval] +==== `monitorInterval` + +[cols="1h,5"] +|=== +| Type | `int` +| Default value | `0` +|=== + +Determines the polling interval used by Log4j to check for changes to the configuration file. + +If set to `0`, polling is disabled. + +[NOTE] +==== +Unlike other logging backends Log4j Core is designed with audit logging in mind. + +During a reconfiguration process, no messages are lost. +Unless the new configuration file removes an appender, the old one continues to work without interruption. +==== + +[id=configuration-attribute-status] +==== `status` + +[cols="1h,5"] +|=== +| Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[LEVEL] +| Status | **DEPRECATED** +| Default value (since 2.24.0) | <> +| Default value (before 2.24.0) | value of `log4j2.defaultStatusLevel` +|=== + +Overrides the logging level of the status logger. + +WARNING: Since 2.24.0 this attribute is deprecated and should be replaced with the <> +variable. + +[id=configuration-attribute-schema] +==== `schema` + +[cols="1h,5"] +|=== +| Type | classpath resource +| Default value | `null` +|=== + +[id=configuration-attribute-strict] +==== `strict` + +[cols="1h,5"] +|=== +| Type | `boolean` +| Default value | `false` +|=== + +If set to `true` all configuration files will be checked against. + +[id=configuration-elements-filters] +==== Filters + +See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to the global configuration object. + +=== Logger configuration + +Log4j 2 contains multiple types of logger components that can be added to the `Loggers` element of the configuration: -appender.1.type = File -appender.1.name = AUDIT -appender.1.fileName = logs/audit.log -appender.1.layout.type = JsonTemplateLayout +`Root`:: is the logger that receives all events that do not have a more specific logger defined. ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig-RootLogger[Plugin reference]. + +`AsyncRoot`:: is an alternative implementation of the root logger used in the xref:manual/async.adoc#MixedSync-Async[mixed synchronous and asynchronous mode]. ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig-RootLogger[Plugin reference]. + +`Logger`:: the most common logger kind, which collects log events from itself and all its children loggers, which do not have an explicit configuration (see xref:manual/architecture.adoc#logger-hierarchy[logger hierarchy]). ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig[Plugin Reference]. + +`AsyncLogger`:: the equivalent of `Logger`, used in the xref:manual/async.adoc#MixedSync-Async[mixed synchronous and asynchronous mode]. ++ +See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig[Plugin Reference]. + +Every configuration **must** have at least a `Root` or `AsyncRoot` element. +The presence of other logger configurations is optional. + +The logger components can have the following attributes and elements: + +[id=logger-attributes-name] +==== `name` + +[cols="1h,5"] +|=== +| Type | `String` +| Applies to | `Logger` and `AsyncLogger` +|=== + +Specifies the name of the logger configuration. + +Since loggers are usually named using fully qualified class names, this value usually contains the fully qualified name of a class or a package. + +[id=logger-attributes-additivity] +==== `additivity` + +[cols="1h,5"] +|=== +| Type | `boolean` +| Default value | `true` +| Applies to | `Logger` and `AsyncLogger` +|=== + +If `true` (default), all the messages received by this logger will also be transmitted to its parent logger. + +[id=logger-attributes-level] +==== `level` + +[cols="1h,5"] +|=== +| Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] +| Default value +a| +* <>, for `Root` and `AsyncRoot`, +* inherited from the parent logger, for `Logger` and `AsyncLogger`. +|=== + +Specifies the level threshold that a log event must have to be logged. +Log events more specific than this setting will be filtered out. + +See also xref:manual/filters.adoc#filters[Filters] if you require additional filtering. + +[id=logger-attributes-includeLocation] +==== `includeLocation` -appender.2.type = File -appender.2.name = MAIN -appender.2.fileName = logs/main.log -appender.2.layout.type = PatternLayout -appender.2.layout.pattern = %d [%t] %p %c - %m%n +[cols="1h,5"] +|=== +| Type | `boolean` +| Default value +a| +* `false`, if an asynchrounous `ContextSelector` is used. +* Otherwise, +** `true` for `Root` and `Logger`, +** `false` for `AsyncRoot` and `AsyncLogger`. + +See <> for more details. +|=== + +Specifies whether Log4j is allowed to compute location information. + +Computing the location information of a logging statement is an expensive operation (a couple of microseconds). +While Log4j makes every effort to only compute it if it was requested by a configured layout (cf. xref:manual/layouts.adoc[Layouts]), this setting provide a kill switch to disable it. + +[TIP] +==== +This setting only applies to computation of location at **runtime**. -rootLogger.level = WARN -rootLogger.appenderRef.0.ref = CONSOLE -rootLogger.appenderRef.1.ref = MAIN +If the location is computed at build time using link:/log4j/transform/latest/#log4j-transform-maven-plugin[Log4j Transform Maven Plugin] this setting is ignored and location information will always be available for logging. +==== + +[id=logger-elements-properties] +==== Additional context properties -logger.0.name = org.example.audit -logger.0.level = INFO -logger.0.appenderRef.0.ref = AUDIT +Loggers can emit additional context data that will be integrated with other context data sources such as xref:manual/thread-context.adoc[ThreadContext]. + +[CAUTION] +==== +The `value` of each property is subject to <> twice: + +* when the configuration is loaded, +* each time a log event is generated. + +Therefore, if you wish to insert a value that changes in time you must double the `$` sign as in the example below. +==== + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$configuration/logger-properties.xml[tag=loggers] +---- + +JSON:: ++ +[source,json] +---- +include::example$configuration/logger-properties.json[tag=loggers] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$configuration/logger-properties.yaml[tag=loggers] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$configuration/logger-properties.properties[tag=loggers] ---- ==== +[id=logger-elements-filters] +==== Filters + +See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to a logger configuration. + [id=property-substitution] === Property substitution +Log4j provides a simple and extensible mechanism to reuse values in the configuration file using `$\{name}` expressions, such as those used in Bash, Ant or Maven. + +Reusable configuration values can be added directly to a configuration file by using a xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-PropertiesPlugin[Properties] component. + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$configuration/properties.xml[tag=!empty] +---- + +JSON:: ++ +[source,json] +---- +include::example$configuration/properties.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$configuration/properties.yaml[] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$configuration/properties.properties[] +---- +==== + +Reusable configuration values can be also provided by an extensible lookup mechanism. +See xref:manual/lookups.adoc[Lookup]s for more information. + +Configuration values defined this way can be used in **any** configuration attribute by using the following expansion rules: + +`$\{name}`:: ++ +If the `Properties` element of the configuration file has a property named `name` its value is substituted. +Otherwise, the placeholder is not expanded. ++ +[WARNING] +==== +If `name` contains a `:` character, it is expanded as in the rule below. +==== + +`${lookup:name}`:: +If both these considitions hold: ++ +-- +* `lookup` is a prefix assigned to a xref:manual/lookups.adoc[Lookup], +* the lookup has a value assigned to `name`, +-- ++ +the value for the lookup is a substituted. +Otherwise, the expansion of `$\{name}` is substituted. ++ +If `name` starts with a hyphen `-` (e.g. `-variable`), it must be escaped with a backslash `\` (e.g. `\-variable`). ++ +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]). + +The above expansions have a version with an additional `default` value that is **expanded** if the lookup fails: + +`${name:-default}`:: ++ +If the `Properties` element of the configuration file has a property named `name` its value is substituted. +Otherwise, the **expansion** of `default` is substituted. ++ +[WARNING] +==== +If `name` contains a `:` character, it is expanded as in the rule below. +==== + +`${lookup:name:-default}`:: ++ +If both these considitions hold: ++ +-- +* `lookup` is a prefix assigned to a xref:manual/lookups.adoc[Lookup], +* the lookup has a value assigned to `name`, +-- ++ +the value for the lookup is a substituted. +Otherwise, the expansion of `$\{name:-default}` is substituted. + +[NOTE] +==== +To prevent the expansion of one of the expression above, the initial `$` must be doubled as `$$`. + +The same rule applies to the `name` parameter: if it contains a `${` sequence, the sequence must be escaped as `$${`. +==== + +[id=lazy-property-substitution] +==== Lazy property substitution + +While property substitution is performed once at **configuration time** for most attributes, there are two exceptions to this rule: + +* 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, you 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}` + +* Other components defer the evaluation of their children components. +In this case you only need one dollar `$` sign. ++ +This case happens for the children of the `Route` element below: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$configuration/routing.xml[tag=appender] +---- + +JSON:: ++ +[source,json] +---- +include::example$configuration/routing.json[tag=appender] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$configuration/routing.yaml[tag=appender] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$configuration/routing.properties[tag=appender] +---- +==== +<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. + [#log4j-core-programmatic-configuration] == Programmatic configuration diff --git a/src/site/antora/modules/ROOT/pages/manual/_properties.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc similarity index 100% rename from src/site/antora/modules/ROOT/pages/manual/_properties.adoc rename to src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc index 50403d926a7..d34d313fcd8 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc @@ -204,28 +204,6 @@ trace will result in results similar to: Note that status logging is disabled when the default configuration is used. -[#Configuration_From_a_URI] -== Configuration From a URI - -When `log4j2.configurationFile` references a URL, Log4j will first determine if the URL reference -a file using the file protocol. If it does Log4j will validate that the file URL is valid and continue -processing as previously described. If it contains a protocol other than file then Log4j will inspect -the value of the <> system property. If the provided list -contains the protocol specified then Log4j will use the URI to locate the specified configuration file. If -not an exception will be thrown and an error message will be logged. If no value is provided for the -system property it will default to "https". Use of any protocol other than "file" can be prevented by -setting the system property value to "_none". This value would be an invalid protocol so cannot conflict -with any custom protocols that may be present. - -Log4j supports access to remote URLs that require authentication. Log4j supports basic authentication -out of the box. If the `log4j2.Configuration.username` and `log4j2.Configuration.password` -are specified those values will be used to perform the authentication. If the password is encrypted a custom -password decryptor may be supplied by specifying the fully qualified class name in the -<> system property. A custom -`AuthenticationProvider` may be used by setting the -`<> system property to the fully qualified class name -of the provider. - [#Additivity] == Additivity @@ -321,656 +299,6 @@ Once an event reaches a logger with its additivity set to false the event will not be passed to any of its parent loggers, regardless of their additivity setting. -[#AutomaticReconfiguration] -== Automatic Reconfiguration - -When configured from a File, Log4j has the ability to automatically -detect changes to the configuration file and reconfigure itself. If the -`monitorInterval` attribute is specified on the configuration element -and is set to a non-zero value then the file will be checked the next -time a log event is evaluated and/or logged and the monitorInterval has -elapsed since the last check. The example below shows how to configure -the attribute so that the configuration file will be checked for changes -only after at least 30 seconds have elapsed. The minimum interval is 5 -seconds. - -[source,xml] ----- - - -... - ----- - -[#ChainsawSupport] -== Chainsaw can automatically process your log files (Advertising appender configurations) - -Log4j provides the ability to 'advertise' appender configuration details -for all file-based appenders as well as socket-based appenders. For -example, for file-based appenders, the file location and the pattern -layout in the file are included in the advertisement. Chainsaw and other -external systems can discover these advertisements and use that -information to intelligently process the log file. - -The mechanism by which an advertisement is exposed, as well as the -advertisement format, is specific to each Advertiser implementation. An -external system which would like to work with a specific Advertiser -implementation must understand how to locate the advertised -configuration as well as the format of the advertisement. For example, a -'database' Advertiser may store configuration details in a database -table. An external system can read that database table in order to -discover the file location and the file format. - -Log4j provides one Advertiser implementation, a 'multicastdns' -Advertiser, which advertises appender configuration details via IP -multicast using the http://jmdns.sourceforge.net library. - -Chainsaw automatically discovers log4j's multicastdns-generated -advertisements and displays those discovered advertisements in -Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's -classpath). To begin parsing and tailing a log file provided in an -advertisement, just double-click the advertised entry in Chainsaw's -Zeroconf tab. Currently, Chainsaw only supports FileAppender -advertisements. - -To advertise an appender configuration: - -* Add the JmDns library from http://jmdns.sourceforge.net to the -application classpath -* Set the 'advertiser' attribute of the configuration element to -'multicastdns' -* Set the 'advertise' attribute on the appender element to 'true' -* If advertising a FileAppender-based configuration, set the -'advertiseURI' attribute on the appender element to an appropriate URI - -FileAppender-based configurations require an additional 'advertiseURI' -attribute to be specified on the appender. The 'advertiseURI' attribute -provides Chainsaw with information on how the file can be accessed. For -example, the file may be remotely accessible to Chainsaw via ssh/sftp by -specifying a Commons VFS (http://commons.apache.org/proper/commons-vfs/) -sftp:// URI, an http:// URI may be used if the file is accessible -through a web server, or a file:// URI can be specified if accessing the -file from a locally-running instance of Chainsaw. - -Here is an example advertisement-enabled appender configuration which -can be used by a locally-running Chainsaw to automatically tail the log -file (notice the file:// advertiseURI): - -*Please note, you must add the JmDNS library mentioned above.* - -[source,xml] ----- - - - ... - - - ... - - - ----- - -[#ConfigurationSyntax] -== Configuration Syntax - -As of version 2.9, for security reasons, Log4j does not process DTD in -XML files. If you want to split the configuration in multiple files, use -link:#XInclude[XInclude] or link:#CompositeConfiguration[Composite -Configuration]. - -As the previous examples have shown as well as those to follow, Log4j -allows you to easily redefine logging behavior without needing to modify -your application. It is possible to disable logging for certain parts of -the application, log only when specific criteria are met such as the -action being performed for a specific user, route output to Flume or a -log reporting system, etc. Being able to do this requires understanding -the syntax of the configuration files. - -The configuration element in the XML file accepts several attributes: - -[cols="1m,5a"] -|=== -|Attribute Name |Description - -|advertiser -|(Optional) The Advertiser plugin name which will be used to -advertise individual FileAppender or SocketAppender configurations. The -only Advertiser plugin provided is "multicastdns". - -|dest -|Either "err" for stderr, "out" for stdout, a file path, or a URL. - -|monitorInterval -|The minimum amount of time, in seconds, that must -elapse before the file configuration is checked for changes. - -|name -|The name of the configuration. - -|schema -|Identifies the location for the classloader to located the XML -Schema to use to validate the configuration. Only valid when strict is -set to true. If not set no schema validation will take place. - -|shutdownHook -|Specifies whether or not Log4j should automatically -shutdown when the JVM shuts down. The shutdown hook is enabled by -default but may be disabled by setting this attribute to "disable" - -|shutdownTimeout -|Specifies how many milliseconds appenders and -background tasks will get to shutdown when the JVM shuts down. Default -is zero which mean that each appender uses its default timeout, and -don't wait for background tasks. Not all appenders will honor this, it -is a hint and not an absolute guarantee that the shutdown procedure will -not take longer. Setting this too low increase the risk of losing -outstanding log events not yet written to the final destination. See -link:../javadoc/log4j-core/org/apache/logging/log4j/core/LoggerContext.html$%7Besc.hash%7Dstop(long,%20java.util.concurrent.TimeUnit)[LoggerContext.stop(long, -java.util.concurrent.TimeUnit)]. (Not used if `shutdownHook` is set to -"disable".) - -|status -|The level of internal Log4j events that should be logged to the console. -Valid values for this attribute are "off", "trace", "debug", "info", "warn", -"error", "fatal", and "all". Log4j will log details about initialization, -rollover and other internal actions to the status logger. Setting -`status="trace"` is one of the first tools available to you if you need -to troubleshoot log4j. - -(Alternatively, setting system property <> will also print -internal Log4j2 logging to the console, including internal logging that -took place before the configuration file was found.) - -|strict -|Enables the use of the strict XML format. Not supported in JSON -configurations. - -|verbose -|Enables diagnostic information while loading plugins. -|=== - -[[XML]] -=== Configuration with XML - -Log4j can be configured using two XML flavors; concise and strict. - -=== Concise Syntax - -The concise format makes configuration very easy as the element names match -the components they represent however it cannot be validated with an XML -schema. For example, the ConsoleAppender is configured by declaring an -XML element named Console under its parent appenders element. However, -element and attribute names are not case sensitive. In addition, -attributes can either be specified as an XML attribute or as an XML -element that has no attributes and has a text value. So - -[source,xml] ----- - ----- - -and - -[source,xml] ----- - - %m%n - ----- - -are equivalent. - -The file below represents the structure of an XML configuration, but -note that the elements in italics below represent the concise element -names that would appear in their place. - -[source,xml] ----- -; - - - value - - - - - - - - ... - - - - - - ... - - - - - ----- - -See the many examples on this page for sample appender, filter and -logger declarations. - -=== Strict XML - -In addition to the concise XML format above, Log4j allows configurations -to be specified in a more "normal" XML manner that can be validated -using an XML Schema. This is accomplished by replacing the friendly -element names above with their object type as shown below. For example, -instead of the ConsoleAppender being configured using an element named -Console it is instead configured as an appender element with a type -attribute containing "Console". - -[source,xml] ----- - - - - value - - - - - - - - ... - - - - - - ... - - - - - ----- - -Below is a sample configuration using the strict format. - -[source,xml] ----- - - - - target/test.log - - - - - - - - - - - - - - - - - - - - - %d %p %C{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - - - ----- - -[#JSON] -=== Configuration with JSON - -In addition to XML, Log4j can be configured using JSON. The JSON format -is very similar to the concise XML format. Each key represents the name -of a plugin and the key/value pairs associated with it are its -attributes. Where a key contains more than a simple value it itself will -be a subordinate plugin. In the example below, ThresholdFilter, Console, -and PatternLayout are all plugins while the Console plugin will be -assigned a value of STDOUT for its name attribute and the -ThresholdFilter will be assigned a level of debug. - -[source,json] ----- -{ "configuration": { "status": "error", "name": "RoutingTest", - "packages": "org.apache.logging.log4j.test", - "properties": { - "property": { "name": "filename", - "value" : "target/rolling1/rollingtest-$${sd:type}.log" } - }, - "ThresholdFilter": { "level": "debug" }, - "appenders": { - "Console": { "name": "STDOUT", - "PatternLayout": { "pattern": "%m%n" }, - "ThresholdFilter": { "level": "debug" } - }, - "Routing": { "name": "Routing", - "Routes": { "pattern": "$${sd:type}", - "Route": [ - { - "RollingFile": { - "name": "Rolling-${sd:type}", "fileName": "${filename}", - "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", - "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, - "SizeBasedTriggeringPolicy": { "size": "500" } - } - }, - { "AppenderRef": "STDOUT", "key": "Audit"} - ] - } - } - }, - "loggers": { - "logger": { "name": "EventLogger", "level": "info", "additivity": "false", - "AppenderRef": { "ref": "Routing" }}, - "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} - } - } -} ----- - -Note that in the RoutingAppender the Route element has been declared as -an array. This is valid because each array element will be a Route -component. This won't work for elements such as appenders and filters, -where each element has a different name in the concise format. Appenders -and filters can be defined as array elements if each appender or filter -declares an attribute named "type" that contains the type of the -appender. The following example illustrates this as well as how to -declare multiple loggers as an array. - -[source,json] ----- -{ "configuration": { "status": "debug", "name": "RoutingTest", - "packages": "org.apache.logging.log4j.test", - "properties": { - "property": { "name": "filename", - "value" : "target/rolling1/rollingtest-$${sd:type}.log" } - }, - "ThresholdFilter": { "level": "debug" }, - "appenders": { - "appender": [ - { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }}, - { "type": "Routing", "name": "Routing", - "Routes": { "pattern": "$${sd:type}", - "Route": [ - { - "RollingFile": { - "name": "Rolling-${sd:type}", "fileName": "${filename}", - "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz", - "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"}, - "SizeBasedTriggeringPolicy": { "size": "500" } - } - }, - { "AppenderRef": "STDOUT", "key": "Audit"} - ] - } - } - ] - }, - "loggers": { - "logger": [ - { "name": "EventLogger", "level": "info", "additivity": "false", - "AppenderRef": { "ref": "Routing" }}, - { "name": "com.foo.bar", "level": "error", "additivity": "false", - "AppenderRef": { "ref": "STDOUT" }} - ], - "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }} - } - } -} ----- - -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using JSON configuration files. - -[#YAML] -=== Configuration with YAML - -Log4j also supports using YAML for configuration files. The structure -follows the same pattern as both the XML and YAML configuration formats. -For example: - -[source,yaml] ----- -Configuration: - status: warn - name: YAMLConfigTest - properties: - property: - name: filename - value: target/test-yaml.log - thresholdFilter: - level: debug - appenders: - Console: - name: STDOUT - target: SYSTEM_OUT - PatternLayout: - Pattern: "%m%n" - File: - name: File - fileName: ${filename} - PatternLayout: - Pattern: "%d %p %C{1.} [%t] %m%n" - Filters: - ThresholdFilter: - level: error - - Loggers: - logger: - - - name: org.apache.logging.log4j.test1 - level: debug - additivity: false - ThreadContextMapFilter: - KeyValuePair: - key: test - value: 123 - AppenderRef: - ref: STDOUT - - - name: org.apache.logging.log4j.test2 - level: debug - additivity: false - AppenderRef: - ref: File - Root: - level: error - AppenderRef: - ref: STDOUT - ----- - -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using YAML configuration files. - -[#Properties] -=== Configuration with Properties - -As of version 2.4, Log4j now supports configuration via properties -files. Note that the property syntax is NOT the same as the syntax used -in Log4j 1. Like the XML and JSON configurations, properties -configurations define the configuration in terms of plugins and -attributes to the plugins. - -Prior to version 2.6, the properties configuration requires that you -list the identifiers of the appenders, filters and loggers, in a comma -separated list in properties with those names. Each of those components -will then be expected to be defined in sets of properties that begin -with _component.<.identifier>._. The identifier does not have to match -the name of the component being defined but must uniquely identify all -the attributes and subcomponents that are part of the component. If the -list of identifiers is not present the identifier must not contain a '.'. -Each individual component MUST have a "type" attribute specified that -identifies the component's Plugin type. - -As of version 2.6, this list of identifiers is no longer required as -names are inferred upon first usage, however if you wish to use more -complex identifies you must still use the list. If the list is present -it will be used. - -Unlike the base components, when creating subcomponents you cannot -specify an element containing a list of identifiers. Instead, you must -define the wrapper element with its type as is shown in the policies -definition in the rolling file appender below. You then define each of -the subcomponents below that wrapper element, as the -TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are defined -below. - -As of version 2.17.2, `rootLogger` and `logger._key_` properties can be specified to set the -level and zero or more appender refs to create for that logger. The level and appender refs are -separated by comma `,` characters with optional whitespace surrounding the comma. The -following example demonstrates how the shorthand is expanded when reading properties configurations. - -[source,properties] ----- -appender.stdout.type = Console -# ... other appender properties -appender.file.type = File -# ... other appender properties -logger.app = INFO, stdout, file -logger.app.name = com.example.app - -# is equivalent to: -# appender.stdout.type = Console -# appender.stdout.name = stdout -# ... -appender.file.type = File -appender.file.name = file -# ... -logger.app.name = com.example.app -logger.app.level = INFO -logger.app.appenderRef.$1.ref = stdout -logger.app.appenderRef.$2.ref = file ----- - -Properties configuration files support the advertiser, monitorInterval, -name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest -attributes. See link:#ConfigurationSyntax[Configuration Syntax] for the -definitions of these attributes. - -[source,properties] ----- -status = error -dest = err -name = PropertiesConfig - -property.filename = target/rolling/rollingtest.log - -filter.threshold.type = ThresholdFilter -filter.threshold.level = debug - -appender.console.type = Console -appender.console.name = STDOUT -appender.console.layout.type = PatternLayout -appender.console.layout.pattern = %m%n -appender.console.filter.threshold.type = ThresholdFilter -appender.console.filter.threshold.level = error - -appender.rolling.type = RollingFile -appender.rolling.name = RollingFile -appender.rolling.fileName = ${filename} -appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz -appender.rolling.layout.type = PatternLayout -appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n -appender.rolling.policies.type = Policies -appender.rolling.policies.time.type = TimeBasedTriggeringPolicy -appender.rolling.policies.time.interval = 2 -appender.rolling.policies.time.modulate = true -appender.rolling.policies.size.type = SizeBasedTriggeringPolicy -appender.rolling.policies.size.size=100MB -appender.rolling.strategy.type = DefaultRolloverStrategy -appender.rolling.strategy.max = 5 - -logger.rolling.name = com.example.my.app -logger.rolling.level = debug -logger.rolling.additivity = false -logger.rolling.appenderRef.rolling.ref = RollingFile - -rootLogger.level = info -rootLogger.appenderRef.stdout.ref = STDOUT - ----- - - -[#Loggers] -=== Configuring Loggers - -An understanding of how loggers work in Log4j is critical before trying -to configure them. Please reference the Log4j -xref:manual/architecture.adoc[architecture] if more information is required. -Trying to configure Log4j without understanding those concepts will lead -to frustration. - -A LoggerConfig is configured using the `logger` element. The `logger` -element must have a name attribute specified, will usually have a level -attribute specified and may also have an additivity attribute specified. -The level may be configured with one of TRACE, DEBUG, INFO, WARN, ERROR, -ALL or OFF. If no level is specified it will default to ERROR. The -additivity attribute may be assigned a value of true or false. If the -attribute is omitted the default value of true will be used. - -Capturing location information (the class name, file name, method name, and line number of the caller) -can be slow. Log4j tries to optimize this by reducing the size of the stack that must be traversed -to find the caller of the logging method. It does this by determining if any component that might -be accessed requires location information. This can cause performance issues if a logger is configured -at a level like trace or debug with the expectation that most logs will be filtered on an Appender -reference or Appender as Log4j will calculate the location information even though the log event -is going to be discarded. To disable this behavior the `includeLocation` attribute -can be set to false on the LoggerConfig. This will cause Log4j to defer calculating the location -information until absolutely necessary. - -A LoggerConfig (including the root LoggerConfig) can be configured with -properties that will be added to the properties copied from the -ThreadContextMap. These properties can be referenced from Appenders, -Filters, Layouts, etc just as if they were part of the ThreadContext -Map. The properties can contain variables that will be resolved either -when the configuration is parsed or dynamically when each event is -logged. See link:#PropertySubstitution[Property Substitution] for more -information on using variables. - -The LoggerConfig may also be configured with one or more AppenderRef -elements. Each appender referenced will become associated with the -specified LoggerConfig. If multiple appenders are configured on the -LoggerConfig each of them be called when processing logging events. - -*_Every configuration must have a root logger_*. If one is not -configured the default root LoggerConfig, which has a level of ERROR and -has a Console appender attached, will be used. The main differences -between the root logger and other loggers are - -1. The root logger does not have a name attribute. -2. The root logger does not support the additivity attribute since it -has no parent. - [#Appenders] === Configuring Appenders @@ -988,299 +316,6 @@ that contains the layout plugin's name. The various appenders will contain other attributes or elements that are required for them to function properly. -[#Filters] -=== Configuring Filters - -Log4j allows a filter to be specified in any of 4 places: - -1. At the same level as the appenders, loggers and properties elements. -These filters can accept or reject events before they have been passed -to a LoggerConfig. -2. In a logger element. These filters can accept or reject events for -specific loggers. -3. In an appender element. These filters can prevent or cause events to -be processed by the appender. -4. In an appender reference element. These filters are used to -determine if a Logger should route the event to an appender. - -Although only a single `filter` element can be configured, that element -may be the `filters` element which represents the CompositeFilter. The -`filters` element allows any number of `filter` elements to be -configured within it. The following example shows how multiple filters -can be configured on the ConsoleAppender. - -[source,xml] ----- - - - - target/test.log - - - - - - - - - - - - - - - - - - %d %p %C{1.} [%t] %m%n - - - - - - - - - - - - - - ${sys:user.name} - - - - - - - - - - - - - - ----- - -[#PropertySubstitution] -== Property Substitution - -Log4j 2 supports the ability to specify tokens in the configuration as -references to properties defined elsewhere. Some of these properties -will be resolved when the configuration file is interpreted while others -may be passed to components where they will be evaluated at runtime. To -accomplish this, Log4j uses variations of -https://commons.apache.org/proper/commons-lang/[Apache Commons Lang]'s -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`] -and -link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] -classes. In a manner similar to Ant or Maven, this allows variables -declared as `$\{name}` to be resolved using properties declared in the -configuration itself. For example, the following example shows the -filename for the rolling file appender being declared as a property. - -[source,xml] ----- - - - - target/rolling1/rollingtest-$${sd:type}.log - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - ----- - -While this is useful, there are many more places properties can -originate from. To accommodate this, Log4j also supports the syntax -`${prefix:name}` where the prefix identifies tells Log4j that variable -name should be evaluated in a specific context. See the -xref:manual/lookups.adoc[Lookups] manual page for more details. The contexts -that are built in to Log4j are: - -[cols="1m,5"] -|=== -|Prefix |Context - - - base64 - - Base64 encoded data. The format is ${base64:Base64_encoded_data}. - For example: - ${base64:SGVsbG8gV29ybGQhCg==} yields Hello World!. - - - -|base64 -|Base64 encoded data. The format is `${base64:Base64_encoded_data}`. -For example: `${base64:SGVsbG8gV29ybGQhCg==}` yields `Hello World!`. - -|bundle -|Resource bundle. The format is `${bundle:BundleName:BundleKey}`. -The bundle name follows package naming conventions, for example: -`${bundle:com.domain.Messages:MyKey}`. - -|ctx -|Thread Context Map (MDC) - -|date -|Inserts the current date and/or time using the specified format - -|docker -| Returns attributes from the Docker container the application is running in. The format is ${docker:some.attribute}. See xref:log4j-docker.adoc[Docker documentation] for requirements and a list of available attributes. - -|env -|System environment variables. The formats are `${env:ENV_NAME}` and `${env:ENV_NAME:-default_value}`. - -| event -| Retrieves values from fields within the log event. The format is ${event:some.field}. See the Lookups manual page for a list of available fields. -| java -| Retrieves information about the Java environment the application is running in. The format is ${java:some.property}. See the Lookups manual page for a list of available properties. - -|jndi -|A value set in the default JNDI Context. - -|jvmrunargs -|A JVM input argument accessed through JMX, but not a main argument; see -https://docs.oracle.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[RuntimeMXBean.getInputArguments()]. -Not available on Android. - -| k8s -| Returns attributes from the Kubernetes environment the application is running in. The format is ${k8s:some.attribute}. See the Lookups manual page for a list of available attributes. - -|log4j -|Log4j configuration properties. The expressions -`${log4j:configLocation}` and `${log4j:configParentLocation}` -respectively provide the absolute path to the log4j configuration file -and its parent folder. - -| lower -| Converts the passed in argument to lower case (usually used with nested lookups). The format is ${lower:argument}. - -|main -|A value set with -../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments-java.lang.String:A-[MapLookup.setMainArguments(String[])] - -|map -|A value from a MapMessage - -| marker -| Allows use of markers in configurations. The formats are ${marker:} and ${marker:some.name}. See the Lookups manual page for further details. - -|sd -|A value from a StructuredDataMessage. The key "id" will return the -name of the StructuredDataId without the enterprise number. The key -"type" will return the message type. Other keys will retrieve individual -elements from the Map. - -| spring -| Returns values of Spring properties from the Spring configuration. The format is ${spring:some.property}. See the Lookups manual page for requirements and details. - -|sys -|System properties. The formats are `${sys:some.property}` and -`${sys:some.property:-default_value}`. - -| upper -| Converts the passed in argument to upper case (usually used with nested lookups). The format is ${upper:argument}. -| web -| Returns values of variables associated with the Servlet Context. The format is ${spring:some.key}. See the Lookups manual page for a list of available keys. -|=== - -[#DefaultProperties] -== Default Properties -A default property map can be declared in the configuration file by placing a Properties -element directly after the Configuration element and before any Loggers, Filters, -Appenders, etc. are declared. If the value cannot be located in the specified lookup the -value in the default property map will be used. The default map is pre-populated with a value -for "hostName" that is the current system's host name or IP address and -the "contextName" with is the value of the current logging context. See many places -a Properties element is used in this section for examples. - -Default properties may also be specified in the Lookup by using the syntax `${lookupName:key:-defaultValue}`. -In some cases the key might contain a leading '-'. When this is the case an escape character must be -included, such as ``${main:\--file:-app.properties}`. This would use the -`MainMapLookup` for a key named `--file`. If the key is not found then -app.properties would be used as the default value. - -[#EnablingMessagePatternLookups] -== Enabling Message Pattern Lookups -A message is processed (by default) without using lookups, for example if you defined -`FOO_BAR`, then `logger.info("${foo.bar}")` will output `${foo.bar}` instead of `FOO_BAR`. -You could enable message pattern lookups by defining the message pattern using `%m\{lookups}`. - -[#RuntimeLookup] -== Lookup Variables with Multiple Leading '$' Characters - -An interesting feature of StrLookup processing is that when a variable -reference is declared with multiple leading '$' characters each time the -variable is resolved the leading '$' is simply removed. In the previous -example the "Routes" element is capable of resolving the variable at -runtime. To allow this the prefix value is specified as a variable with -two leading '$' characters. When the configuration file is first -processed the first '$' character is simply removed. Thus, when the -Routes element is evaluated at runtime it is the variable declaration -"$\{sd:type}" which causes the event to be inspected for a -StructuredDataMessage and if one is present the value of its type -attribute to be used as the routing key. Not all elements support -resolving variables at runtime. Components that do will specifically -call that out in their documentation. - -If no value is found for the key in the Lookup associated with the -prefix then the value associated with the key in the properties -declaration in the configuration file will be used. If no value is found -the variable declaration will be returned as the value. Default values -may be declared in the configuration by doing: - -[source,xml] ----- - - - - Audit - - ... - ----- - -_As a footnote, it is worth pointing out that the variables in the -RollingFile appender declaration will also not be evaluated when the -configuration is processed. This is simply because the resolution of the -whole RollingFile element is deferred until a match occurs. See -xref:manual/appenders.adoc#RoutingAppender[RoutingAppender] for more -information._ - [#Scripts] == Scripts @@ -1677,43 +712,4 @@ StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR); StatusLogger.getLogger().registerListener(listener); ---- -[#UnitTestingInMaven] -== Testing in Maven - -Maven can run unit and functional tests during the build cycle. By -default, any files placed in `src/test/resources` are automatically -copied to target/test-classes and are included in the classpath during -execution of any tests. As such, placing a log4j2-test.xml into this -directory will cause it to be used instead of a log4j2.xml or -log4j2.json that might be present. Thus a different log configuration -can be used during testing than what is used in production. - -A second approach, which is extensively used by Log4j 2, is to set the -log4j2.configurationFile property in the method annotated with -@BeforeClass in the junit test class. This will allow an arbitrarily -named file to be used during the test. - -A third approach, also used extensively by Log4j 2, is to use the -`LoggerContextRule` JUnit test rule which provides additional -convenience methods for testing. This requires adding the `log4j-core` -`test-jar` dependency to your test scope dependencies. For example: - -[source,java] ----- -public class AwesomeTest { - @Rule - public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml"); - - @Test - public void testSomeAwesomeFeature() { - final LoggerContext ctx = init.getLoggerContext(); - final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger"); - final Configuration cfg = init.getConfiguration(); - final ListAppender app = init.getListAppender("List"); - logger.warn("Test message"); - final List events = app.getEvents(); - // etc. - } -} ----- diff --git a/src/site/antora/modules/ROOT/pages/manual/filters.adoc b/src/site/antora/modules/ROOT/pages/manual/filters.adoc index 1a616f5baf1..134da34fcdf 100644 --- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc @@ -14,32 +14,77 @@ See the License for the specific language governing permissions and limitations under the License. //// +[id=filters] = Filters Ralph Goers Volkan Yazıcı -Filters allow Log Events to be evaluated to determine if or how they -should be published. A Filter will be called on one of its `filter` -methods and will return a `Result`, which is an Enum that has one of 3 -values - `ACCEPT`, `DENY` or `NEUTRAL`. - -Filters may be configured in one of four locations: - -1. Context-wide Filters are configured directly in the configuration. -Events that are rejected by these filters will not be passed to loggers -for further processing. Once an event has been accepted by a -Context-wide filter it will not be evaluated by any other Context-wide -Filters nor will the Logger's Level be used to filter the event. The -event will be evaluated by Logger and Appender Filters however. -2. Logger Filters are configured on a specified Logger. These are -evaluated after the Context-wide Filters and the Log Level for the -Logger. Events that are rejected by these filters will be discarded and -the event will not be passed to a parent Logger regardless of the -additivity setting. -3. Appender Filters are used to determine if a specific Appender should -handle the formatting and publication of the event. -4. Appender Reference Filters are used to determine if a Logger should -route the event to an appender. +Log4j supports filtering of log events at each level of the logging pipeline using two features: + +* the `level` attributes that can be set on loggers and appender references, +* filter components that can be attached to loggers, appenders, appender references or the global configuration object. + +Filters evaluate the parameters of a logging call (context-wide filter) or a log event and return one of three results: + +ACCEPT:: The log event is accepted by the filter and goes to the next stage of the logging pipeline, + +DENY:: The log event is unconditionally dropped, + +NEUTRAL:: Log4j behaves as if the filter was not present. + +To decide whether a log event from a certain logger is delivered to a specific appender, the following procedure is followed: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$configuration/filters.xml[] +---- + +JSON:: ++ +[source,json] +---- +include::example$configuration/filters.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$configuration/filters.yaml[] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$configuration/filters.properties[] +---- +==== +<1> First the context-wide filter is consulted. +If it returns `ACCEPT` the log message goes directly to point 3. +<2> Then Log4j checks the message against the configured logger level. +<3> The filter configured on a logger is applied next. +If the logger is additive, the filter on the parent logger is applied recursively until we end up on the logger that references the given appender. +<4> Next comes the turn of the filter configured on an appender reference, +<5> followed by a level check against the configured level of the reference. +<6> The process ends with the filter attached to an appender. + +[CAUTION] +==== +For performance reasons log events should be filtered as soon as possible in the logging pipeline. +This reduces the costs (formatting, transfer through an asynchronous barrier) of disabled log events. +==== + +[TIP] +==== +Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 1 appender with a <> on the equivalent Log4j 2 appender. + +Using the `level` property of appender references will give a better performance. +==== [#BurstFilter] == BurstFilter diff --git a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc index 1ac6898e464..58c8b138371 100644 --- a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc @@ -107,8 +107,8 @@ Log4j Docker provides access to the following container attributes: This Lookup is subject to the requirements listed at xref:log4j-docker.adoc[Log4j Docker Support] -[#EnvironmentLookup] -== Environment Lookup +[id=environment-lookup] +== [[EnvironmentLookup]] Environment Lookup The EnvironmentLookup allows systems to configure environment variables, either in global files such as /etc/profile or in the startup scripts @@ -596,8 +596,8 @@ while "type" would have to be an item in the Map in a MapMessage. ---- -[#SystemPropertiesLookup] -== System Properties Lookup +[id=system-properties-lookup] +== [[SystemPropertiesLookup]] System Properties Lookup As it is quite common to define values inside and outside the application by using System Properties, it is only natural that they diff --git a/src/site/antora/modules/ROOT/pages/plugin-reference.adoc b/src/site/antora/modules/ROOT/pages/plugin-reference.adoc index c3417aa050f..628d310c922 100644 --- a/src/site/antora/modules/ROOT/pages/plugin-reference.adoc +++ b/src/site/antora/modules/ROOT/pages/plugin-reference.adoc @@ -18,3 +18,768 @@ Licensed to the Apache Software Foundation (ASF) under one or more This file is a stub. Its content will be auto-generated during build. + +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-AbstractBuilder] +== `AbstractBuilder` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-AppenderBuilder] +== `AppenderBuilder` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-AsyncAppenderBuilder] +== org.apache.log4j.AsyncAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-ConsoleAppenderBuilder] +== org.apache.log4j.ConsoleAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-DailyRollingFileAppenderBuilder] +== org.apache.log4j.DailyRollingFileAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-EnhancedRollingFileAppenderBuilder] +== org.apache.log4j.rolling.RollingFileAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-FileAppenderBuilder] +== org.apache.log4j.FileAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-NullAppenderBuilder] +== org.apache.log4j.varia.NullAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-RewriteAppenderBuilder] +== org.apache.log4j.rewrite.RewriteAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-RollingFileAppenderBuilder] +== org.apache.log4j.RollingFileAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-SocketAppenderBuilder] +== org.apache.log4j.net.SocketAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-SyslogAppenderBuilder] +== org.apache.log4j.net.SyslogAppender +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-Builder] +== `Builder` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-filter-DenyAllFilterBuilder] +== org.apache.log4j.varia.DenyAllFilter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-filter-FilterBuilder] +== `FilterBuilder` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-filter-LevelMatchFilterBuilder] +== org.apache.log4j.varia.LevelMatchFilter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-filter-LevelRangeFilterBuilder] +== org.apache.log4j.varia.LevelRangeFilter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-filter-StringMatchFilterBuilder] +== org.apache.log4j.varia.StringMatchFilter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-layout-HtmlLayoutBuilder] +== org.apache.log4j.HTMLLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-layout-LayoutBuilder] +== `LayoutBuilder` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-layout-PatternLayoutBuilder] +== org.apache.log4j.PatternLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-layout-SimpleLayoutBuilder] +== org.apache.log4j.SimpleLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-layout-TTCCLayoutBuilder] +== org.apache.log4j.TTCCLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-layout-XmlLayoutBuilder] +== org.apache.log4j.xml.XMLLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-Parser] +== `Parser` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-rolling-CompositeTriggeringPolicyBuilder] +== org.apache.log4j.rolling.CompositeTriggeringPolicy +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-rolling-SizeBasedTriggeringPolicyBuilder] +== org.apache.log4j.rolling.SizeBasedTriggeringPolicy +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-rolling-TimeBasedRollingPolicyBuilder] +== org.apache.log4j.rolling.TimeBasedRollingPolicy +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-rolling-TriggeringPolicyBuilder] +== `TriggeringPolicyBuilder` +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-config-PropertiesConfigurationFactory] +== Log4j1PropertiesConfigurationFactory +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-layout-Log4j1SyslogLayout] +== Log4j1SyslogLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-layout-Log4j1XmlLayout] +== Log4j1XmlLayout +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-pattern-Log4j1LevelPatternConverter] +== Log4j1LevelPatternConverter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-pattern-Log4j1MdcPatternConverter] +== Log4j1MdcPatternConverter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-pattern-Log4j1NdcPatternConverter] +== Log4j1NdcPatternConverter +[#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-xml-XmlConfigurationFactory] +== Log4j1XmlConfigurationFactory +[#org-apache-logging-log4j_log4j-cassandra_com-datastax-driver-core-BatchStatement-Type] +== `Type` +[#org-apache-logging-log4j_log4j-cassandra_org-apache-logging-log4j-cassandra-CassandraAppender] +== Cassandra +[#org-apache-logging-log4j_log4j-core_com-conversantmedia-util-concurrent-SpinPolicy] +== `SpinPolicy` +[#org-apache-logging-log4j_log4j-core_org-apache-commons-csv-QuoteMode] +== `QuoteMode` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-AbstractLifeCycle] +== `AbstractLifeCycle` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-AbstractAppender] +== `AbstractAppender` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-AbstractOutputStreamAppender] +== `AbstractOutputStreamAppender` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-AbstractWriterAppender] +== `AbstractWriterAppender` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Appender] +== `Appender` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-AppenderSet] +== AppenderSet +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-AsyncAppender] +== Async +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-ConsoleAppender] +== Console +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-ConsoleAppender-Target] +== `Target` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-CountingNoOpAppender] +== CountingNoOp +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-AbstractDatabaseAppender] +== `AbstractDatabaseAppender` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-ColumnMapping] +== ColumnMapping +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-AbstractConnectionSource] +== `AbstractConnectionSource` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-AbstractDriverManagerConnectionSource] +== `AbstractDriverManagerConnectionSource` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-ColumnConfig] +== Column +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-ConnectionSource] +== `ConnectionSource` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-DataSourceConnectionSource] +== DataSource +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-DriverManagerConnectionSource] +== DriverManager +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-FactoryMethodConnectionSource] +== ConnectionFactory +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-db-jdbc-JdbcAppender] +== JDBC +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-FailoverAppender] +== Failover +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-FailoversPlugin] +== failovers +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-FileAppender] +== File +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-HttpAppender] +== Http +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-MemoryMappedFileAppender] +== MemoryMappedFile +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-mom-jeromq-JeroMqAppender] +== JeroMQ +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-mom-JmsAppender] +== JMS +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-mom-kafka-KafkaAppender] +== Kafka +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-nosql-NoSqlAppender] +== NoSql +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-NullAppender] +== Null +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-OutputStreamAppender] +== OutputStream +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-RandomAccessFileAppender] +== RandomAccessFile +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rewrite-LoggerNameLevelRewritePolicy] +== LoggerNameLevelRewritePolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rewrite-MapRewritePolicy] +== MapRewritePolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rewrite-PropertiesRewritePolicy] +== PropertiesRewritePolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rewrite-RewriteAppender] +== Rewrite +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rewrite-RewritePolicy] +== `RewritePolicy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-AbstractRolloverStrategy] +== `AbstractRolloverStrategy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-AbstractTriggeringPolicy] +== `AbstractTriggeringPolicy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-AbstractAction] +== `AbstractAction` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-AbstractPathAction] +== `AbstractPathAction` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-Action] +== `Action` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-DeleteAction] +== Delete +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-Duration] +== `Duration` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfAccumulatedFileCount] +== IfAccumulatedFileCount +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfAccumulatedFileSize] +== IfAccumulatedFileSize +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfAll] +== IfAll +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfAny] +== IfAny +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfFileName] +== IfFileName +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfLastModified] +== IfLastModified +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-IfNot] +== IfNot +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-PathCondition] +== `PathCondition` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-PathSortByModificationTime] +== SortByModificationTime +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-PathSorter] +== `PathSorter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-PosixViewAttributeAction] +== PosixViewAttribute +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-action-ScriptCondition] +== ScriptCondition +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-CompositeTriggeringPolicy] +== Policies +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-CronTriggeringPolicy] +== CronTriggeringPolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-DefaultRolloverStrategy] +== DefaultRolloverStrategy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-DirectFileRolloverStrategy] +== `DirectFileRolloverStrategy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-DirectWriteRolloverStrategy] +== DirectWriteRolloverStrategy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-RollingFileAppender] +== RollingFile +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-NoOpTriggeringPolicy] +== NoOpTriggeringPolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-OnStartupTriggeringPolicy] +== OnStartupTriggeringPolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-RollingRandomAccessFileAppender] +== RollingRandomAccessFile +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-RolloverStrategy] +== `RolloverStrategy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-SizeBasedTriggeringPolicy] +== SizeBasedTriggeringPolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-TimeBasedTriggeringPolicy] +== TimeBasedTriggeringPolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-rolling-TriggeringPolicy] +== `TriggeringPolicy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-routing-IdlePurgePolicy] +== IdlePurgePolicy +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-routing-PurgePolicy] +== `PurgePolicy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-routing-Route] +== Route +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-routing-Routes] +== Routes +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-routing-RoutingAppender] +== Routing +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-ScriptAppenderSelector] +== ScriptAppenderSelector +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-SmtpAppender] +== SMTP +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-SocketAppender] +== `SocketAppender` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-SyslogAppender] +== Syslog +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-appender-WriterAppender] +== Writer +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-ArrayBlockingQueueFactory] +== ArrayBlockingQueue +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig] +== asyncLogger +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig-RootLogger] +== asyncRoot +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncWaitStrategyFactoryConfig] +== AsyncWaitStrategyFactory +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-BlockingQueueFactory] +== `BlockingQueueFactory` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-DisruptorBlockingQueueFactory] +== DisruptorBlockingQueue +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-JCToolsBlockingQueueFactory] +== JCToolsBlockingQueue +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-JCToolsBlockingQueueFactory-WaitStrategy] +== `WaitStrategy` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-LinkedTransferQueueFactory] +== LinkedTransferQueue +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-AppenderRef] +== AppenderRef +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-AppendersPlugin] +== appenders +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-Arbiter] +== `Arbiter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-ClassArbiter] +== ClassArbiter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-DefaultArbiter] +== DefaultArbiter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-EnvironmentArbiter] +== EnvironmentArbiter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-ScriptArbiter] +== ScriptArbiter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-SelectArbiter] +== Select +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-SystemPropertyArbiter] +== SystemPropertyArbiter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-builder-api-ConfigurationBuilderFactory] +== `ConfigurationBuilderFactory` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Configuration] +== Configuration +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-ConfigurationAware] +== `ConfigurationAware` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-ConfigurationFactory] +== `ConfigurationFactory` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevelConfig] +== CustomLevel +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevels] +== CustomLevels +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-DefaultAdvertiser] +== default +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-HttpWatcher] +== http +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-json-JsonConfigurationFactory] +== JsonConfigurationFactory +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig] +== `LoggerConfig` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig-RootLogger] +== root +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggersPlugin] +== loggers +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverter] +== `TypeConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-BigDecimalConverter] +== BigDecimal +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-BigIntegerConverter] +== BigInteger +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-BooleanConverter] +== Boolean +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-ByteArrayConverter] +== ByteArray +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-ByteConverter] +== Byte +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-CharacterConverter] +== Character +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-CharArrayConverter] +== CharacterArray +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-CharsetConverter] +== Charset +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-ClassConverter] +== Class +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-CronExpressionConverter] +== CronExpression +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-DoubleConverter] +== Double +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-DurationConverter] +== Duration +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-FileConverter] +== File +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-FloatConverter] +== Float +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-InetAddressConverter] +== InetAddress +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-IntegerConverter] +== Integer +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-LevelConverter] +== Level +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-LongConverter] +== Long +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-PathConverter] +== Path +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-PatternConverter] +== Pattern +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-SecurityProviderConverter] +== SecurityProvider +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-ShortConverter] +== Short +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-StringConverter] +== String +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-UriConverter] +== URI +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-UrlConverter] +== URL +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-plugins-convert-TypeConverters-UuidConverter] +== UUID +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-PropertiesPlugin] +== properties +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-properties-PropertiesConfigurationFactory] +== PropertiesConfigurationFactory +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Property] +== property +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-ScriptsPlugin] +== scripts +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-xml-XmlConfigurationFactory] +== XmlConfigurationFactory +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-yaml-YamlConfigurationFactory] +== YamlConfigurationFactory +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-AbstractFilterable] +== `AbstractFilterable` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-AbstractFilter] +== `AbstractFilter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Filter] +== `Filter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-BurstFilter] +== BurstFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-CompositeFilter] +== filters +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-DenyAllFilter] +== DenyAllFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-DynamicThresholdFilter] +== DynamicThresholdFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-Filterable] +== `Filterable` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-LevelMatchFilter] +== LevelMatchFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-LevelRangeFilter] +== LevelRangeFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-MapFilter] +== `MapFilter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-MarkerFilter] +== MarkerFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-MutableThreadContextMapFilter] +== MutableThreadContextMapFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-NoMarkerFilter] +== NoMarkerFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-RegexFilter] +== RegexFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Filter-Result] +== `Result` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-ScriptFilter] +== ScriptFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-StringMatchFilter] +== StringMatchFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-StructuredDataFilter] +== StructuredDataFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-ThreadContextMapFilter] +== ThreadContextMapFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-ThresholdFilter] +== ThresholdFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-TimeFilter] +== TimeFilter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-impl-LocationAware] +== `LocationAware` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-AbstractCsvLayout] +== `AbstractCsvLayout` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-AbstractJacksonLayout] +== `AbstractJacksonLayout` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-AbstractLayout] +== `AbstractLayout` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-AbstractStringLayout] +== `AbstractStringLayout` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-Layout] +== `Layout` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-CsvLogEventLayout] +== CsvLogEventLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-CsvParameterLayout] +== CsvParameterLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-Encoder] +== `Encoder` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-GelfLayout] +== GelfLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-GelfLayout-CompressionType] +== `CompressionType` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-HtmlLayout] +== HtmlLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-HtmlLayout-FontSize] +== `FontSize` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-JsonLayout] +== JsonLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-LevelPatternSelector] +== LevelPatternSelector +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-LoggerFields] +== LoggerFields +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-MarkerPatternSelector] +== MarkerPatternSelector +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-MessageLayout] +== MessageLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-PatternLayout] +== PatternLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-PatternMatch] +== PatternMatch +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-PatternSelector] +== `PatternSelector` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-Rfc5424Layout] +== Rfc5424Layout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-ScriptPatternSelector] +== ScriptPatternSelector +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-SerializedLayout] +== SerializedLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-SyslogLayout] +== SyslogLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-XmlLayout] +== XmlLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-layout-YamlLayout] +== YamlLayout +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-LifeCycle2] +== `LifeCycle2` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-LifeCycle] +== `LifeCycle` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-AbstractConfigurationAwareLookup] +== `AbstractConfigurationAwareLookup` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-AbstractLookup] +== `AbstractLookup` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-ContextMapLookup] +== ctx +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-DateLookup] +== date +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-EnvironmentLookup] +== env +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-EventLookup] +== event +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-JavaLookup] +== java +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-JmxRuntimeInputArgumentsLookup] +== jvmrunargs +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-JndiLookup] +== jndi +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-Log4jLookup] +== log4j +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-LowerLookup] +== lower +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-MainMapLookup] +== main +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-MapLookup] +== `MapLookup` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-MarkerLookup] +== marker +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-ResourceBundleLookup] +== bundle +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-StrLookup] +== `StrLookup` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-StructuredDataLookup] +== sd +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-SystemPropertiesLookup] +== sys +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-lookup-UpperLookup] +== upper +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-Advertiser] +== `Advertiser` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-Facility] +== `Facility` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-MulticastDnsAdvertiser] +== multicastdns +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-Protocol] +== `Protocol` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-Rfc1349TrafficClass] +== `Rfc1349TrafficClass` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-SocketAddress] +== SocketAddress +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-SocketOptions] +== SocketOptions +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-SocketPerformancePreferences] +== SocketPerformancePreferences +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-ssl-AbstractKeyStoreConfiguration] +== `AbstractKeyStoreConfiguration` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-ssl-KeyStoreConfiguration] +== KeyStore +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-ssl-SslConfiguration] +== Ssl +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-ssl-StoreConfiguration] +== `StoreConfiguration` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-net-ssl-TrustStoreConfiguration] +== TrustStore +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractPatternConverter] +== `AbstractPatternConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter] +== `AbstractStyleNameConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Black] +== black +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Blue] +== blue +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Cyan] +== cyan +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Green] +== green +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Magenta] +== magenta +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Red] +== red +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-White] +== white +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AbstractStyleNameConverter-Yellow] +== yellow +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-AnsiConverter] +== `AnsiConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ArrayPatternConverter] +== `ArrayPatternConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ClassNamePatternConverter] +== ClassNamePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-DatePatternConverter] +== DatePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-EncodingPatternConverter] +== encode +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-EndOfBatchPatternConverter] +== EndOfBatchPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-EqualsBaseReplacementConverter] +== `EqualsBaseReplacementConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-EqualsIgnoreCaseReplacementConverter] +== equalsIgnoreCase +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-EqualsReplacementConverter] +== equals +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ExtendedThrowablePatternConverter] +== ExtendedThrowablePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-FileDatePatternConverter] +== FileDatePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-FileLocationPatternConverter] +== FileLocationPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-FullLocationPatternConverter] +== FullLocationPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-HighlightConverter] +== highlight +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-IntegerPatternConverter] +== IntegerPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-LevelPatternConverter] +== LevelPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-LineLocationPatternConverter] +== LineLocationPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-LineSeparatorPatternConverter] +== LineSeparatorPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-LogEventPatternConverter] +== `LogEventPatternConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-LoggerFqcnPatternConverter] +== LoggerFqcnPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-LoggerPatternConverter] +== LoggerPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MapPatternConverter] +== MapPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MarkerPatternConverter] +== MarkerPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MarkerSimpleNamePatternConverter] +== MarkerNamePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MaxLengthConverter] +== maxLength +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MdcPatternConverter] +== MdcPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MessagePatternConverter] +== MessagePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-MethodLocationPatternConverter] +== MethodLocationPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-NamePatternConverter] +== `NamePatternConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-NanoTimePatternConverter] +== NanoTimePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-NdcPatternConverter] +== NdcPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-PatternConverter] +== `PatternConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ProcessIdPatternConverter] +== ProcessIdPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-RegexReplacement] +== replace +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-RegexReplacementConverter] +== replace +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-RelativeTimePatternConverter] +== RelativeTimePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-RepeatPatternConverter] +== repeat +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-RootThrowablePatternConverter] +== RootThrowablePatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-SequenceNumberPatternConverter] +== SequenceNumberPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-StyleConverter] +== style +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ThreadIdPatternConverter] +== ThreadIdPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ThreadNamePatternConverter] +== ThreadPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ThreadPriorityPatternConverter] +== ThreadPriorityPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-ThrowablePatternConverter] +== `ThrowablePatternConverter` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-UuidPatternConverter] +== UuidPatternConverter +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-pattern-VariablesNotEmptyReplacementConverter] +== notEmpty +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-script-AbstractScript] +== `AbstractScript` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-script-Script] +== Script +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-script-ScriptFile] +== ScriptFile +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-script-ScriptRef] +== ScriptRef +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-StringLayout] +== `StringLayout` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-AbstractWatcher] +== `AbstractWatcher` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-Builder] +== `Builder` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-KeyValuePair] +== KeyValuePair +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-Watcher] +== `Watcher` +[#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-Level] +== `Level` +[#org-apache-logging-log4j_log4j-core-test_org-apache-logging-log4j-core-test-appender-AlwaysFailAppender] +== AlwaysFail +[#org-apache-logging-log4j_log4j-core-test_org-apache-logging-log4j-core-test-appender-BlockingAppender] +== Block +[#org-apache-logging-log4j_log4j-core-test_org-apache-logging-log4j-core-test-appender-FailOnceAppender] +== FailOnce +[#org-apache-logging-log4j_log4j-core-test_org-apache-logging-log4j-core-test-appender-ListAppender] +== List +[#org-apache-logging-log4j_log4j-core-test_org-apache-logging-log4j-core-test-ExtendedLevels] +== ExtendedLevel +[#org-apache-logging-log4j_log4j-core-test_org-apache-logging-log4j-core-test-junit-TestPropertyLookup] +== test +[#org-apache-logging-log4j_log4j-couchdb_org-apache-logging-log4j-core-appender-nosql-NoSqlProvider] +== `NoSqlProvider` +[#org-apache-logging-log4j_log4j-couchdb_org-apache-logging-log4j-couchdb-CouchDbProvider] +== CouchDB +[#org-apache-logging-log4j_log4j-docker_org-apache-logging-log4j-docker-DockerLookup] +== docker +[#org-apache-logging-log4j_log4j-flume-ng_org-apache-logging-log4j-flume-appender-Agent] +== Agent +[#org-apache-logging-log4j_log4j-flume-ng_org-apache-logging-log4j-flume-appender-FlumeAppender] +== Flume +[#org-apache-logging-log4j_log4j-flume-ng_org-apache-logging-log4j-flume-appender-FlumeEventFactory] +== `FlumeEventFactory` +[#org-apache-logging-log4j_log4j-jakarta-web_org-apache-logging-log4j-web-appender-ServletAppender] +== Servlet +[#org-apache-logging-log4j_log4j-jakarta-web_org-apache-logging-log4j-web-WebLookup] +== web +[#org-apache-logging-log4j_log4j-jdbc-dbcp2_org-apache-logging-log4j-core-appender-db-jdbc-PoolableConnectionFactoryConfig] +== PoolableConnectionFactory +[#org-apache-logging-log4j_log4j-jdbc-dbcp2_org-apache-logging-log4j-core-appender-db-jdbc-PoolingDriverConnectionSource] +== PoolingDriver +[#org-apache-logging-log4j_log4j-jpa_org-apache-logging-log4j-core-appender-db-jpa-JpaAppender] +== JPA +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-JsonTemplateLayout] +== JsonTemplateLayout +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-JsonTemplateLayout-EventTemplateAdditionalField] +== EventTemplateAdditionalField +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-JsonTemplateLayout-EventTemplateAdditionalField-Format] +== `Format` +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-CaseConverterResolverFactory] +== CaseConverterResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-CounterResolverFactory] +== CounterResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-EndOfBatchResolverFactory] +== EndOfBatchResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-EventAdditionalFieldInterceptor] +== EventAdditionalFieldInterceptor +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-EventResolverFactory] +== `EventResolverFactory` +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-EventResolverInterceptor] +== `EventResolverInterceptor` +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-EventRootObjectKeyInterceptor] +== EventRootObjectKeyInterceptor +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-ExceptionResolverFactory] +== ExceptionResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-ExceptionRootCauseResolverFactory] +== ExceptionRootCauseResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-LevelResolverFactory] +== LevelResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-LoggerResolverFactory] +== LoggerResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-MainMapResolverFactory] +== MainMapResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-MapResolverFactory] +== MapResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-MarkerResolverFactory] +== MarkerResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-MessageParameterResolverFactory] +== MessageParameterResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-MessageResolverFactory] +== MessageResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-PatternResolverFactory] +== PatternResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-SourceResolverFactory] +== SourceResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-TemplateResolverFactory] +== `TemplateResolverFactory` +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-TemplateResolverInterceptor] +== `TemplateResolverInterceptor` +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-ThreadContextDataResolverFactory] +== ThreadContextDataResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-ThreadContextStackResolverFactory] +== ThreadContextStackResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-ThreadResolverFactory] +== ThreadResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-resolver-TimestampResolverFactory] +== TimestampResolverFactory +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-util-RecyclerFactory] +== `RecyclerFactory` +[#org-apache-logging-log4j_log4j-layout-template-json_org-apache-logging-log4j-layout-template-json-util-RecyclerFactoryConverter] +== RecyclerFactoryConverter +[#org-apache-logging-log4j_log4j-mongodb4_org-apache-logging-log4j-mongodb4-MongoDb4Provider] +== MongoDb4 +[#org-apache-logging-log4j_log4j-mongodb_org-apache-logging-log4j-mongodb-MongoDbProvider] +== MongoDb +[#org-apache-logging-log4j_log4j-spring-boot_org-apache-logging-log4j-core-config-LoggerContextAware] +== `LoggerContextAware` +[#org-apache-logging-log4j_log4j-spring-boot_org-apache-logging-log4j-spring-boot-SpringLookup] +== spring +[#org-apache-logging-log4j_log4j-spring-boot_org-apache-logging-log4j-spring-boot-SpringProfileArbiter] +== SpringProfile diff --git a/src/site/antora/modules/ROOT/partials/properties-configuration-factory.adoc b/src/site/antora/modules/ROOT/partials/properties-configuration-factory.adoc index d1b921786b2..ecf6f5f3f4f 100644 --- a/src/site/antora/modules/ROOT/partials/properties-configuration-factory.adoc +++ b/src/site/antora/modules/ROOT/partials/properties-configuration-factory.adoc @@ -45,6 +45,8 @@ If a relative URL is provided, it is interpreted as: * path to a file, if the file exists, * a classpath resource otherwise. +Usage of absolute URLs is restricted by the xref:manual/configuration.adoc#properties-transport-security[Transport Security] configuration options. + See also xref:manual/configuration.adoc#AutomaticConfiguration[Automatic Configuration]. [id=log4j2.level] diff --git a/src/site/antora/modules/ROOT/partials/properties-transport-security.adoc b/src/site/antora/modules/ROOT/partials/properties-transport-security.adoc index 5fa32070194..5c1629ebd8d 100644 --- a/src/site/antora/modules/ROOT/partials/properties-transport-security.adoc +++ b/src/site/antora/modules/ROOT/partials/properties-transport-security.adoc @@ -30,7 +30,7 @@ A comma separated list of https://docs.oracle.com/javase/{java-target-version}/d To completely prevent accessing the configuration via the Java `URL` class specify a value of `_none`. -// TODO: What about 'jar:http:'? +NOTE:: Since Log4j does not use `URL` to access `file:` resources, this protocol can not be effectively disabled. [id=log4j2.configurationAuthorizationProvider] == `log4j2.configurationAuthorizationProvider` From 553dd7b0c4f16c2e0012d145fdb0a47b8f805c87 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Fri, 10 May 2024 23:36:59 +0200 Subject: [PATCH 03/24] Move configuration properties to separate page --- .../antora/modules/ROOT/pages/log4j-jul.adoc | 21 ++++++++-- .../log4j-spring-cloud-config-client.adoc | 8 +++- .../modules/ROOT/pages/manual/appenders.adoc | 2 +- .../modules/ROOT/pages/manual/async.adoc | 6 +-- .../ROOT/pages/manual/configuration.adoc | 39 +++++++++++-------- .../manual/configuration/properties.adoc | 4 +- .../ROOT/pages/manual/garbagefree.adoc | 8 ++-- .../antora/modules/ROOT/pages/manual/jmx.adoc | 15 ++++--- 8 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/log4j-jul.adoc b/src/site/antora/modules/ROOT/pages/log4j-jul.adoc index c0d869e14e4..e141ea06131 100644 --- a/src/site/antora/modules/ROOT/pages/log4j-jul.adoc +++ b/src/site/antora/modules/ROOT/pages/log4j-jul.adoc @@ -35,15 +35,28 @@ This must be done either through the command line (i.e., using the `-Djava.util. == Compatibility -The use of a http://docs.oracle.com/javase/6/docs/api/java/util/logging/Filter.html[`java.util.logging.Filter`] is supported on a per-http://docs.oracle.com/javase/6/docs/api/java/util/logging/Logger.html[`Logger`] basis. +The use of a +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/logging/Filter.html[java.util.logging.Filter] +is supported on a +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/logging/Logger.html[per-Logger] +basis. However, it is recommended to use the standard xref:manual/filters.adoc[Filters] feature in Log4j instead. -The use of http://docs.oracle.com/javase/6/docs/api/java/util/logging/Handler.html[`java.util.logging.Handler`] classes is _NOT_ supported. -Custom Handlers should instead use an appropriate xref:manual/appenders.adoc[Appender] or code their own link:javadoc/log4j-core/org/apache/logging/log4j/core/Appender.adoc[`Appender`] plugin. +The use of +https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/logging/Handler.html[java.util.logging.Handler] +classes is +_NOT_ supported. +Custom Handlers should instead use an appropriate +xref:manual/appenders.adoc[Appender] +or code their own +link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[Appender] +plugin. Java logging levels are translated into Log4j logging levels dynamically. The following table lists the conversions between a Java logging level and its equivalent Log4j level. -Custom levels should be implemented as an implementation of `LevelConverter`, and the Log4j property xref:manual/configuration.adoc#log4j2.julLevelConverter[log4j2.julLevelConverter] must be set to your custom class name. +Custom levels should be implemented as an implementation of `LevelConverter`, and the Log4j property +xref:manual/configuration/properties.adoc#log4j2.julLevelConverter[log4j2.julLevelConverter] +must be set to your custom class name. Using the default `LevelConverter` implementation, custom logging levels are mapped to whatever the current level of the `Logger` being logged to is using. [#default-level-conversions] diff --git a/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc b/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc index dd81aa136ed..5eca408a296 100644 --- a/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc +++ b/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc @@ -24,7 +24,9 @@ Spring Boot applications initialize logging 3 times. . SpringApplication declares a Logger. This Logger will be initialized using Log4j's "normal" mechanisms. -Thus the xref:manual/configuration.adoc#log4j2.configurationFile[`log4j2.configurationFile`] system property will be checked to see if a specific configuration file has been provided, otherwise it will search for a configuration file on the classpath. +Thus, the +xref:manual/configuration/properties.adoc#log4j2.configurationFile[`log4j2.configurationFile`] +system property will be checked to see if a specific configuration file has been provided, otherwise it will search for a configuration file on the classpath. The property may also be declare in log4j2.component.properties. == Usage @@ -122,7 +124,9 @@ logging: Note that Log4j currently does not directly support encrypting the password. However, Log4j does use Spring's standard APIs to access properties in the Spring configuration so any customizations made to Spring's property handling would apply to the properties Log4j uses as well. -If more extensive authentication is required an `AuthorizationProvider` can be implemented and its fully qualified class name should be specified in the xref:manual/configuration.adoc#log4j2.configurationAuthorizationProvider[log4j2.configurationAuthorizationProvider] system property, in log4j2.component.properties or in Spring's `bootstrap.yml` using either the `log4j2.authorizationProvider` or `logging.auth.authorizationProvider` key. +If more extensive authentication is required an `AuthorizationProvider` can be implemented and its fully qualified class name should be specified in the +xref:manual/configuration/properties.adoc#log4j2.configurationAuthorizationProvider[log4j2.configurationAuthorizationProvider] +system property, in log4j2.component.properties or in Spring's `bootstrap.yml` using either the `log4j2.authorizationProvider` or `logging.auth.authorizationProvider` key. For the properties required by TLS configuration see xref:manual/configuration.adoc#transport-security[the Transport Security configuration]. diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index 95e7c6fea8d..1431c9b49d6 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -120,7 +120,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration.adoc#log4j2.AsyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` +xref:manual/configuration/properties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` and `log4j2.DiscardThreshold`]. A typical AsyncAppender configuration might look like: diff --git a/src/site/antora/modules/ROOT/pages/manual/async.adoc b/src/site/antora/modules/ROOT/pages/manual/async.adoc index a727e64fb5e..53e8e9f24f1 100644 --- a/src/site/antora/modules/ROOT/pages/manual/async.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/async.adoc @@ -117,7 +117,7 @@ classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required._ This is simplest to configure and gives the best performance. -To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/configuration.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. +To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/configuration/properties.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. By default, link:#Location[location] is not passed to the I/O thread by asynchronous loggers. If one of your layouts or custom filters needs @@ -183,7 +183,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` +xref:manual/configuration/properties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` and `log4j2.discardThreshold`]. [#MixedSync-Async] @@ -257,7 +257,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` +xref:manual/configuration/properties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` and `log4j2.discardThreshold`]. [#custom-waitstrategy] diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 770694bd8b9..3f64c8b8661 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -29,7 +29,7 @@ Since version 2.0 the configuration file format is considered as part of the pub [NOTE] ==== -To prevent a chicken-and-egg problem some configuration options, such as the location of the configuration file can be supplied only through <>. +To prevent a chicken-and-egg problem some configuration options, such as the location of the configuration file can be supplied only through xref:manual/configuration/properties.adoc[System properties]. ==== [#log4j-core-configuration-file] @@ -62,7 +62,9 @@ Upon initialization of a new logger context, Log4j assigns it a context name and . Files named `log4j2.` . Files named `log4j2.`, . If no configuration file could be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. -The default configuration prints all messages less specific than <> to the console. +The default configuration prints all messages less specific than +xref:manual/configuration/properties.adoc#log4j2.level[log4j2.level] +to the console. [CAUTION] ==== @@ -104,11 +106,12 @@ See xref:manual/webapp.adoc#configuration[Log4j [NOTE] ==== -It is also possible to override the location of the configuration file using the <> +It is also possible to override the location of the configuration file using the +xref:./configuration/properties.adoc#log4j2.configurationFile[log4j2.configurationFile] configuration property. In this case Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. -See <> for details. +See xref:./configuration/properties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. ==== === Syntax @@ -398,14 +401,15 @@ Unless the new configuration file removes an appender, the old one continues to |=== | Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[LEVEL] | Status | **DEPRECATED** -| Default value (since 2.24.0) | <> +| Default value (since 2.24.0) | xref:./configuration/properties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] | Default value (before 2.24.0) | value of `log4j2.defaultStatusLevel` |=== Overrides the logging level of the status logger. -WARNING: Since 2.24.0 this attribute is deprecated and should be replaced with the <> -variable. +WARNING: Since 2.24.0 this attribute is deprecated and will be replaced with the +xref:./configuration/properties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] +configuration property. [id=configuration-attribute-schema] ==== `schema` @@ -490,7 +494,8 @@ If `true` (default), all the messages received by this logger will also be trans | Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] | Default value a| -* <>, for `Root` and `AsyncRoot`, +* xref:./configuration/properties.adoc#log4j2.level[log4j2.level], +for `Root` and `AsyncRoot`, * inherited from the parent logger, for `Logger` and `AsyncLogger`. |=== @@ -507,12 +512,14 @@ See also xref:manual/filters.adoc#filters[Filters] if you require additional fil | Type | `boolean` | Default value a| -* `false`, if an asynchrounous `ContextSelector` is used. +* `false`, if an asynchronous `ContextSelector` is used. * Otherwise, ** `true` for `Root` and `Logger`, ** `false` for `AsyncRoot` and `AsyncLogger`. -See <> for more details. +See +xref:./configuration/properties.adoc#log4j2.contextSelector[log4j2.contextSelector] +for more details. |=== Specifies whether Log4j is allowed to compute location information. @@ -632,7 +639,7 @@ If `name` contains a `:` character, it is expanded as in the rule below. ==== `${lookup:name}`:: -If both these considitions hold: +If both these conditions hold: + -- * `lookup` is a prefix assigned to a xref:manual/lookups.adoc[Lookup], @@ -663,7 +670,7 @@ If `name` contains a `:` character, it is expanded as in the rule below. `${lookup:name:-default}`:: + -If both these considitions hold: +If both these conditions hold: + -- * `lookup` is a prefix assigned to a xref:manual/lookups.adoc[Lookup], @@ -732,10 +739,10 @@ Java properties:: include::example$configuration/routing.properties[tag=appender] ---- ==== -<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. + +<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. [#log4j-core-programmatic-configuration] -== Programmatic configuration - -include::_properties.adoc[leveloffset=+1] \ No newline at end of file +== Programmatic configuration \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc index 30a502fe3a7..3b132b4f6b3 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc @@ -152,7 +152,7 @@ include::partial$properties-async-logger-config.adoc[leveloffset=+2] [id=properties-properties-context-selector] === Context selector -The link:../javadoc/log4j-core/org/apache/logging/log4j/core/selector/ContextSelector[ContextSelector] component specifies the strategy used by Log4j to create new logger contexts. +The link:javadoc/log4j-core/org/apache/logging/log4j/core/selector/ContextSelector[ContextSelector] component specifies the strategy used by Log4j to create new logger contexts. The choice of `ContextSelector` determines in particular: * how loggers are divided among logger contexts. @@ -243,7 +243,7 @@ include::partial$properties-log4j-spring-boot.adoc[leveloffset=+2] [id=property-sources] == Property sources -The Log4j configuration properties sub-system merges the content of multiple property sources that implement the Java interface link:../javadoc/log4j-api/org/apache/logging/log4j/util/PropertySource[PropertySource]. +The Log4j configuration properties sub-system merges the content of multiple property sources that implement the Java interface link:javadoc/log4j-api/org/apache/logging/log4j/util/PropertySource[PropertySource]. Additional property source classes can be added through: diff --git a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc index 220a49fc4ef..1763e1bcee2 100644 --- a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc @@ -82,7 +82,7 @@ reference these fields after the web application is undeployed. To avoid causing memory leaks, Log4j will not use these ThreadLocals when it detects that it is used in a web application (when the `javax.servlet.Servlet` class is in the classpath, or when system -property xref:manual/configuration.adoc#log4j2.isWebapp[log4j2.isWebapp] is set to `true`). +property xref:manual/configuration/properties.adoc#log4j2.isWebapp[log4j2.isWebapp] is set to `true`). Some garbage-reducing functionality does not rely on ThreadLocals and is enabled by default for all applications: in Log4j 2.6, converting log @@ -112,8 +112,8 @@ you may also configure a xref:manual/async.adoc#WaitStrategy[custom wait strateg There are separate system properties for manually controlling the mechanisms Log4j uses to avoid creating temporary objects: -* xref:manual/configuration.adoc#log4j2.enableThreadlocals[log4j2.enableThreadlocals] - if "true" (the default for non-web applications) objects are stored in ThreadLocal fields and reused, otherwise new objects are created for each log event. -* xref:manual/configuration.adoc#log4j2.enableDirectEncoders[log4j2.enableDirectEncoders] - if "true" (the default) +* xref:manual/configuration/properties.adoc#log4j2.enableThreadlocals[log4j2.enableThreadlocals] - if "true" (the default for non-web applications) objects are stored in ThreadLocal fields and reused, otherwise new objects are created for each log event. +* xref:manual/configuration/properties.adoc#log4j2.enableDirectEncoders[log4j2.enableDirectEncoders] - if "true" (the default) log events are converted to text and this text is converted to bytes without creating temporary objects. Note: _synchronous_ logging performance may be worse @@ -122,7 +122,7 @@ the shared buffer. If your application is multi-threaded and logging performance is important, consider using Async Loggers. * The ThreadContext map is _not_ garbage-free by default, but from Log4j 2.7 it can be configured to be garbage-free by setting system property -xref:manual/configuration.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". +xref:manual/configuration/properties.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". Instead of system properties, the above properties can also be specified in a file named `log4j2.component.properties` by including this file in diff --git a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc index a5439324f61..cf47226659d 100644 --- a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc @@ -34,15 +34,20 @@ JMX support is disabled by default. NOTE: JMX support was enabled by default in Log4j 2 versions before 2.24.0. -To enable JMX support, set the following system property when starting the Java VM: +To enable JMX support, set the +xref:manual/configuration/properties.adoc#log4j2.disableJmx[log4j2.disableJmx] +system property when starting the Java VM: -`xref:manual/configuration.adoc#log4j2.disableJmx[log4j2.disableJmx]=false` +`log4j2.disableJmx=false` [#Local] == Local Monitoring and Management -To perform local monitoring you need to specify the `xref:manual/configuration.adoc#log4j2.disableJmx[log4j2.disableJmx]=false` system -property. The JConsole tool that is included in the Java JDK can be +To perform local monitoring you need to set the +xref:manual/configuration/properties.adoc#log4j2.disableJmx[log4j2 +.disableJmx] +system property to `false`. +The JConsole tool that is included in the Java JDK can be used to monitor your application. Start JConsole by typing `$JAVA_HOME/bin/jconsole` in a command shell. For more details, see Oracle's documentation on @@ -55,7 +60,7 @@ to use JConsole]. To enable monitoring and management from remote systems, set the following two system properties when starting the Java VM: -`xref:manual/configuration.adoc#log4j2.disableJmx[log4j2.disableJmx]=false` +`log4j2.disableJmx=false` and From a330c6bca35922dcf47e5404fd4e8018122713fb Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Sun, 12 May 2024 12:07:04 +0200 Subject: [PATCH 04/24] Add arbiters and scripts --- .../configuration/arbiters-select.json | 29 + .../configuration/arbiters-select.properties | 15 + .../configuration/arbiters-select.xml | 22 + .../configuration/arbiters-select.yaml | 18 + .../ROOT/examples/configuration/arbiters.json | 33 + .../configuration/arbiters.properties | 16 + .../ROOT/examples/configuration/arbiters.xml | 20 + .../ROOT/examples/configuration/arbiters.yaml | 18 + .../ROOT/examples/configuration/scripts.json | 65 ++ .../examples/configuration/scripts.properties | 51 ++ .../ROOT/examples/configuration/scripts.xml | 50 ++ .../ROOT/examples/configuration/scripts.yaml | 54 ++ .../configuration/xinclude-appenders.xml | 9 + .../configuration/xinclude-loggers.xml | 9 + .../examples/configuration/xinclude-main.xml | 11 + src/site/antora/modules/ROOT/nav.adoc | 4 +- .../antora/modules/ROOT/pages/log4j-jul.adoc | 2 +- .../log4j-spring-cloud-config-client.adoc | 4 +- .../modules/ROOT/pages/manual/appenders.adoc | 2 +- .../modules/ROOT/pages/manual/async.adoc | 6 +- .../ROOT/pages/manual/configuration.adoc | 551 ++++++++++++-- .../ROOT/pages/manual/configuration_old.adoc | 715 ------------------ .../ROOT/pages/manual/garbagefree.adoc | 8 +- .../antora/modules/ROOT/pages/manual/jmx.adoc | 4 +- .../properties.adoc => systemproperties.adoc} | 0 25 files changed, 910 insertions(+), 806 deletions(-) create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/scripts.json create mode 100644 src/site/antora/modules/ROOT/examples/configuration/scripts.properties create mode 100644 src/site/antora/modules/ROOT/examples/configuration/scripts.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/scripts.yaml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml create mode 100644 src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml delete mode 100644 src/site/antora/modules/ROOT/pages/manual/configuration_old.adoc rename src/site/antora/modules/ROOT/pages/manual/{configuration/properties.adoc => systemproperties.adoc} (100%) diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json new file mode 100644 index 00000000000..a30901cebdf --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json @@ -0,0 +1,29 @@ +{ + "Configuration": { + "Appenders": { + "File": { + "name": "MAIN", + "Select": { + "SystemPropertyArbiter": { // <1> + "propertyName": "env", + "propertyValue": "dev", + "PatternLayout": { + "pattern": "%d [%t] %p %c - %m%n" + } + }, + "DefaultArbiter": { // <2> + "JsonTemplateLayout": {} + } + } + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "MAIN" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties new file mode 100644 index 00000000000..006414a3c28 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties @@ -0,0 +1,15 @@ +appender.0.type = File +appender.0.name = MAIN +appender.0.select.type = Select + +appender.0.select.0.type = SystemPropertyArbiter # <1> +appender.0.select.0.propertyName = env +appender.0.select.0.propertyValue = dev +appender.0.select.0.layout.type = PatternLayout +appender.0.select.0.layout.pattern = %d [%t] %p %c - %m%n + +appender.0.select.1.type = DefaultArbiter # <2> +appender.0.select.1.layout.type = JsonTemplateLayout + +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = MAIN \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml new file mode 100644 index 00000000000..a1afe264218 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml new file mode 100644 index 00000000000..1ddaed5a155 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml @@ -0,0 +1,18 @@ +Configuration: + Appenders: + File: + name: "MAIN" + fileName: "logs/app.log" + Select: + SystemPropertyArbiter: # <1> + propertyName: "env" + propertyValue: "dev" + PatternLayout: + pattern: "%d [%t] %p %c - %m%n" + DefaultArbiter: # <2> + JsonTemplateLayout: { } + Loggers: + Root: + level: "INFO" + AppenderRef: + ref: "MAIN" diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.json b/src/site/antora/modules/ROOT/examples/configuration/arbiters.json new file mode 100644 index 00000000000..d732aaaa7ae --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters.json @@ -0,0 +1,33 @@ +{ + "Configuration": { + "Appenders": { + "File": { + "name": "MAIN", + "SystemPropertyArbiter": [ + // <1> + { + "propertyName": "env", + "propertyValue": "dev", + "PatternLayout": { + "pattern": "%d [%t] %p %c - %m%n" + } + }, + // <2> + { + "propertyName": "env", + "propertyValue": "prod", + "JsonTemplateLayout": {} + } + ] + } + }, + "Loggers": { + "Root": { + "level": "INFO", + "AppenderRef": { + "ref": "MAIN" + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.properties b/src/site/antora/modules/ROOT/examples/configuration/arbiters.properties new file mode 100644 index 00000000000..7c4f664549a --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters.properties @@ -0,0 +1,16 @@ +appender.0.type = File +appender.0.name = MAIN + +appender.0.arbiter[0].type = SystemPropertyArbiter # <1> +appender.0.arbiter[0].propertyName = env +appender.0.arbiter[0].propertyValue = dev +appender.0.arbiter[0].layout.type = PatternLayout +appender.0.arbiter[0].layout.pattern = %d [%t] %p %c - %m%n + +appender.0.arbiter[1].type = SystemPropertyArbiter # <2> +appender.0.arbiter[1].propertyName = env +appender.0.arbiter[1].propertyValue = prod +appender.0.arbiter[1].layout.type = JsonTemplateLayout + +rootLogger.level = INFO +rootLogger.appenderRef.0.ref = MAIN \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml b/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml new file mode 100644 index 00000000000..0e17becbe28 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml b/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml new file mode 100644 index 00000000000..4bb5c7bb173 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml @@ -0,0 +1,18 @@ +Configuration: + Appenders: + File: + name: "MAIN" + fileName: "logs/app.log" + SystemPropertyArbiter: + - propertyName: "env" # <1> + propertyValue: "dev" + PatternLayout: + pattern: "%d [%t] %p %c - %m%n" + - propertyName: "env" # <2> + propertyValue: "prod" + JsonTemplateLayout: { } + Loggers: + Root: + level: "INFO" + AppenderRef: + ref: "MAIN" diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.json b/src/site/antora/modules/ROOT/examples/configuration/scripts.json new file mode 100644 index 00000000000..5a8aeaa4849 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.json @@ -0,0 +1,65 @@ +{ + "Configuration": { + "Appenders": { + "Console": { + "name": "STDOUT", + "PatternLayout": { + "ScriptPatternSelector": { + "defaultPattern": "%d %p %m%n", + "ScriptRef": { + "ref": "selector", + "PatternMatch": [ + { + "key": "NoLocation", + "pattern": "[%-5level] %c{1.} %msg%n" + }, + { + "key": "Flow", + "pattern": "[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n" + } + ] + } + } + } + }, + "Loggers": { + "Logger": { + "name": "EventLogger", + "ScriptFilter": { + "onMatch": "ACCEPT", + "onMismatch": "DENY", + "Script": { + "name": "EventLogger-filter", + "language": "groovy", + "scriptText": "if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf(\"FLOW\"))) { return true; } else if (logEvent.getContextMap().containsKey(\"UserId\")) { return true; } return false;" + } + } + }, + "Root": { + "level": "INFO", + "ScriptFilter": { + "onMatch": "ACCEPT", + "onMismatch": "DENY", + "ScriptRef": { + "ref": "Root-filter" + } + }, + "AppenderRef": { + "ref": "STDOUT" + } + }, + "Scripts": { + "Script": { + "name": "selector", + "language": "javascript", + "scriptText": "var result; if (logEvent.getLoggerName().equals(\"JavascriptNoLocation\")) { result = \"NoLocation\"; } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf(\"FLOW\")) { result = \"Flow\"; } result;" + }, + "ScriptFile": { + "name": "Root-filter", + "path": "scripts/filter.groovy" + } + } + } + } + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.properties b/src/site/antora/modules/ROOT/examples/configuration/scripts.properties new file mode 100644 index 00000000000..d09c3949777 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.properties @@ -0,0 +1,51 @@ +appender.0.type = Console +appender.0.name = STDOUT +appender.0.layout.type = PatternLayout + +appender.0.layout.selector = ScriptPatternSelector +appender.0.layout.selector.defaultPattern = %d %p %m%n +appender.0.layout.selector.scriptRef.type = ScriptRef +appender.0.layout.selector.scriptRef.ref = selector +appender.0.layout.selector.match[0].type = PatternMatch +appender.0.layout.selector.match[0].key = NoLocation +appender.0.layout.selector.match[0].pattern = [%-5level] %c{1.} %msg%n +appender.0.layout.selector.match[1].type = PatternMatch +appender.0.layout.selector.match[1].key = Flow +appender.0.layout.selector.match[1].pattern = [%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n + +logger.0.name = EventLogger +logger.0.filter.0.type = ScriptFilter +logger.0.filter.0.onMatch = ACCEPT +logger.0.filter.0.onMismatch = DENY +logger.0.filter.0.script.type = Script +logger.0.filter.0.script.name = EventLogger-filter +logger.0.filter.0.script.language = groovy +logger.0.filter.0.script.scriptText = if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW"))) {\ + return true;\ + } else if (logEvent.getContextMap().containsKey("UserId")) {\ + return true;\ + }\ + return false; + +rootLogger.level = INFO +rootLogger.filter.0.type = ScriptFilter +rootLogger.filter.0.onMatch = ACCEPT +rootLogger.filter.0.onMismatch = DENY +rootLogger.filter.0.scriptRef.type = ScriptRef +rootLogger.filter.0.scriptRef.ref = Root-Filter +rootLogger.appenderRef.0.ref = STDOUT + +script.0.type = Script +script.0.name = selector +script.0.language = javascript +script.0.scriptText = var result;\ + if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {\ + result = "NoLocation";\ + } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {\ + result = "Flow";\ + }\ + result; + +script.1.type = ScriptFile +script.1.name = Root-filter +script.1.path = scripts/filter.groovy diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.xml b/src/site/antora/modules/ROOT/examples/configuration/scripts.xml new file mode 100644 index 00000000000..4334eb7c826 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml b/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml new file mode 100644 index 00000000000..de5252dcd76 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml @@ -0,0 +1,54 @@ +Configuration: + Appenders: + Console: + name: "STDOUT" + PatternLayout: + ScriptPatternSelector: + defaultPattern: "%d %p %m%n" + ScriptRef: + ref: "selector" + PatternMatch: + - key: "NoLocation" + pattern: "[%-5level] %c{1.} %msg%n" + - key: "Flow" + pattern: "[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n" + Loggers: + Logger: + name: "EventLogger" + ScriptFilter: + onMatch: "ACCEPT" + onMismatch: "DENY" + Script: + name: "EventLogger-filter" + language: "groovy" + scriptText: | + if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { + return true; + } else if (logEvent.getContextMap().containsKey("UserId")) { + return true; + } + return false; + Root: + level: "INFO" + ScriptFilter: + onMatch: "ACCEPT" + onMismatch: "DENY" + ScriptRef: + ref: "Root-filter" + AppenderRef: + ref: "STDOUT" + Scripts: + Script: + name: "selector" + language: "javascript" + scriptText: | + var result; + if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { + result = "NoLocation"; + } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { + result = "Flow"; + } + result; + ScriptFile: + name: "Root-filter" + path: "scripts/filter.groovy" diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml new file mode 100644 index 00000000000..2a129061692 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml new file mode 100644 index 00000000000..408560cb9f0 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml new file mode 100644 index 00000000000..130b9ada716 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/nav.adoc b/src/site/antora/modules/ROOT/nav.adoc index b7789787fdc..218fec59597 100644 --- a/src/site/antora/modules/ROOT/nav.adoc +++ b/src/site/antora/modules/ROOT/nav.adoc @@ -41,6 +41,9 @@ ** xref:manual/scoped-context.adoc[] ** xref:manual/resource-logger.adoc[] * xref:manual/configuration.adoc[] +** xref:manual/configuration.adoc#configuration-file[Configuration file] +** xref:manual/customconfig.adoc[] +** xref:manual/systemproperties.adoc[] * xref:manual/usage.adoc[] * xref:manual/cloud.adoc[] * xref:manual/lookups.adoc[] @@ -52,7 +55,6 @@ * xref:manual/garbagefree.adoc[] * xref:manual/extending.adoc[] * xref:manual/plugins.adoc[] -* xref:manual/customconfig.adoc[] * xref:manual/customloglevels.adoc[] * xref:manual/jmx.adoc[] * xref:manual/logsep.adoc[] diff --git a/src/site/antora/modules/ROOT/pages/log4j-jul.adoc b/src/site/antora/modules/ROOT/pages/log4j-jul.adoc index e141ea06131..d6974a822e2 100644 --- a/src/site/antora/modules/ROOT/pages/log4j-jul.adoc +++ b/src/site/antora/modules/ROOT/pages/log4j-jul.adoc @@ -55,7 +55,7 @@ plugin. Java logging levels are translated into Log4j logging levels dynamically. The following table lists the conversions between a Java logging level and its equivalent Log4j level. Custom levels should be implemented as an implementation of `LevelConverter`, and the Log4j property -xref:manual/configuration/properties.adoc#log4j2.julLevelConverter[log4j2.julLevelConverter] +xref:manual/systemproperties.adoc#log4j2.julLevelConverter[log4j2.julLevelConverter] must be set to your custom class name. Using the default `LevelConverter` implementation, custom logging levels are mapped to whatever the current level of the `Logger` being logged to is using. diff --git a/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc b/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc index 5eca408a296..ce8e4b31caa 100644 --- a/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc +++ b/src/site/antora/modules/ROOT/pages/log4j-spring-cloud-config-client.adoc @@ -25,7 +25,7 @@ Spring Boot applications initialize logging 3 times. . SpringApplication declares a Logger. This Logger will be initialized using Log4j's "normal" mechanisms. Thus, the -xref:manual/configuration/properties.adoc#log4j2.configurationFile[`log4j2.configurationFile`] +xref:manual/systemproperties.adoc#log4j2.configurationFile[`log4j2.configurationFile`] system property will be checked to see if a specific configuration file has been provided, otherwise it will search for a configuration file on the classpath. The property may also be declare in log4j2.component.properties. @@ -125,7 +125,7 @@ Note that Log4j currently does not directly support encrypting the password. However, Log4j does use Spring's standard APIs to access properties in the Spring configuration so any customizations made to Spring's property handling would apply to the properties Log4j uses as well. If more extensive authentication is required an `AuthorizationProvider` can be implemented and its fully qualified class name should be specified in the -xref:manual/configuration/properties.adoc#log4j2.configurationAuthorizationProvider[log4j2.configurationAuthorizationProvider] +xref:manual/systemproperties.adoc#log4j2.configurationAuthorizationProvider[log4j2.configurationAuthorizationProvider] system property, in log4j2.component.properties or in Spring's `bootstrap.yml` using either the `log4j2.authorizationProvider` or `logging.auth.authorizationProvider` key. For the properties required by TLS configuration see xref:manual/configuration.adoc#transport-security[the Transport Security configuration]. diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index 1431c9b49d6..07fca6666ee 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -120,7 +120,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration/properties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` and `log4j2.DiscardThreshold`]. A typical AsyncAppender configuration might look like: diff --git a/src/site/antora/modules/ROOT/pages/manual/async.adoc b/src/site/antora/modules/ROOT/pages/manual/async.adoc index 53e8e9f24f1..c334ccb2f07 100644 --- a/src/site/antora/modules/ROOT/pages/manual/async.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/async.adoc @@ -117,7 +117,7 @@ classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required._ This is simplest to configure and gives the best performance. -To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/configuration/properties.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. +To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/systemproperties.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. By default, link:#Location[location] is not passed to the I/O thread by asynchronous loggers. If one of your layouts or custom filters needs @@ -183,7 +183,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration/properties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` and `log4j2.discardThreshold`]. [#MixedSync-Async] @@ -257,7 +257,7 @@ There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. See the details for system properties -xref:manual/configuration/properties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy` and `log4j2.discardThreshold`]. [#custom-waitstrategy] diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 3f64c8b8661..a3ed9b7899e 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -14,25 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. //// +[id=configuration] = Configuration +Ralph Goers ; Piotr Karwasz + Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. In order to decide which of these statements will be logged and where, users need to configure Log4j Core. Log4j Core can be configured in two ways: -* through a <>. +* through a <>. Since version 2.0 the configuration file format is considered as part of the public API, and it remains stable even across major version upgrades. -* through <>, which provides a larger spectrum of possible customizations, but might require code changes even for minor version upgrades, according to https://semver.org/[semantic versioning] rules. +* through xref:manual/customconfig.adoc[Programmatic Configuration], which provides a larger spectrum of possible customizations, but might require code changes even for minor version upgrades, according to https://semver.org/[semantic versioning] rules. [NOTE] ==== -To prevent a chicken-and-egg problem some configuration options, such as the location of the configuration file can be supplied only through xref:manual/configuration/properties.adoc[System properties]. +To prevent a chicken-and-egg problem some configuration options, such as the location of the configuration file can be supplied only through xref:manual/systemproperties.adoc[System properties]. ==== -[#log4j-core-configuration-file] +[#configuration-file] == Configuration file TIP: For a quick example of configuration file see the xref:manual/installation.adoc#impl-core-config[Configuring Log4j Core section]. @@ -53,7 +56,7 @@ To enable partial support for old configuration formats see xref:manual/migratio ==== [id=automatic-configuration] -=== Configuration file location +=== [[AutomaticConfiguration]] Configuration file location Upon initialization of a new logger context, Log4j assigns it a context name and scans the following **classpath** locations for a configuration file: @@ -63,7 +66,7 @@ Upon initialization of a new logger context, Log4j assigns it a context name and . Files named `log4j2.`, . If no configuration file could be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. The default configuration prints all messages less specific than -xref:manual/configuration/properties.adoc#log4j2.level[log4j2.level] +xref:manual/systemproperties.adoc#log4j2.level[log4j2.level] to the console. [CAUTION] @@ -107,14 +110,15 @@ See xref:manual/webapp.adoc#configuration[Log4j [NOTE] ==== It is also possible to override the location of the configuration file using the -xref:./configuration/properties.adoc#log4j2.configurationFile[log4j2.configurationFile] +xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] configuration property. In this case Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. -See xref:./configuration/properties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. +See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. ==== -=== Syntax +[id=configuration-syntax] +=== [[ConfigurationSyntax]] Syntax All configuration files are parsed into a tree of link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node[Node]s, each representing a different Log4j component. The root of the tree creates a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration[Configuration] object. @@ -239,41 +243,12 @@ In the Java properties configuration format: ==== The id assigned to nested components is only used for sorting purposes. However, some components assign a special meaning to some ids. -See a list of exceptions below: -==== -+ -.Properties format quirks -[%collapsible,#properties-format-quirks] +See a list of exceptions in <>. ==== -The Java properties configuration format is by far the most verbose of the available formats. -In order to make it more usable a series of exceptions to the rules in <> have been introduced over time: -. The following direct children of `Configuration` have predefined prefixes and do not require to specify a `type` -attribute: -* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-AppendersPlugin[Appender container] has a predefined `appender` prefix. -* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevels[Custom levels container] has a predefined `customLevel` prefix. -* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggersPlugin[Loggers container] has a predefined `logger` prefix. -* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-PropertiesPlugin[Properties container] has a predefined `property` prefix. -* The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-ScriptsPlugin[Scripts container] has a predefined `script` prefix. -. Properties that start with `property` are used for <>. -Their syntax is `property. = `. -. The root logger can be configured using properties that start with `rootLogger`. -. A shorthand notation is available that allows users to write: -+ ----- -rootLogger = INFO, APPENDER ----- -+ -instead of: -+ ----- -rootLogger.level = INFO -rootLogger.appenderRef.0.ref = APPENDER ----- -. All the keys of the form `logger..appenderRef.`, where `` and `` are arbitrary, are considered appender references. -==== ===== +[id=main-configuration-elements] === Main configuration elements Log4j Core's logging pipeline is quite complex (see xref:manual/architecture.adoc[Architecture]), but most users only require these elements: @@ -282,19 +257,26 @@ Loggers:: + Loggers are the entry point of the logging pipeline, directly used in code. Their configuration must specify which level of messages they log and to which appenders they send the messages. ++ +See <> for details. -Appenders:: +[id=configuring-appenders] +[[Appenders]] Appenders:: + Appenders are the exit point of the logging pipeline. They decide to which resource (console, file, database, etc.) the log event is sent. -For a complete list see xref:manual/appenders.adoc[Appenders]. -In this chapter we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender] in the examples. +In the examples of this chapter we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender] in the examples. ++ +See xref:manual/appenders.adoc[Appender configuration] for details. Layouts:: + Layouts tell appenders how they should format the log event: text, JSON, XML, etc. -For a complete list see xref:manual/layouts.adoc[Layouts]. -In this chapter we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] and xref:manual/json-template-layout.adoc[JSON template layout] in the examples. +In the examples of this chapter we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] +and +xref:manual/json-template-layout.adoc[JSON template layout] in the examples. ++ +See xref:manual/layouts.adoc[Layout configuration] for details. A moderately complex configuration might look like this: @@ -367,6 +349,34 @@ The logger is configured to forward messages to its parent (the root appender). |=== +[id=additional-configuration-elements] +=== Additional configuration elements + +A Log4j Core configuration file can also contain these configuration elements: + +CustomLevels:: ++ +Log4j allows to configure custom level names. ++ +See xref:manual/customloglevels.adoc[Custom log level configuration] for details. + +Filters:: ++ +Components that can be added to loggers, appender references, appenders or the global configuration object to provide additional filtering of log events. ++ +See xref:manual/filters.adoc[Filter configuration] for details. + +Properties:: ++ +A set of reusable configuration values for property substitution. ++ +See <> for details. + +Scripts:: ++ +See <> for details. + +[id=global-configuration-attributes] === Global configuration attributes The main `Configuration` element has a set of attributes that can be used to tune the way the configuration file itself is used. @@ -374,7 +384,7 @@ The principal attributes are listed below. See xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Configuration[Plugin reference] for a complete list. [id=configuration-attribute-monitorInterval] -==== `monitorInterval` +==== [[AutomaticReconfiguration]] `monitorInterval` [cols="1h,5"] |=== @@ -384,14 +394,19 @@ See xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-lo Determines the polling interval used by Log4j to check for changes to the configuration file. +If a change in the configuration file is detected, Log4j automatically reconfigures the logger context. + If set to `0`, polling is disabled. -[NOTE] +[CAUTION] ==== -Unlike other logging backends Log4j Core is designed with audit logging in mind. +Unlike other logging backends Log4j Core is designed with **audit** logging in mind. During a reconfiguration process, no messages are lost. + Unless the new configuration file removes an appender, the old one continues to work without interruption. +This behavior also implies that changes to appenders that modify the options of the resource used by the appender (e.g. a change in the `append` attribute of a file appender) will be **ignored**. +In order to modify these options during a reconfiguration you also need to change the resource used by the appender (e .g. the file name used by a file appender). ==== [id=configuration-attribute-status] @@ -401,42 +416,23 @@ Unless the new configuration file removes an appender, the old one continues to |=== | Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[LEVEL] | Status | **DEPRECATED** -| Default value (since 2.24.0) | xref:./configuration/properties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] +| Default value (since 2.24.0) | xref:manual/systemproperties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] | Default value (before 2.24.0) | value of `log4j2.defaultStatusLevel` |=== Overrides the logging level of the status logger. WARNING: Since 2.24.0 this attribute is deprecated and will be replaced with the -xref:./configuration/properties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] +xref:manual/systemproperties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] configuration property. -[id=configuration-attribute-schema] -==== `schema` - -[cols="1h,5"] -|=== -| Type | classpath resource -| Default value | `null` -|=== - -[id=configuration-attribute-strict] -==== `strict` - -[cols="1h,5"] -|=== -| Type | `boolean` -| Default value | `false` -|=== - -If set to `true` all configuration files will be checked against. - [id=configuration-elements-filters] ==== Filters See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to the global configuration object. -=== Logger configuration +[id=configuring-loggers] +=== [[Loggers]] Loggers Log4j 2 contains multiple types of logger components that can be added to the `Loggers` element of the configuration: @@ -459,7 +455,7 @@ See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apac Every configuration **must** have at least a `Root` or `AsyncRoot` element. The presence of other logger configurations is optional. -The logger components can have the following attributes and elements: +The logger components can have the following configuration attributes and elements: [id=logger-attributes-name] ==== `name` @@ -475,7 +471,7 @@ Specifies the name of the logger configuration. Since loggers are usually named using fully qualified class names, this value usually contains the fully qualified name of a class or a package. [id=logger-attributes-additivity] -==== `additivity` +==== [[Additivity]] `additivity` [cols="1h,5"] |=== @@ -494,7 +490,7 @@ If `true` (default), all the messages received by this logger will also be trans | Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] | Default value a| -* xref:./configuration/properties.adoc#log4j2.level[log4j2.level], +* xref:manual/systemproperties.adoc#log4j2.level[log4j2.level], for `Root` and `AsyncRoot`, * inherited from the parent logger, for `Logger` and `AsyncLogger`. |=== @@ -518,7 +514,7 @@ a| ** `false` for `AsyncRoot` and `AsyncLogger`. See -xref:./configuration/properties.adoc#log4j2.contextSelector[log4j2.contextSelector] +xref:manual/systemproperties.adoc#log4j2.contextSelector[log4j2.contextSelector] for more details. |=== @@ -534,6 +530,13 @@ This setting only applies to computation of location at **runtime**. If the location is computed at build time using link:/log4j/transform/latest/#log4j-transform-maven-plugin[Log4j Transform Maven Plugin] this setting is ignored and location information will always be available for logging. ==== +[id=logger-elements-appenderrefs] +==== Appender references + +Loggers use appender references to list the appenders to use to deliver log events. + +See <> below for more details. + [id=logger-elements-properties] ==== Additional context properties @@ -585,6 +588,43 @@ include::example$configuration/logger-properties.properties[tag=loggers] See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to a logger configuration. +[id=configuring-appenderrefs] +=== Appender references + +Many Log4j components such as loggers use appender references to designate, which appenders will be used to deliver their events. + +Unlike Log4j 1, where appender references were simple pointers, in Log4j 2 they have additional filtering capabilities. + +Appender references can have the following configuration attributes and elements: + +[id=appenderref-attributes-name] +==== `ref` + +[cols="1h,5"] +|=== +| Type | `String` +|=== + +Specifies the name of the appender to use. + +[id=appenderref-attributes-level] +==== `level` + +[cols="1h,5"] +|=== +| Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] +|=== + +Specifies the level threshold that a log event must have to be logged. +Log events more specific than this setting will be filtered out. + +See also xref:manual/filters.adoc#filters[Filters] if you require additional filtering. + +[id=appenderrefs-elements-filters] +==== Filters + +See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilities that can be applied to a logger configuration. + [id=property-substitution] === Property substitution @@ -744,5 +784,362 @@ include::example$configuration/routing.properties[tag=appender] 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. -[#log4j-core-programmatic-configuration] -== Programmatic configuration \ No newline at end of file +[id=arbiters] +=== [[Arbiters]] Arbiters + +While property substitution allows to use the same configuration file in multiple deployment environments, sometimes changing the values of configuration attributes is not enough. + +Arbiters are to configuration elements what property substitution is for configuration attributes: they allow to conditionally add a subtree of configuration elements to a configuration file. + +Arbiters may occur anywhere an element is allowed in the configuration and can be nested. +So an Arbiter could encapsulate something as simple as a single property declaration or a whole set of appenders, loggers or other arbiters. +The child elements of an arbiter must be valid elements for whatever element is the parent of the arbiter. + +For a complete list of available arbiters see +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-Arbiter[plugin reference]. +In the examples below we'll just use the +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-DefaultArbiter[DefaultArbiter], +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-SelectArbiter[Select] +and +xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-arbiters-SystemPropertyArbiter[SystemPropertyArbiter]. + +For example, you might want to use a different layout in a production and development environment: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$configuration/arbiters.xml[] +---- + +JSON:: ++ +[source,json] +---- +include::example$configuration/arbiters.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$configuration/arbiters.yaml[] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$configuration/arbiters.properties[] +---- +==== + +<1> If the Java system property `env` has a value of `dev`, a pattern layout will be used. +<2> If the Java system property `env` has a value of `prod`, a JSON template layout will be used. + +The above example has a problem: if the Java system property `env` has a value different from `dev` or `prod`, the appender will have no layout. + +This is a case, when the `Select` plugin is useful: this configuration element contains a list of arbiters and a +`DefaultArbiter` element. +If none of the arbiters match, the configuration from the `DefaultArbiter` element will be used: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$configuration/arbiters-select.xml[] +---- + +JSON:: ++ +[source,json] +---- +include::example$configuration/arbiters-select.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$configuration/arbiters-select.yaml[] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$configuration/arbiters-select.properties[] +---- +==== + +<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. + +[#CompositeConfiguration] +=== Composite Configuration + +Log4j allows multiple configuration files to be used at the same time by specifying them as a list of comma separated file paths or URLs in the +xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] +configuration property. + +These configuration files are merged into a single configuration file using +link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/composite/MergeStrategy.html[MergeStrategy] +service that can be customized using the +xref:manual/systemproperties.adoc#log4j2.mergeStrategy[log4j2.mergeStrategy] +configuration property. + +The default merge strategy will merge the files using the following rules: + +. <> in later configurations replace those in previous configurations. ++ +The exception is the `monitorInterval` attribute: the lowest positive value from all the configuration files will be used. + +. <> from all configurations are aggregated. +Duplicate properties replace those in previous configurations. + +. xref:manual/filters.adoc[Filters] are aggregated under +xref:manual/filters.adoc#CompositeFilter[CompositeFilter], if more than one filter is defined. + +. <> are aggregated. +Duplicate definitions replace those in previous configurations. + +. xref:manual/appenders.adoc[Appenders] are aggregated. +Appenders with the same name are **replaced** by those in later configurations, including all their elements. + +. <> are all aggregated. +Logger attributes are individually merged with duplicates being replaced by those in later configurations. +Appender references on a logger are aggregated with duplicates being replaced by those in later configurations. +The strategy merges filters on loggers using the rule above. + +[id=scripts] +=== [[Scripts]] Scripts + +Log4j provides support for +https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR +223] scripting languages to be used in some of its components. + +[WARNING] +==== +In order to enable a scripting language, its name must be included in the +xref:manual/systemproperties.adoc#log4j2.scriptEnableLanguages[log4j2.scriptEnableLanguages] +configuration property. +==== + +Each component that allows scripts can contain on of the following configuration elements: + +Script:: ++ +This element specifies the content of the script directly and has: ++ +-- +* a required `language` configuration attribute that specifies the name of the JSR 223 language to use, +* a required `scriptText` configuration attribute that contains the text of the script. +In the XML configuration format, the text of the script can also be written as content of the ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----- - -If the status attribute on the Configuration element is set to DEBUG the -list of script engines currently installed and their attributes will be -listed. Although some engines may say they are not thread safe, Log4j -takes steps to insure that the scripts will run in a thread-safe manner -if the engine advertises that it is not thread safe. - -.... -2015-09-27 16:13:22,925 main DEBUG Installed script engines -2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe, - Compile: false, Names: {AppleScriptEngine, AppleScript, OSA} -2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED, - Compile: true, Names: {groovy, Groovy} -2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED, - Compile: true, Names: {beanshell, bsh, java} -2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED, - Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript} -.... - -When the scripts are executed they will be provided with a set of -variables that should allow them to accomplish whatever task they are -expected to perform. See the documentation for the individual components -for the list of variables that are available to the script. - -The components that support scripting expect a return value to be passed -back to the calling Java code. This is not a problem for several of the -scripting languages, but Javascript does not allow a return statement -unless it is within a function. However, Javascript will return the -value of the last statement executed in the script. As a consequence, -code such as that shown below will result in the desired behavior. - -[source,javascript] ----- -var result; -if (logEvent.getLoggerName().equals("JavascriptNoLocation")) { - result = "NoLocation"; -} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { - result = "Flow"; -} -result; ----- - -=== A special note on Beanshell - -JSR 223 scripting engines are supposed to identify that they support the -Compilable interface if they support compiling their scripts. Beanshell -does this. However, whenever the compile method is called it throws an -Error (not an Exception). Log4j catches this but will log the warning -shown below for each Beanshell script when it tries to compile them. All -Beanshell scripts will then be interpreted on each execution. - -.... -2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable -2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented - at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175) - at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154) - at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.(ScriptManager.java:125) - at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94) - -.... - -[#XInclude] -== XInclude - -XML configuration files can include other files with -http://www.xml.com/lpt/a/1009[XInclude]. Here is an example log4j2.xml -file that includes two other files: - -.log4j2.xml -[source,xml] ----- - - - - xinclude-demo.log - - - - - ----- - -.log4j-xinclude-appenders.xml -[source,xml] ----- - - - - - - - - %d %p %C{1.} [%t] %m%n - - - ----- - -.log4j-xinclude-loggers.xml -[source,xml] ----- - - - - - - - - - - - - - - - - - ----- - -[#CompositeConfiguration] -== Composite Configuration - -Log4j allows multiple configuration files to be used by specifying them -as a list of comma separated file paths on log4j2.configurationFile or, -when using URLs, by adding secondary configuration locations as query -parameters named "override". The merge logic can be controlled by specifying -a class that implements the MergeStrategy interface on the log4j.mergeStrategy -property. The default merge strategy will merge the files using the following rules: - -1. The global configuration attributes are aggregated with those in -later configurations replacing those in previous configurations, with -the exception that the highest status level and the lowest -monitorInterval greater than 0 will be used. -2. Properties from all configurations are aggregated. Duplicate -properties replace those in previous configurations. -3. Filters are aggregated under a CompositeFilter if more than one -Filter is defined. Since Filters are not named duplicates may be -present. -4. Scripts and ScriptFile references are aggregated. Duplicate -definitions replace those in previous configurations. -5. Appenders are aggregated. Appenders with the same name are replaced -by those in later configurations, including all of the Appender's -subcomponents. -6. Loggers are all aggregated. Logger attributes are individually -merged with duplicates being replaced by those in later configurations. -Appender references on a Logger are aggregated with duplicates being -replaced by those in later configurations. Filters on a Logger are -aggregated under a CompositeFilter if more than one Filter is defined. -Since Filters are not named duplicates may be present. Filters under -Appender references included or discarded depending on whether their -parent Appender reference is kept or discarded. - -[#StatusMessages] -== Status Messages - -**** -*Troubleshooting tip for the impatient:* - -From log4j-2.9 onward, log4j2 will print all internal logging to the -console if system property `log4j2.debug` is either defined empty or its value -equals to `true` (ignoring case). - -Prior to log4j-2.9, there are two places where internal logging can be -controlled: - -* Before a configuration is found, status logger level can be controlled -with system property -`org.apache.logging.log4j.simplelog.StatusLogger.level`. -* After a configuration is found, status logger level can be controlled -in the configuration file with the "status" attribute, for example: -``. -**** - -Just as it is desirable to be able to diagnose problems in applications, -it is frequently necessary to be able to diagnose problems in the -logging configuration or in the configured components. Since logging has -not been configured, "normal" logging cannot be used during -initialization. In addition, normal logging within appenders could -create infinite recursion which Log4j will detect and cause the -recursive events to be ignored. To accomodate this need, the Log4j 2 API -includes a -link:../javadoc/log4j-api/org/apache/logging/log4j/status/StatusLogger.html[`StatusLogger`]. -Components declare an instance of the StatusLogger similar to: - -[source,java] ----- -protected final static Logger logger = StatusLogger.getLogger(); ----- - -Since StatusLogger implements the Log4j 2 API's Logger interface, all -the normal Logger methods may be used. - -When configuring Log4j it is sometimes necessary to view the generated status events. -This can be accomplished by adding the status attribute to the configuration element or a default value can be provided by setting the xref:statusLoggerLevel["log4j2.statusLoggerLevel"] system property. -Valid values of the status attribute are "trace", "debug", "info", "warn", "error" and "fatal". -The following configuration has the status attribute set to debug. - -[source,xml] ----- - - - - target/rolling1/rollingtest-$${sd:type}.log - - - - - - - - - - - - - - %d %p %c{1.} [%t] %m%n - - - - - - - - - - - - - - - - - - - - ----- - -During startup this configuration produces: - -.... -2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds -2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${sd:type}.log") -2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${sd:type}.log}) -2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds -2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") -2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null") -2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds -2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null") -2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null") -2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route) -2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route) -2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit')}) -2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null) -2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing}) -2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing") -2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null) -2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT") -2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null) -2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root}) -2011-11-23 17:08:00,834 DEBUG Reconfiguration completed -2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null") -2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500") -2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null") -2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds -2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher$AppClassLoader@37b90b39 -2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds -2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds -2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds -2011-11-23 17:08:00,965 WARN No Loggers were configured, using default -2011-11-23 17:08:00,976 DEBUG Reconfiguration completed -.... - -If the status attribute is set to error then only error messages will be -written to the console. This makes troubleshooting configuration errors -possible. As an example, if the configuration above is changed to have -the status set to error and the logger declaration is: - -[source,xml] ----- - - - ----- - -the following error message will be produced. - -.... -2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger -.... - -Applications may wish to direct the status output to some other -destination. This can be accomplished by setting the dest attribute to -either "err" to send the output to stderr or to a file location or URL. -This can also be done by insuring the configured status is set to OFF -and then configuring the application programmatically such as: - -[source,java] ----- -StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR); -StatusLogger.getLogger().registerListener(listener); ----- - - diff --git a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc index 1763e1bcee2..426af6b5d83 100644 --- a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc @@ -82,7 +82,7 @@ reference these fields after the web application is undeployed. To avoid causing memory leaks, Log4j will not use these ThreadLocals when it detects that it is used in a web application (when the `javax.servlet.Servlet` class is in the classpath, or when system -property xref:manual/configuration/properties.adoc#log4j2.isWebapp[log4j2.isWebapp] is set to `true`). +property xref:manual/systemproperties.adoc#log4j2.isWebapp[log4j2.isWebapp] is set to `true`). Some garbage-reducing functionality does not rely on ThreadLocals and is enabled by default for all applications: in Log4j 2.6, converting log @@ -112,8 +112,8 @@ you may also configure a xref:manual/async.adoc#WaitStrategy[custom wait strateg There are separate system properties for manually controlling the mechanisms Log4j uses to avoid creating temporary objects: -* xref:manual/configuration/properties.adoc#log4j2.enableThreadlocals[log4j2.enableThreadlocals] - if "true" (the default for non-web applications) objects are stored in ThreadLocal fields and reused, otherwise new objects are created for each log event. -* xref:manual/configuration/properties.adoc#log4j2.enableDirectEncoders[log4j2.enableDirectEncoders] - if "true" (the default) +* xref:manual/systemproperties.adoc#log4j2.enableThreadlocals[log4j2.enableThreadlocals] - if "true" (the default for non-web applications) objects are stored in ThreadLocal fields and reused, otherwise new objects are created for each log event. +* xref:manual/systemproperties.adoc#log4j2.enableDirectEncoders[log4j2.enableDirectEncoders] - if "true" (the default) log events are converted to text and this text is converted to bytes without creating temporary objects. Note: _synchronous_ logging performance may be worse @@ -122,7 +122,7 @@ the shared buffer. If your application is multi-threaded and logging performance is important, consider using Async Loggers. * The ThreadContext map is _not_ garbage-free by default, but from Log4j 2.7 it can be configured to be garbage-free by setting system property -xref:manual/configuration/properties.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". +xref:manual/systemproperties.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". Instead of system properties, the above properties can also be specified in a file named `log4j2.component.properties` by including this file in diff --git a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc index cf47226659d..a6a5f933614 100644 --- a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc @@ -35,7 +35,7 @@ JMX support is disabled by default. NOTE: JMX support was enabled by default in Log4j 2 versions before 2.24.0. To enable JMX support, set the -xref:manual/configuration/properties.adoc#log4j2.disableJmx[log4j2.disableJmx] +xref:manual/systemproperties.adoc#log4j2.disableJmx[log4j2.disableJmx] system property when starting the Java VM: `log4j2.disableJmx=false` @@ -44,7 +44,7 @@ system property when starting the Java VM: == Local Monitoring and Management To perform local monitoring you need to set the -xref:manual/configuration/properties.adoc#log4j2.disableJmx[log4j2 +xref:manual/systemproperties.adoc#log4j2.disableJmx[log4j2 .disableJmx] system property to `false`. The JConsole tool that is included in the Java JDK can be diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc similarity index 100% rename from src/site/antora/modules/ROOT/pages/manual/configuration/properties.adoc rename to src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc From 1d1a69cf25dc1d12ff078db6fb554d070466998e Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Sun, 12 May 2024 14:01:07 +0200 Subject: [PATCH 05/24] Move scripts to a separate file --- src/site/antora/modules/ROOT/nav.adoc | 19 +-- .../ROOT/pages/manual/configuration.adoc | 117 +--------------- .../modules/ROOT/pages/manual/scripts.adoc | 127 ++++++++++++++++++ 3 files changed, 139 insertions(+), 124 deletions(-) create mode 100644 src/site/antora/modules/ROOT/pages/manual/scripts.adoc diff --git a/src/site/antora/modules/ROOT/nav.adoc b/src/site/antora/modules/ROOT/nav.adoc index 218fec59597..dc69a9c656a 100644 --- a/src/site/antora/modules/ROOT/nav.adoc +++ b/src/site/antora/modules/ROOT/nav.adoc @@ -40,22 +40,23 @@ ** xref:manual/thread-context.adoc[] ** xref:manual/scoped-context.adoc[] ** xref:manual/resource-logger.adoc[] -* xref:manual/configuration.adoc[] -** xref:manual/configuration.adoc#configuration-file[Configuration file] -** xref:manual/customconfig.adoc[] +* Backend Configuration +** xref:manual/configuration.adoc[Configuration file] +** xref:manual/appenders.adoc[] +** xref:manual/layouts.adoc[] +*** xref:manual/json-template-layout.adoc[] +** xref:manual/lookups.adoc[] +** xref:manual/customloglevels.adoc[] +** xref:manual/filters.adoc[] +** xref:manual/scripts.adoc[] ** xref:manual/systemproperties.adoc[] * xref:manual/usage.adoc[] * xref:manual/cloud.adoc[] -* xref:manual/lookups.adoc[] -* xref:manual/appenders.adoc[] -* xref:manual/layouts.adoc[] -** xref:manual/json-template-layout.adoc[] -* xref:manual/filters.adoc[] * xref:manual/async.adoc[] * xref:manual/garbagefree.adoc[] * xref:manual/extending.adoc[] +** xref::manual/customconfig.adoc[] * xref:manual/plugins.adoc[] -* xref:manual/customloglevels.adoc[] * xref:manual/jmx.adoc[] * xref:manual/logsep.adoc[] * xref:manual/performance.adoc[] diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index a3ed9b7899e..3c8cca26768 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -16,7 +16,6 @@ //// [id=configuration] = Configuration - Ralph Goers ; Piotr Karwasz Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. @@ -374,7 +373,7 @@ See <> for details. Scripts:: + -See <> for details. +See xref:manual/scripts.adoc[Scripts configuration] for details. [id=global-configuration-attributes] === Global configuration attributes @@ -904,7 +903,7 @@ Duplicate properties replace those in previous configurations. . xref:manual/filters.adoc[Filters] are aggregated under xref:manual/filters.adoc#CompositeFilter[CompositeFilter], if more than one filter is defined. -. <> are aggregated. +. xref:manual/scripts.adoc[] are aggregated. Duplicate definitions replace those in previous configurations. . xref:manual/appenders.adoc[Appenders] are aggregated. @@ -915,118 +914,6 @@ Logger attributes are individually merged with duplicates being replaced by thos Appender references on a logger are aggregated with duplicates being replaced by those in later configurations. The strategy merges filters on loggers using the rule above. -[id=scripts] -=== [[Scripts]] Scripts - -Log4j provides support for -https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR -223] scripting languages to be used in some of its components. - -[WARNING] -==== -In order to enable a scripting language, its name must be included in the -xref:manual/systemproperties.adoc#log4j2.scriptEnableLanguages[log4j2.scriptEnableLanguages] -configuration property. -==== - -Each component that allows scripts can contain on of the following configuration elements: - -Script:: -+ -This element specifies the content of the script directly and has: -+ --- -* a required `language` configuration attribute that specifies the name of the JSR 223 language to use, -* a required `scriptText` configuration attribute that contains the text of the script. -In the XML configuration format, the text of the script can also be written as content of the ` - \ No newline at end of file + diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml b/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml index de5252dcd76..a339d397eed 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml @@ -1,3 +1,19 @@ +# +# 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: Appenders: Console: diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml index 2a129061692..f3ef2af16f1 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml @@ -1,4 +1,20 @@ + @@ -6,4 +22,4 @@ - \ No newline at end of file + diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml index 408560cb9f0..cc2637345ac 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml @@ -1,4 +1,20 @@ + @@ -6,4 +22,4 @@ - \ No newline at end of file + diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml index 130b9ada716..7f8d7574b99 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml @@ -1,4 +1,20 @@ + - \ No newline at end of file + diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 3c8cca26768..996c91538a3 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -285,7 +285,7 @@ XML:: + [source,xml] ---- -include::example$configuration/main-elements.xml[] +include::example$configuration/main-elements.xml[lines=1;18..-1] ---- JSON:: @@ -299,14 +299,14 @@ YAML:: + [source,yaml] ---- -include::example$configuration/main-elements.yaml[] +include::example$configuration/main-elements.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/main-elements.properties[] +include::example$configuration/main-elements.properties[lines=17..-1] ---- ==== @@ -637,7 +637,7 @@ XML:: + [source,xml] ---- -include::example$configuration/properties.xml[tag=!empty] +include::example$configuration/properties.xml[lines=1;18..24;26] ---- JSON:: @@ -651,14 +651,14 @@ YAML:: + [source,yaml] ---- -include::example$configuration/properties.yaml[] +include::example$configuration/properties.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/properties.properties[] +include::example$configuration/properties.properties[lines=17..-1] ---- ==== @@ -810,7 +810,7 @@ XML:: + [source,xml] ---- -include::example$configuration/arbiters.xml[] +include::example$configuration/arbiters.xml[lines=1;18..-1] ---- JSON:: @@ -824,14 +824,14 @@ YAML:: + [source,yaml] ---- -include::example$configuration/arbiters.yaml[] +include::example$configuration/arbiters.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/arbiters.properties[] +include::example$configuration/arbiters.properties[lines=17..-1] ---- ==== @@ -850,7 +850,7 @@ XML:: + [source,xml] ---- -include::example$configuration/arbiters-select.xml[] +include::example$configuration/arbiters-select.xml[lines=1;18..-1] ---- JSON:: @@ -864,14 +864,14 @@ YAML:: + [source,yaml] ---- -include::example$configuration/arbiters-select.yaml[] +include::example$configuration/arbiters-select.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/arbiters-select.properties[] +include::example$configuration/arbiters-select.properties[lines=17..-1] ---- ==== @@ -964,19 +964,19 @@ Here is an example log4j2.xml file that includes two other files: .log4j2.xml [source,xml] ---- -include::example$configuration/xinclude-main.xml[] +include::example$configuration/xinclude-main.xml[lines=1;18..-1] ---- .xinclude-appenders.xml [source,xml] ---- -include::example$configuration/xinclude-appenders.xml[] +include::example$configuration/xinclude-appenders.xml[lines=1;18..-1] ---- .xinclude-loggers.xml [source,xml] ---- -include::example$configuration/xinclude-loggers.xml[] +include::example$configuration/xinclude-loggers.xml[lines=1;18..-1] ---- [id=java-properties-features] diff --git a/src/site/antora/modules/ROOT/pages/manual/filters.adoc b/src/site/antora/modules/ROOT/pages/manual/filters.adoc index 134da34fcdf..52c4bdfc36d 100644 --- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc @@ -40,7 +40,7 @@ XML:: + [source,xml] ---- -include::example$configuration/filters.xml[] +include::example$configuration/filters.xml[lines=1;18..-1] ---- JSON:: @@ -54,14 +54,14 @@ YAML:: + [source,yaml] ---- -include::example$configuration/filters.yaml[] +include::example$configuration/filters.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/filters.properties[] +include::example$configuration/filters.properties[lines=17..-1] ---- ==== <1> First the context-wide filter is consulted. diff --git a/src/site/antora/modules/ROOT/pages/manual/scripts.adoc b/src/site/antora/modules/ROOT/pages/manual/scripts.adoc index cacedad1f68..df835933db7 100644 --- a/src/site/antora/modules/ROOT/pages/manual/scripts.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/scripts.adoc @@ -80,7 +80,7 @@ XML:: + [source,xml] ---- -include::example$configuration/scripts.xml[] +include::example$configuration/scripts.xml[lines=1;18..-1] ---- JSON:: @@ -94,14 +94,14 @@ YAML:: + [source,yaml] ---- -include::example$configuration/scripts.yaml[] +include::example$configuration/scripts.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/scripts.properties[] +include::example$configuration/scripts.properties[lines=17..-1] ---- ==== From 5f8e0aeb524d3b7de5147817c9ba74f8802798f7 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 13 May 2024 11:19:29 +0200 Subject: [PATCH 08/24] Proofreading --- .../ROOT/pages/manual/configuration.adoc | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 996c91538a3..ae32f9198d9 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -16,6 +16,7 @@ //// [id=configuration] = Configuration + Ralph Goers ; Piotr Karwasz Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. @@ -264,7 +265,7 @@ See <> for details. + Appenders are the exit point of the logging pipeline. They decide to which resource (console, file, database, etc.) the log event is sent. -In the examples of this chapter we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender] in the examples. +In the examples of this chapter we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender]. + See xref:manual/appenders.adoc[Appender configuration] for details. @@ -273,7 +274,7 @@ Layouts:: Layouts tell appenders how they should format the log event: text, JSON, XML, etc. In the examples of this chapter we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] and -xref:manual/json-template-layout.adoc[JSON template layout] in the examples. +xref:manual/json-template-layout.adoc[JSON template layout]. + See xref:manual/layouts.adoc[Layout configuration] for details. @@ -318,6 +319,8 @@ The `CONSOLE` appender will only log messages less specific than `WARN`. <5> Configures a logger named `"org.example"` at level `DEBUG` and connects it to the `DEBUG_LOG` appender. The logger is configured to forward messages to its parent (the root appender). +Using the above configuration, the list of appenders that will be used for each log event depends only on the level of the event and the name of the logger, as in the table below: + [cols="2m,2m,5"] |=== | Logger name | Log event level | Appenders @@ -373,6 +376,8 @@ See <> for details. Scripts:: + +A container for JSR 223 scripts that can be used in other Log4j components. ++ See xref:manual/scripts.adoc[Scripts configuration] for details. [id=global-configuration-attributes] @@ -404,8 +409,10 @@ Unlike other logging backends Log4j Core is designed with **audit** logging in m During a reconfiguration process, no messages are lost. Unless the new configuration file removes an appender, the old one continues to work without interruption. -This behavior also implies that changes to appenders that modify the options of the resource used by the appender (e.g. a change in the `append` attribute of a file appender) will be **ignored**. -In order to modify these options during a reconfiguration you also need to change the resource used by the appender (e .g. the file name used by a file appender). + +Since some appender options (like the append mode used to open a file) can not be changed without closing the resource used by an appender, some attribute changes will be **ignored** during a reconfiguration. + +In order to modify these options during a reconfiguration you also need to change the resource used by the appender (e.g. the file name used by a file appender). ==== [id=configuration-attribute-status] @@ -421,7 +428,7 @@ In order to modify these options during a reconfiguration you also need to chang Overrides the logging level of the status logger. -WARNING: Since 2.24.0 this attribute is deprecated and will be replaced with the +WARNING: Since 2.24.0 this attribute is deprecated and should be replaced with the xref:manual/systemproperties.adoc#log4j2.statusLoggerLevel[log4j2.statusLoggerLevel] configuration property. @@ -443,7 +450,7 @@ See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apac + See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig-RootLogger[Plugin reference]. -`Logger`:: the most common logger kind, which collects log events from itself and all its children loggers, which do not have an explicit configuration (see xref:manual/architecture.adoc#logger-hierarchy[logger hierarchy]). +`Logger`:: the most common logger kind, which collects log events from itself and all the children loggers, which do not have an explicit configuration (see xref:manual/architecture.adoc#logger-hierarchy[logger hierarchy]). + See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggerConfig[Plugin Reference]. @@ -520,7 +527,7 @@ for more details. Specifies whether Log4j is allowed to compute location information. Computing the location information of a logging statement is an expensive operation (a couple of microseconds). -While Log4j makes every effort to only compute it if it was requested by a configured layout (cf. xref:manual/layouts.adoc[Layouts]), this setting provide a kill switch to disable it. +While Log4j makes every effort to only compute it if it was requested by a configured layout (cf. xref:manual/layouts.adoc[Layouts]), this setting provides a kill switch to disable it. [TIP] ==== @@ -617,8 +624,6 @@ Specifies the name of the appender to use. Specifies the level threshold that a log event must have to be logged. Log events more specific than this setting will be filtered out. -See also xref:manual/filters.adoc#filters[Filters] if you require additional filtering. - [id=appenderrefs-elements-filters] ==== Filters @@ -717,7 +722,7 @@ If both these conditions hold: -- + the value for the lookup is a substituted. -Otherwise, the expansion of `$\{name:-default}` is substituted. +Otherwise, the expansion of `${name:-default}` is substituted. [NOTE] ==== @@ -729,7 +734,7 @@ The same rule applies to the `name` parameter: if it contains a `${` sequence, t [id=lazy-property-substitution] ==== Lazy property substitution -While property substitution is performed once at **configuration time** for most attributes, there are two exceptions to this rule: +For most attributes property substitution is performed only once at **configuration time**, but there are two categories of exceptions to this rule: * Some attributes are **also** evaluated when a component specific event occurs. For example From cd8a61722ab5e6388788e25564ff382c2a2c3e52 Mon Sep 17 00:00:00 2001 From: Christian Grobmeier Date: Mon, 13 May 2024 22:58:45 +0200 Subject: [PATCH 09/24] grammar, typos, some rewording --- .../modules/ROOT/pages/manual/appenders.adoc | 440 +++++++++--------- 1 file changed, 223 insertions(+), 217 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index 07fca6666ee..a6464040b56 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -27,12 +27,12 @@ link:../javadoc/log4j-core/org/apache/logging/log4j/core/LifeCycle.html[`Lifecyc and link:../javadoc/log4j-core/org/apache/logging/log4j/core/filter/Filterable.html[`Filterable`] support. `Lifecycle` allows components to finish initialization after -configuration has completed and to perform cleanup during shutdown. -`Filterable` allows the component to have `Filter`s attached to it which are +configuration has been completed and to perform cleanup during shutdown. +`Filterable` allows the component to have `Filter` attached to it which are evaluated during event processing. Appenders usually are only responsible for writing the event data to the -target destination. In most cases they delegate responsibility for +target destination. In most cases, they delegate responsibility for formatting the event to a xref:manual/layouts.adoc[layout]. Some appenders wrap other appenders so that they can modify the `LogEvent`, handle a failure in an `Appender`, route the event to a subordinate `Appender` based on @@ -77,7 +77,7 @@ slots in the queue. If false, the event will be written to the error appender if the queue is full. The default is true. |shutdownTimeout |integer |How many milliseconds the Appender should -wait to flush outstanding log events in the queue on shutdown. The +wait to flush outstanding log events in the queue on shutdown? The default is zero which means to wait forever. |bufferSize |integer a| @@ -86,7 +86,7 @@ is 1024. Note that when using a disruptor-style `BlockingQueue`, this buffer size must be a power of 2. When the application is logging faster than the underlying appender can -keep up with for a long enough time to fill up the queue, the behaviour +keep up with for a long enough time to fill up the queue, the behavior is determined by the link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html[`AsyncQueueFullPolicy`]. @@ -123,7 +123,7 @@ system properties xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` and `log4j2.DiscardThreshold`]. -A typical AsyncAppender configuration might look like: +A typical AsyncAppender configuration might look like this: [source,xml] ---- @@ -190,7 +190,7 @@ https://jctools.github.io/JCTools/[JCTools], specifically the MPSC bounded lock-free queue. This implementation is provided by the `log4j-jctools` artifact. -|LinkedTransferQueue |This uses the new in Java 7 implementation +|LinkedTransferQueue |This uses the new Java 7 implementation https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedTransferQueue.html[`LinkedTransferQueue`]. Note that this queue does not use the `bufferSize` configuration attribute from AsyncAppender as `LinkedTransferQueue` does not support a @@ -294,7 +294,7 @@ TimestampGenerator. By default, this is `false`. | Whether or not to use TLS/SSL to connect to Cassandra. This is `false` by default. |=== -Here is an example CassandraAppender configuration: +Here is an example `CassandraAppender` configuration: [source,xml] ---- @@ -343,7 +343,7 @@ CREATE TABLE logs ( == [[ConsoleAppender]] ConsoleAppender As one might expect, the ConsoleAppender writes its output to either -System.out or System.err with System.out being the default target. A +`System.out` or `System.err` with `System.out` being the default target. A Layout must be provided to format the LogEvent. .ConsoleAppender Parameters @@ -358,14 +358,14 @@ CompositeFilter. is supplied the default pattern layout of "%m%n" will be used. |follow |boolean |Identifies whether the appender honors reassignments -of System.out or System.err via System.setOut or System.setErr made +of `System.out` or `System.err` via `System.setOut` or `System.setErr` made after configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with `direct`. |direct |boolean |Write directly to `java.io.FileDescriptor` and bypass `java.lang.System.out/.err`. Can give up to 10x performance boost when -the output is redirected to file or other process. Cannot be used with -Jansi on Windows. Cannot be used with `follow`. Output will not respect +the output is redirected to a file or other process. Cannot be used with +Jansi on Windows. Cannot be used with `follow`. The output will not respect `java.lang.System.setOut()/.setErr()` and may get intertwined with other output to `java.lang.System.out/.err` in a multi-threaded application. _New since 2.6.2. Be aware that this is a new addition, and it has only @@ -470,11 +470,11 @@ A Failover configuration might look like: == [[FileAppender]] FileAppender The FileAppender is an OutputStreamAppender that writes to the File -named in the fileName parameter. The FileAppender uses a FileManager -(which extends OutputStreamManager) to actually perform the file I/O. +defined in the `fileName` parameter. The FileAppender uses a FileManager +(which extends OutputStreamManager) to perform the file I/O. While FileAppenders from different Configurations cannot be shared, the FileManagers can be if the Manager is accessible. For example, two web -applications in a servlet container can have their own configuration and +applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. @@ -489,11 +489,11 @@ new records are written. |bufferedIO |boolean |When true - the default, records will be written to a buffer and the data will be written to disk when the buffer is full or, if immediateFlush is set, when the record is written. File locking -cannot be used with bufferedIO. Performance tests have shown that using -buffered I/O significantly improves performance, even if immediateFlush +cannot be used with `bufferedIO`. Performance tests have shown that using +buffered I/O significantly improves performance, even if `immediateFlush` is enabled. -|bufferSize |int |When bufferedIO is true, this is the buffer size, the +|bufferSize |int |When `bufferedIO` is true, this is the buffer size, the default is 8192 bytes. |createOnDemand |boolean |The appender creates the file on-demand. The @@ -510,7 +510,7 @@ of its parent directories, do not exist, they will be created. |immediateFlush |boolean a| When set to true - the default, each write will be followed by a flush. This will guarantee that the data is passed to the operating system for writing; -it does not guarantee that the data is actually written to a physical device +it does not guarantee that the data is written to a physical device such as a disk drive. Note that if this flag is set to false, and the logging activity is sparse, @@ -532,7 +532,7 @@ is supplied the default pattern layout of "%m%n" will be used. while the file lock is held allowing FileAppenders in multiple JVMs and potentially multiple hosts to write to the same file simultaneously. This will significantly impact performance so should be used carefully. -Furthermore, on many systems the file lock is "advisory" meaning that +Furthermore, on many systems, the file lock is "advisory" meaning that other applications can perform operations on the file without acquiring a lock. The default value is false. @@ -548,7 +548,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. File attribute permissions in POSIX format to apply whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -557,21 +557,21 @@ Examples: `rw-------` or `rw-rw-rw-` etc... |fileOwner |String a| File owner to define whenever the file is created. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying files system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -635,13 +635,13 @@ used. be sent. If more than one agent is specified the first Agent will be the primary and subsequent Agents will be used in the order specified as secondaries should the primary Agent fail. Each Agent definition -supplies the Agents host and port. The specification of agents and +supplies the Agent's host and port. The specification of agents and properties are mutually exclusive. If both are configured an error will result. |agentRetries |integer |The number of times the agent should be retried before failing to a secondary. This parameter is ignored when -type="persistent" is specified (agents are tried once before failing to +`type="persistent"` is specified (agents are tried once before failing to the next). |batchSize |integer |Specifies the number of events that should be sent @@ -654,7 +654,7 @@ using gzip |connectTimeoutMillis |integer |The number of milliseconds Flume will wait before timing out the connection. -|dataDir |String |Directory where the Flume write ahead log should be +|dataDir |String |Directory where the Flume write-ahead log should be written. Valid only when embedded is set to true and Agent elements are used instead of Property elements. @@ -663,7 +663,7 @@ this Appender. More than one Filter may be used by using a CompositeFilter. |eventPrefix |String |The character string to prepend to each event -attribute in order to distinguish it from MDC attributes. The default is +attribute to distinguish it from MDC attributes. The default is an empty string. |flumeEventFactory |FlumeEventFactory |Factory that generates the Flume @@ -680,21 +680,20 @@ is 5. |maxDelayMillis |integer |The maximum number of milliseconds to wait for batchSize events before publishing the batch. -|mdcExcludes |String |A comma separated list of mdc keys that should be +|mdcExcludes |String |A comma-separated list of mdc keys that should be excluded from the FlumeEvent. This is mutually exclusive with the mdcIncludes attribute. -|mdcIncludes |String |A comma separated list of mdc keys that should be +|mdcIncludes |String |A comma-separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes attribute. -|mdcRequired |String |A comma separated list of mdc keys that must be +|mdcRequired |String |A comma-separated list of `mdc` keys that must be present in the MDC. If a key is not present a LoggingException will be thrown. -|mdcPrefix |String |A string that should be prepended to each MDC key in -order to distinguish it from event attributes. The default string is +|mdcPrefix |String |A string that should be prepended to each MDC key to distinguish it from event attributes. The default string is "mdc:". |name |String |The name of the Appender. @@ -710,7 +709,7 @@ result in an error. When used to configure in Persistent mode the valid properties are: -1. "keyProvider" to specify the name of the plugin to provide the +1. `keyProvider` to specify the name of the plugin to provide the secret key for encryption. |requestTimeoutMillis |integer |The number of milliseconds Flume will @@ -727,7 +726,7 @@ indicate which variation of the Appender is desired. |======================================================================= A sample FlumeAppender configuration that is configured with a primary -and a secondary agent, compresses the body, and formats the body using +and a secondary agent compresses the body and formats the body using the RFC5424Layout: [source,xml] @@ -750,7 +749,7 @@ the RFC5424Layout: ---- A sample FlumeAppender configuration that is configured with a primary -and a secondary agent, compresses the body, formats the body using the +and a secondary agent compresses the body, formats the body using the RFC5424Layout, and persists encrypted events to disk: [source,xml] @@ -774,7 +773,7 @@ RFC5424Layout, and persists encrypted events to disk: ---- A sample FlumeAppender configuration that is configured with a primary -and a secondary agent, compresses the body, formats the body using +and a secondary agent compresses the body, and formats the body using RFC5424Layout and passes the events to an embedded Flume Agent. [source,xml] @@ -803,7 +802,7 @@ RFC5424Layout and passes the events to an embedded Flume Agent. ---- A sample FlumeAppender configuration that is configured with a primary -and a secondary agent using Flume configuration properties, compresses +and a secondary agent using Flume configuration properties compresses the body, formats the body using RFC5424Layout and passes the events to an embedded Flume Agent. @@ -875,7 +874,7 @@ conversion to allow for more data types. To get off the ground quickly during development, an alternative to using a connection source based on JNDI is to use the non-pooling `DriverManager` connection source. This connection source uses a JDBC -connection string, a user name, and a password. Optionally, you can also +connection string, a username, and a password. Optionally, you can also use properties. .JDBCAppender Parameters @@ -894,10 +893,10 @@ Appender in a link:#FailoverAppender[FailoverAppender]. this Appender. More than one Filter may be used by using a CompositeFilter. -|bufferSize |int |If an integer greater than 0, this causes the appender +|bufferSize |int |If an integer is greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. -|connectionSource |ConnectionSource |_Required._ The connections source +|connectionSource |ConnectionSource |_Required._ The connection source from which database connections should be retrieved. |tableName |String |_Required._ The name of the database table to insert @@ -905,7 +904,7 @@ log events into. |columnConfigs |ColumnConfig[] |_Required (and/or columnMappings)._ Information about the columns that log event data should be inserted -into and how to insert that data. This is represented with multiple +into and how to insert that data. This is represented by multiple `` elements. |columnMappings |ColumnMapping[] |_Required (and/or columnConfigs)._ A @@ -991,16 +990,16 @@ be backed by a connection pool for the same reasons. connection string. |userName |String |The database user name. You cannot specify both -properties and a user name or password. +properties and a username or password. |password |String |The database password. You cannot specify both -properties and a user name or password. +properties and a username or password. |driverClassName |String |The JDBC driver class name. Some old JDBC -Driver can only be discovered by explicitly loading them by class name. +driver can only be discovered by explicitly loading them by class name. |properties |Property[] |A list of properties. You cannot specify both -properties and a user name or password. +properties and a username or password. |======================================================================= [#JDBCPoolingDriver] @@ -1009,7 +1008,7 @@ properties and a user name or password. |======================================================================= |Parameter Name |Type |Description |DriverManager parameters |DriverManager parameters |This connection -source inherits all parameter from the DriverManager connection source. +source inherits all parameters from the DriverManager connection source. |poolName |String |The pool name used to pool JDBC Connections. Defaults to `example`. You can use the JDBC connection string prefix @@ -1083,7 +1082,7 @@ your value should contain single quotes around it like this: You can only specify one of `literal` or `parameter`. |isEventTimestamp |boolean |Use this attribute to insert the event -timestamp in this column, which should be a SQL datetime. The value will +timestamp in this column, which should be a SQL `datetime`. The value will be inserted as a `java.sql.Types.TIMESTAMP`. Either this attribute (equal to `true`), `pattern`, or `isEventTimestamp` must be specified, but not more than one of these. @@ -1091,7 +1090,7 @@ but not more than one of these. |isUnicode |boolean |This attribute is ignored unless `pattern` is specified. If `true` or omitted (default), the value will be inserted as unicode (`setNString` or `setNClob`). Otherwise, the value will be -inserted non-unicode (`setString` or `setClob`). +inserted non-Unicode (`setString` or `setClob`). |isClob |boolean |This attribute is ignored unless `pattern` is specified. Use this attribute to indicate that the column stores @@ -1126,10 +1125,10 @@ these. |layout |Layout |The Layout to format the LogEvent. -|type |String |Conversion type name, a fully-qualified class name. +|type |String |Conversion type name, a fully qualified class name. |======================================================================= -Here are a couple sample configurations for the JDBCAppender, as well as +Here are a couple of sample configurations for the JDBCAppender, as well as a sample factory implementation that uses Commons Pooling and Commons DBCP to pool database connections: @@ -1226,10 +1225,10 @@ public class ConnectionFactory { This appender is xref:manual/messages.adoc#MapMessage[`MapMessage`]-aware. The following configuration uses no layout to indicate that the -Appender should match the keys of a `MapMessage` to the names of +appender should match the keys of a `MapMessage` to the names of `ColumnMapping`s when setting the values of the Appender's SQL INSERT -statement. This let you insert rows for custom values in a database -table based on a Log4j `MapMessage` instead of values from `LogEvent`s. +statement. This lets you insert rows for custom values in a database +table based on a Log4j `MapMessage` instead of values from `LogEvent`. [source,xml] ---- @@ -1266,7 +1265,7 @@ The JMS Appender sends the formatted log event to a JMS Destination. The JMS Appender requires JNDI support so as of release 2.17.0, this appender will not function unless `log4j2.enableJndiJms=true` is configured as a system property or environment variable. See the https://logging.apache.org/log4j/2.x/manual/configuration.html#enableJndiJms[enableJndiJms] system property. -Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics. However, configurations written for 2.0 which use the `` or `` elements will continue to work with the new `` configuration element. +Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics. However, configurations written for 2.0 that use the `` or `` elements will continue to work with the new `` configuration element. .JMS Appender Parameters [cols="1,1,1,3", options="header"] @@ -1281,7 +1280,7 @@ Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JM | factoryName | String | _Required_ -| The fully qualified class name that should be used to define the Initial Context Factory as defined in https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[INITIAL_CONTEXT_FACTORY]. If a factoryName is specified without a providerURL, a warning message will be logged as this is likely to cause problems. +| The fully qualified class name that should be used to define the Initial Context Factory as defined in https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[INITIAL_CONTEXT_FACTORY]. If a `factoryName` is specified without a `providerURL`, a warning message will be logged as this is likely to cause problems. | filter | Filter @@ -1316,7 +1315,7 @@ Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JM | securityPrincipalName | String | null -| The name of the identity of the Principal as specified by https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[SECURITY_PRINCIPAL]. If a securityPrincipalName is specified without securityCredentials, a warning message will be logged as this is likely to cause problems. +| The name of the identity of the Principal as specified by https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[SECURITY_PRINCIPAL]. If a securityPrincipalName is specified without `securityCredentials`, a warning message will be logged as this is likely to cause problems. | securityCredentials | String @@ -1346,7 +1345,7 @@ Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JM | userName | String | null -| The user id used to create the JMS connection. +| The user ID used to create the JMS connection. |=== Here is a sample JMS Appender configuration: @@ -1395,7 +1394,14 @@ layout of the appender to `MessageLayout` with `<MessageLayout />` (Since As of Log4j 2.11.0, JPA support has moved from the existing module `log4j-core` to the new module `log4j-jpa`. -The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1. It requires the API and a provider implementation be on the classpath. It also requires a decorated entity configured to persist to the table desired. The entity should either extend `org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity` (if you mostly want to use the default mappings) and provide at least an `@Id` property, or `org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity` (if you want to significantly customize the mappings). See the Javadoc for these two classes for more information. You can also consult the source code of these two classes as an example of how to implement the entity. +The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1. +It requires the API and a provider implementation to be on the classpath. +It also requires a decorated entity configured to persist to the table desired. + +If you want to use the default mappings, you can extend `org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity` and provide an `@Id` property. +If you want to significantly customize the mappings, you can extend `org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity`. + +See the Javadoc or source code for these two classes for more information and examples. [width="100%",options="header"] |=== @@ -1415,7 +1421,7 @@ The JPAAppender writes log events to a relational database table using the Java |bufferSize |int -|If an integer greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. +|If an integer is greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. |entityClassName |String @@ -1426,7 +1432,9 @@ The JPAAppender writes log events to a relational database table using the Java |_Required._ The name of the JPA persistence unit that should be used for persisting log events. |=== -Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j configuration file, the second is the `persistence.xml` file. EclipseLink is assumed here, but any JPA 2.1 or higher provider will do. You should _always_ create a _separate_ persistence unit for logging, for two reasons. First, `` _must_ be set to "NONE," which is usually not desired in normal JPA usage. Also, for performance reasons the logging entity should be isolated in its own persistence unit away from all other entities and you should use a non-JTA data source. Note that your persistence unit _must_ also contain `` elements for all of the `org.apache.logging.log4j.core.appender.db.jpa.converter` converter classes. +Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j configuration file, the second is the `persistence.xml` file. EclipseLink is assumed here, but any JPA 2.1 or higher provider will do. You should _always_ create a _separate_ persistence unit for logging, for two reasons. First, `` _must_ be set to "NONE," which is usually not desired in normal JPA usage. +Also, for performance reasons the logging entity should be isolated in its persistence unit away from all other entities and you should use a non-JTA data source. +Note that your persistence unit _must_ also contain `` elements for all of the `org.apache.logging.log4j.core.appender.db.jpa.converter` converter classes. [source,xml] ---- @@ -1561,10 +1569,10 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity { The HttpAppender sends log events over HTTP. A Layout must be provided to format the LogEvent. -Will set the `Content-Type` header according to the layout. Additional +It will set the `Content-Type` header according to the layout. Additional headers can be specified with embedded Property elements. -Will wait for response from server, and throw error if no 2xx response +It will also wait for a response from the server, and throw an error if no 2xx response is received. Implemented with @@ -1665,7 +1673,7 @@ The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topi |syncSend |boolean -|The default is `true`, causing sends to block until the record has been acknowledged by the Kafka server. When set to `false`, sends return immediately, allowing for lower latency and significantly higher throughput. _New since 2.8. Be aware that this is a new addition, and it has not been extensively tested. Any failure sending to Kafka will be reported as error to StatusLogger and the log event will be dropped (the ignoreExceptions parameter will not be effective). Log events may arrive out of order to the Kafka server._ +|The default is `true`, causing sends to block until the record has been acknowledged by the Kafka server. When set to `false`, sends a return immediately, allowing for lower latency and significantly higher throughput. _New since 2.8. Be aware that this is a new addition, and it has not been extensively tested. Any failure sending to Kafka will be reported as an error to StatusLogger and the log event will be dropped (the ignoreExceptions parameter will not be effective). Log events may arrive out of order on the Kafka server._ |properties |Property[] @@ -1721,11 +1729,11 @@ record as the other file appenders._ The MemoryMappedFileAppender maps a part of the specified file into memory and writes log events to this memory, relying on the operating system's virtual memory manager to synchronize the changes to the -storage device. The main benefit of using memory mapped files is I/O +storage device. The main benefit of using memory-mapped files is I/O performance. Instead of making system calls to write to disk, this appender can simply change the program's local memory, which is orders of magnitude faster. Also, in most operating systems the memory region -mapped actually is the kernel's +mapped is the kernel's http://en.wikipedia.org/wiki/Page_cache[page cache] (file cache), meaning that no copies need to be created in user space. @@ -1738,15 +1746,14 @@ especially very large regions (half a gigabyte or more). The default region size is 32 MB, which should strike a reasonable balance between the frequency and the duration of remap operations. -// (TODO: performance -// test remapping various sizes.) +// (TODO: performance test remapping various sizes.) Similar to the FileAppender and the RandomAccessFileAppender, MemoryMappedFileAppender uses a MemoryMappedFileManager to actually perform the file I/O. While MemoryMappedFileAppender from different Configurations cannot be shared, the MemoryMappedFileManagers can be if -the Manager is accessible. For example, two web applications in a -servlet container can have their own configuration and safely write to +the manager is accessible. For example, two web applications in a +servlet container can have its own configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. @@ -1775,7 +1782,7 @@ written to the storage device even if the Java process crashes, but there may be data loss if the operating system crashes. Note that manually forcing a sync on every log event loses most of the -performance benefits of using a memory mapped file. +performance benefits of using a memory-mapped file. Flushing after every write is only useful when using this appender with synchronous loggers. Asynchronous loggers and appenders will @@ -1846,7 +1853,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. this Appender. More than one Filter may be used by using a CompositeFilter. -|bufferSize |int |If an integer greater than 0, this causes the appender +|bufferSize |int |If an integer is greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size. |NoSqlProvider |NoSQLProvider` element. The only type currently -supported is ``. To create your own custom +supported is ``. To create your custom provider, read the JavaDoc for the `NoSQLProvider`, `NoSQLConnection`, and `NoSQLObject` classes and the documentation about creating Log4j -plugins. We recommend you review the source code for the MongoDB -providers as a guide for creating your own provider. +plugins. +We recommend you review the source code for the MongoDB +providers as a guide for creating your provider. The following example demonstrates how log events are persisted in NoSQL databases if represented in a JSON format: @@ -2126,7 +2134,7 @@ This section details specializations of the link:#NoSQLAppender[NoSQLAppender] p |factoryClassName |Class -|To provide a connection to the CouchDB database, you can use this attribute and `factoryMethodName` to specify a class and static method to get the connection from. The method must return a `org.lightcouch.CouchDbClient` or a `org.lightcouch.CouchDbProperties`. If you use the factory method for providing a connection, you must not specify the `databaseName`, `protocol`, `server`, `port`, `username`, or `password` attributes. +|To provide a connection to the CouchDB database, you can use this attribute and `factoryMethodName` to specify a class and static method to retrieve the connection. The method must return an `org.lightcouch.CouchDbClient` or a `org.lightcouch.CouchDbProperties`. If you use the factory method for providing a connection, you must not specify the `databaseName`, `protocol`, `server`, `port`, `username`, or `password` attributes. |factoryMethodName |Method @@ -2134,7 +2142,7 @@ This section details specializations of the link:#NoSQLAppender[NoSQLAppender] p |databaseName |String -|If you do not specify a `factoryClassName` and `factoryMethodName` for providing a CouchDB connection, you must specify a CouchDB database name using this attribute. You must also specify a `username` and `password`. You can optionally also specify a `protocol` (defaults to http), `server` (defaults to localhost), and a `port` (defaults to 80 for http and 443 for https). +|If you do not specify a `factoryClassName` and `factoryMethodName` for providing a CouchDB connection, you must specify a CouchDB database name using this attribute. You must also specify a `username` and `password`. You can optionally also specify a `protocol` (defaults to `http`), `server` (defaults to localhost), and a `port` (defaults to 80 for `http` and 443 for `https`). |protocol |String @@ -2200,10 +2208,10 @@ saw a 20-200% performance improvement compared to FileAppender with "bufferedIO=true" in our xref:manual/performance.adoc#whichAppender[measurements]. Similar to the FileAppender, RandomAccessFileAppender uses a RandomAccessFileManager to -actually perform the file I/O. While RandomAccessFileAppender from +perform the file I/O. While RandomAccessFileAppender from different Configurations cannot be shared, the RandomAccessFileManagers can be if the Manager is accessible. For example, two web applications -in a servlet container can have their own configuration and safely write +in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. @@ -2225,7 +2233,7 @@ CompositeFilter. |immediateFlush |boolean a| When set to true - the default, each write will be followed by a flush. This will guarantee that the data is passed to the operating system for writing; -it does not guarantee that the data is actually written to a physical device +it does not guarantee that the data is written to a physical device such as a disk drive. Note that if this flag is set to false, and the logging activity is sparse, @@ -2279,7 +2287,7 @@ Here is a sample RandomAccessFile configuration: [#RewriteAppender] == RewriteAppender -The RewriteAppender allows the LogEvent to manipulated before it is +The RewriteAppender allows the LogEvent to be manipulated before it is processed by another Appender. This can be used to mask sensitive information such as passwords or to inject information into each event. The RewriteAppender must be configured with a RewritePolicy. The @@ -2401,10 +2409,10 @@ product key and its value to the MapMessage: ==== LoggerNameLevelRewritePolicy -You can use this policy to make loggers in third party code less chatty +You can use this policy to make loggers in third-party code less chatty by changing event levels. The LoggerNameLevelRewritePolicy will rewrite log event levels for a given logger name prefix. You configure a -LoggerNameLevelRewritePolicy with a logger name prefix and a pairs of +LoggerNameLevelRewritePolicy with a logger name prefix and a pair of levels, where a pair defines a source level and a target level. [cols="20%,20%,60%",options="header",] @@ -2449,22 +2457,22 @@ with `com.foo.bar`. == [[RollingFileAppender]] RollingFileAppender The RollingFileAppender is an OutputStreamAppender that writes to the -File named in the fileName parameter and rolls the file over according -the TriggeringPolicy and the RolloverPolicy. The RollingFileAppender -uses a RollingFileManager (which extends OutputStreamManager) to -actually perform the file I/O and perform the rollover. While -RolloverFileAppenders from different Configurations cannot be shared, -the RollingFileManagers can be if the Manager is accessible. For -example, two web applications in a servlet container can have their own +file named in the fileName parameter and rolls the file over according to +the `TriggeringPolicy` and the `RolloverPolicy`. The `RollingFileAppender` +uses a `RollingFileManager` (which extends `OutputStreamManager`) to +perform the file I/O and perform the rollover. +While `RolloverFileAppenders` from different Configurations cannot be shared, +the `RollingFileManagers` can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a -ClassLoader that is common to both of them. +`ClassLoader` that is common to both of them. A RollingFileAppender requires a link:#TriggeringPolicies[TriggeringPolicy] and a link:#RolloverStrategies[RolloverStrategy]. The triggering policy -determines if a rollover should be performed while the RolloverStrategy -defines how the rollover should be done. If no RolloverStrategy is -configured, RollingFileAppender will use the +determines if a rollover should be performed while the `RolloverStrategy` +defines how the rollover should be done. If no `RolloverStrategy` is +configured, `RollingFileAppender` will use the link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. Since log4j-2.5, a link:#CustomDeleteOnRollover[custom delete action] can be configured in the DefaultRolloverStrategy to run at rollover. Since 2.8 if no file @@ -2473,7 +2481,7 @@ link:#DirectWriteRolloverStrategy[DirectWriteRolloverStrategy] will be used instead of DefaultRolloverStrategy. Since log4j-2.9, a link:#CustomPosixViewAttributeOnRollover[custom POSIX file attribute view action] can be configured in the DefaultRolloverStrategy to run at -rollover, if not defined, inherited POSIX file attribute view from the +rollover, if not defined, the inherited POSIX file attribute view from the RollingFileAppender will be applied. File locking is not supported by the RollingFileAppender. @@ -2508,7 +2516,7 @@ CompositeFilter. 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 +file. The format of the pattern is dependent on the `RolloverPolicy` that is used. The DefaultRolloverPolicy will accept both a date/time pattern compatible with https://download.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html[`SimpleDateFormat`] @@ -2523,7 +2531,7 @@ pattern. |immediateFlush |boolean a| When set to true - the default, each write will be followed by a flush. This will guarantee that the data is passed to the operating system for writing; -it does not guarantee that the data is actually written to a physical device +it does not guarantee that the data is written to a physical device such as a disk drive. Note that if this flag is set to false, and the logging activity is sparse, @@ -2547,7 +2555,7 @@ is supplied the default pattern layout of "%m%n" will be used. should occur. |strategy |RolloverStrategy |The strategy to use to determine the name -and location of the archive file. +and the location of the archive file. |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -2559,7 +2567,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. File attribute permissions in POSIX format to apply whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -2568,21 +2576,21 @@ Examples: rw------- or rw-rw-rw- etc... |fileOwner |String a| File owner to define whenever the file is created. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying files system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -2599,8 +2607,8 @@ and returns true if any of the configured policies return true. The policies in a `Policies` element. For example, the following XML fragment defines policies that rollover -the log when the JVM starts, when the log size reaches twenty megabytes, -and when the current date no longer matches the log’s start date. +the log when the JVM starts when the log size reaches twenty megabytes, +and when the current date no longer matches the log's start date. [source,xml] ---- @@ -2614,9 +2622,9 @@ and when the current date no longer matches the log’s start date. === Cron Triggering Policy The `CronTriggeringPolicy` triggers rollover based on a cron expression. This policy -is controlled by a timer and is asynchronous to processing log events, so it is possible that log events -from the previous or next time period may appear at the beginning or end of the log file. -The filePattern attribute of the Appender should contain a timestamp otherwise the target file will be +is controlled by a timer and is asynchronous in processing log events, so it is possible that log events +from the previous or next period may appear at the beginning or end of the log file. +The `filePattern` attribute of the Appender should contain a timestamp otherwise the target file will be overwritten on each rollover. .CronTriggeringPolicy Parameters @@ -2645,7 +2653,7 @@ met or exceeded. |======================================================================= |Parameter Name |Type |Description |minSize |long |The minimum size the file must have to roll over. A size -of zero will cause a roll over no matter what the file size is. The +of zero will cause a rollover no matter what the file size is. The default value is 1, which will prevent rolling over an empty file. |======================================================================= @@ -2661,12 +2669,11 @@ and falls back to Log4J initialization time instead.) The `SizeBasedTriggeringPolicy` causes a rollover once the file has reached the specified size. The size can be specified in bytes, with the suffix KB, MB, GB, or TB for example `20MB`. -size.The size may also contain a fractional value such as `1.5 MB`. The size is evaluated +size. The size may also contain a fractional value such as `1.5 MB`. The size is evaluated using the Java root Locale so a period must always be used for the fractional unit. -When combined with a time based triggering policy the file pattern must contain a `%i` -otherwise the target file will be overwritten on every rollover as the SizeBased Triggering Policy -will not cause the timestamp value in the file name to change. When used without a time based -triggering policy the SizeBased Triggering Policy will cause the timestamp value to change. +When combined with a time-based triggering policy the file pattern must contain a `%i`. +Otherwise, the target file will be overwritten on every rollover as the SizeBased Triggering Policy will not cause the timestamp value in the file name to change. +When used without a time-based triggering policy the SizeBased Triggering Policy will cause the timestamp value to change. === TimeBased Triggering Policy @@ -2681,19 +2688,19 @@ occur based on the time pattern and a `modulate` boolean attribute. |Parameter Name |Type |Description |interval |integer |How often a rollover should occur based on the most specific time unit in the date pattern. For example, with a date pattern -with hours as the most specific item and and increment of 4 rollovers +with hours as the most specific item, an increment of 4 rollovers would occur every 4 hours. The default value is 1. |modulate |boolean |Indicates whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. For example, if the item is hours, the current hour is 3 am and the interval is 4 -then the first rollover will occur at 4 am and then next ones will occur -at 8 am, noon, 4pm, etc. The default value is false. +then the first rollover will occur at 4 am and then the next ones will occur +at 8 am, noon, 4 pm, etc. The default value is false. |maxRandomDelay |integer |Indicates the maximum number of seconds to randomly delay a rollover. By default, this is 0 which indicates no delay. This setting is useful on servers where multiple applications are -configured to rollover log files at the same time and can spread the +configured to roll over logfiles at the same time and can spread the load of doing so across time. |======================================================================= @@ -2706,7 +2713,7 @@ load of doing so across time. Default Rollover Strategy The default rollover strategy accepts both a date/time pattern and an -integer from the filePattern attribute specified on the +integer from the `filePattern` attribute specified on the RollingFileAppender itself. If the date/time pattern is present it will be replaced with the current date and time values. If the pattern contains an integer it will be incremented on each rollover. If the @@ -2719,7 +2726,7 @@ Pack200 and XZ require http://commons.apache.org/proper/commons-compress/[Apache Commons Compress]. In addition, XZ requires http://tukaani.org/xz/java.html[XZ for Java]. The pattern may also contain lookup references that can be -resolved at runtime such as is shown in the example below. +resolved at runtime such as shown in the example below. The default rollover strategy supports three variations for incrementing the counter. To illustrate how it works, suppose that the min attribute @@ -2749,7 +2756,7 @@ foo-1.log, foo-3.log is renamed to foo-2.log and foo.log is renamed to foo-3.log. A new foo.log file is created and starts being written to. |======================================================================= -By way of contrast, when the fileIndex attribute is set to "min" but all +By way of contrast, when the `fileIndex` attribute is set to "min" all the other settings are the same the "fixed window" strategy will be performed. @@ -2777,7 +2784,7 @@ foo-3.log, foo-1.log is renamed to foo-2.log and foo.log is renamed to foo-1.log. A new foo.log file is created and starts being written to. |======================================================================= -Finally, as of release 2.8, if the fileIndex attribute is set to "nomax" +Finally, as of release 2.8, if the `fileIndex` attribute is set to `nomax` then the min and max values will be ignored and file numbering will increment by 1 and each rollover will have an incrementally higher value with no maximum number of files. @@ -2793,7 +2800,7 @@ described above. |min |integer |The minimum value of the counter. The default value is 1. -|max |integer |The maximum value of the counter. Once this values is +|max |integer |The maximum value of the counter. Once this value is reached older archives will be deleted on subsequent rollovers. The default value is 7. @@ -2813,7 +2820,7 @@ DirectWrite Rollover Strategy The DirectWriteRolloverStrategy causes log events to be written directly to files represented by the file pattern. With this strategy file renames are not performed. If the size-based triggering policy causes -multiple files to be written during the specified time period they will +multiple files to be written during the specified period they will be numbered starting at one and continually incremented until a time-based rollover occurs. @@ -2827,8 +2834,8 @@ startup either. [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|maxFiles |String |The maximum number of files to allow in the time -period matching the file pattern. If the number of files is exceeded the +|maxFiles |String |The maximum number of files to allow in the period matching +the file pattern. If the number of files is exceeded the oldest file will be deleted. If specified, the value must be greater than 1. If the value is less than zero or omitted then the number of files will not be limited. @@ -2842,7 +2849,7 @@ archived log file during compression. |======================================================================= Below is a sample configuration that uses a RollingFileAppender with -both the time and size based triggering policies, will create up to 7 +both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip: @@ -2899,7 +2906,7 @@ files before removing them. ---- Below is a sample configuration that uses a RollingFileAppender with -both the time and size based triggering policies, will create up to 7 +both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every 6 hours when the hour is divisible by 6: @@ -2929,7 +2936,7 @@ and will roll every 6 hours when the hour is divisible by 6: ---- This sample configuration uses a RollingFileAppender with both the cron -and size based triggering policies, and writes directly to an unlimited +and size-based triggering policies, and writes directly to an unlimited number of archive files. The cron trigger causes a rollover every hour while the file size is limited to 250MB: @@ -2956,7 +2963,7 @@ while the file size is limited to 250MB: ---- -This sample configuration is the same as the previous but limits the +This sample configuration is the same as the previous one but limits the number of files saved each hour to 10: [source,xml] @@ -2994,7 +3001,7 @@ the DefaultRolloverStrategy `max` attribute. The Delete action lets users configure one or more conditions that select the files to delete relative to a base directory. -Note that it is possible to delete any file, not just rolled over log +Note that it is possible to delete any file, not just rolled-over log files, so use this action with care! With the `testMode` parameter you can test your configuration without accidentally deleting the wrong files. @@ -3008,7 +3015,7 @@ for files to delete. |maxDepth |int |The maximum number of levels of directories to visit. A value of 0 means that only the starting file (the base path itself) is -visited, unless denied by the security manager. A value of +visited unless denied by the security manager. A value of Integer.MAX_VALUE indicates that all levels should be visited. The default is 1, meaning only the files in the specified base directory. @@ -3018,12 +3025,12 @@ false. |testMode |boolean |If true, files are not deleted but instead a message is printed to the xref:manual/configuration.adoc#StatusMessages[status logger] at INFO level. Use this to do a dry run to test if the configuration -works as expected. Default is false. +works as expected. The default is false. |pathSorter |PathSorter |A plugin implementing the link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.html[PathSorter] interface to sort the files before selecting the files to delete. The -default is to sort most recently modified files first. +default is to sort the most recently modified files first. |pathConditions [[DeletePathCondition]] |PathCondition[] a| _Required if no ScriptCondition is specified._ One or more PathCondition @@ -3054,7 +3061,7 @@ paths after the accumulated file size threshold is exceeded during the file tree walk. * IfAll - accepts a path if all nested conditions accept it (logical AND). Nested conditions may be evaluated in any order. -* IfAny - accepts a path if one of the nested conditions accept it +* IfAny - accepts a path if one of the nested conditions accepts it (logical OR). Nested conditions may be evaluated in any order. * IfNot - accepts a path if the nested condition does not accept it (logical NOT). @@ -3069,7 +3076,7 @@ executed. (See also the xref:manual/filters.adoc#Script[ScriptFilter] documentation for more examples of configuring ScriptFiles and ScriptRefs.) -The script is passed a number of link:#ScriptParameters[parameters], +The script is passed several link:#ScriptParameters[parameters], including a list of paths found under the base path (up to `maxDepth`) and must return a list with the paths to delete. @@ -3082,7 +3089,7 @@ and must return a list with the paths to delete. [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|glob |String |_Required if regex not specified._ Matches the relative +|glob |String |_Required if regex is not specified._ Matches the relative path (relative to the base path) using a limited pattern language that resembles regular expressions but with a https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)[simpler @@ -3190,7 +3197,7 @@ and are 60 days old or older are deleted at rollover time. ---- Below is a sample configuration that uses a RollingFileAppender with -both the time and size based triggering policies, will create up to 100 +both the time and size-based triggering policies will create up to 100 archives on the same day (1-100) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every hour. During every rollover, this configuration will @@ -3247,7 +3254,7 @@ comes first. |======================================================================= |Parameter Name |Type |Description |script |Script, ScriptFile or ScriptRef |The Script element that -specifies the logic to be executed. The script is passed a list of paths +specifies the logic to be executed. The script passes a list of paths found under the base path and must return the paths to delete as a `java.util.List`. See also the xref:manual/filters.adoc#Script[ScriptFilter] documentation for an example of @@ -3263,7 +3270,7 @@ how ScriptFiles and ScriptRefs can be configured. |Parameter Name |Type |Description |basePath |`java.nio.file.Path` |The directory from where the Delete action started scanning for files to delete. Can be used to relativize -the paths in the pathList. +the paths in the `pathList`. |pathList |`java.util.List` |The list of paths found under the base path up to the specified max depth, sorted most recently @@ -3284,7 +3291,7 @@ variables. Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy configured to trigger every day at midnight. Archives are stored in a directory based on the current year and month. -The script returns a list of rolled over files under the base directory +The script returns a list of rolled-over files under the base directory dated Friday the 13th. The Delete action will delete all files returned by the script. @@ -3331,7 +3338,7 @@ by the script. } statusLogger.trace 'SCRIPT: returning ' + result; result; - ]] > + ]]> @@ -3366,7 +3373,7 @@ for files to apply attributes. |maxDepth |int |The maximum number of levels of directories to visit. A value of 0 means that only the starting file (the base path itself) is -visited, unless denied by the security manager. A value of +visited unless denied by the security manager. A value of Integer.MAX_VALUE indicates that all levels should be visited. The default is 1, meaning only the files in the specified base directory. @@ -3380,7 +3387,7 @@ link:#DeletePathCondition[DeletePathCondition] File attribute permissions in POSIX format to apply when action is executed. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -3389,28 +3396,28 @@ Examples: rw------- or rw-rw-rw- etc... |fileOwner |String a| File owner to define when action is executed. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying files system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define when action is executed. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. |======================================================================= Below is a sample configuration that uses a RollingFileAppender and -defines different POSIX file attribute view for current and rolled log +defines different POSIX file attribute views for current and rolled log files. [source,xml] @@ -3453,21 +3460,21 @@ buffered (this cannot be switched off) and internally it uses a saw a 20-200% performance improvement compared to RollingFileAppender with "bufferedIO=true" in our xref:manual/performance.adoc#whichAppender[measurements]. The -RollingRandomAccessFileAppender writes to the File named in the fileName -parameter and rolls the file over according the TriggeringPolicy and the +`RollingRandomAccessFileAppender` writes to the file named in the fileName +parameter and rolls the file over according to the TriggeringPolicy and the RolloverPolicy. Similar to the RollingFileAppender, RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager to -actually perform the file I/O and perform the rollover. While +perform the file I/O and perform the rollover. While RollingRandomAccessFileAppender from different Configurations cannot be shared, the RollingRandomAccessFileManagers can be if the Manager is accessible. For example, two web applications in a servlet container can -have their own configuration and safely write to the same file if Log4j +have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. A RollingRandomAccessFileAppender requires a link:#TriggeringPolicies[TriggeringPolicy] and a link:#RolloverStrategies[RolloverStrategy]. The triggering policy -determines if a rollover should be performed while the RolloverStrategy +determines if a rollover should be performed while the `RolloverStrategy` defines how the rollover should be done. If no RolloverStrategy is configured, RollingRandomAccessFileAppender will use the link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. Since log4j-2.5, @@ -3524,7 +3531,7 @@ is supplied the default pattern layout of "%m%n" will be used. should occur. |strategy |RolloverStrategy |The strategy to use to determine the name -and location of the archive file. +and the location of the archive file. |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -3536,7 +3543,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. File attribute permissions in POSIX format to apply whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -3545,21 +3552,21 @@ Examples: `rw-------` or `rw-rw-rw-` etc... |fileOwner |String a| File owner to define whenever the file is created. -Changing file's owner may be restricted for security reason and +Changing the file's owner may be restricted for security reasons and Operation not permitted IOException thrown. Only processes with an effective user ID equal to the user ID of the file or with appropriate privileges may change the ownership of a file if http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED] is in effect for path. -Underlying files system shall support file +The underlying file system shall support file https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner] attribute view. |fileGroup |String a| File group to define whenever the file is created. -Underlying files system shall support +The underlying files system shall support https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX] file attribute view. @@ -3574,8 +3581,8 @@ See xref:#TriggeringPolicies[RollingFileAppender Triggering Policies]. See link:#RolloverStrategies[RollingFileAppender Rollover Strategies]. Below is a sample configuration that uses a -RollingRandomAccessFileAppender with both the time and size based -triggering policies, will create up to 7 archives on the same day (1-7) +RollingRandomAccessFileAppender with both the time and size-based +triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip: @@ -3632,8 +3639,8 @@ files before removing them. ---- Below is a sample configuration that uses a -RollingRandomAccessFileAppender with both the time and size based -triggering policies, will create up to 7 archives on the same day (1-7) +RollingRandomAccessFileAppender with both the time and size-based +triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every 6 hours when the hour is divisible by 6: @@ -3665,13 +3672,13 @@ the hour is divisible by 6: [#RoutingAppender] == RoutingAppender -The RoutingAppender evaluates LogEvents and then routes them to a +The `RoutingAppender` evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be -dynamically created as needed. The RoutingAppender should be configured +dynamically created as needed. The `RoutingAppender` should be configured after any Appenders it references to allow it to shut down properly. -You can also configure a RoutingAppender with scripts: you can run a +You can also configure a `RoutingAppender` with scripts: you can run a script when the appender starts and when a route is chosen for an log event. @@ -3750,26 +3757,26 @@ appender can be used, it is only used as a shorthand. [#Routes] === Routes -The Routes element accepts a single attribute named "pattern". The +The `Routes` element accepts a single attribute named "pattern". The pattern is evaluated against all the registered Lookups and the result -is used to select a Route. Each Route may be configured with a key. If -the key matches the result of evaluating the pattern then that Route -will be selected. If no key is specified on a Route then that Route is -the default. Only one Route can be configured as the default. +is used to select a `Route`. Each `Route` may be configured with a key. If +the key matches the result of evaluating the pattern then that `Route` +will be selected. If no key is specified on a `Route` then that `Route` is +the default. Only one `Route` can be configured as the default. -The Routes element may contain a Script child element. If specified, the -Script is run for each log event and returns the String Route key to +The `Routes` element may contain a `Script` child element. If specified, the +`Script` is run for each log event and returns the String Route key to use. -You must specify either the pattern attribute or the Script element, but +You must specify either the pattern attribute or the `Script` element, but not both. -Each Route must reference an Appender. If the Route contains a ref -attribute then the Route will reference an Appender that was defined in -the configuration. 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. +Each `Route` must reference an `Appender`. If the `Route` contains a ref +attribute then the `Route` will reference an `Appender` that was defined in +the configuration. 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`. This script is passed the following variables: @@ -3841,7 +3848,7 @@ based on the presence of a Marker named "AUDIT". The RoutingAppender can be configured with a PurgePolicy whose purpose is to stop and remove dormant Appenders that have been dynamically created by the RoutingAppender. Log4j currently provides the -IdlePurgePolicy as the only PurgePolicy available for cleaning up the +IdlePurgePolicy is the only PurgePolicy available for cleaning up the Appenders. The IdlePurgePolicy accepts 2 attributes; timeToLive, which is the number of timeUnits the Appender should survive without having any events sent to it, and timeUnit, the String representation of @@ -3850,7 +3857,7 @@ attribute. Below is a sample configuration that uses a RoutingAppender to route all Audit events to a FlumeAppender and all other events will be routed to a -RollingFileAppender that captures only the specific event type. Note +RollingFileAppender captures only the specific event type. Note that the AuditAppender was predefined while the RollingFileAppenders are created as needed. @@ -3893,9 +3900,9 @@ created as needed. Sends an e-mail when a specific logging event occurs, typically on errors or fatal errors. -The number of logging events delivered in this e-mail depend on the value of *BufferSize* option. The `SMTPAppender` keeps only the last `BufferSize` logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application context. All events in the buffer are included in the email. The buffer will contain the most recent events of level TRACE to WARN preceding the event that triggered the email. +The number of logging events delivered in this e-mail depends on the value of the `BufferSize` option. The `SMTPAppender` keeps only the last `BufferSize` logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application context. All events in the buffer are included in the email. The buffer will contain the most recent events of level TRACE to WARN preceding the event that triggered the email. -The default behavior is to trigger sending an email whenever an ERROR or higher severity event is logged and to format it as HTML. The circumstances on when the email is sent can be controlled by setting one or more filters on the Appender. As with other Appenders, the formatting can be controlled by specifying a Layout for the Appender. +The default behavior is to trigger sending an email whenever an ERROR or higher severity event is logged and to format it as HTML. The circumstances of when the email is sent can be controlled by setting one or more filters on the Appender. As with other Appenders, the formatting can be controlled by specifying a Layout for the Appender. [width="100%",options="header"] |=== @@ -3943,7 +3950,7 @@ The default behavior is to trigger sending an email whenever an ERROR or higher |smtpDebug |boolean -|When set to true enables session debugging on STDOUT. Defaults to false. +|When set to true turns on the session debugging on STDOUT. Defaults to false. |smtpHost |String @@ -4000,7 +4007,7 @@ calls a `ScriptPlugin` to compute an appender name. Log4j then creates one of the appender named listed under `AppenderSet` using the name of the `ScriptAppenderSelector`. After configuration, Log4j ignores the `ScriptAppenderSelector`. Log4j only builds the one selected appender -from the configuration tree, and ignores other `AppenderSet` child +from the configuration tree and ignores other `AppenderSet` child nodes. In the following example, the script returns the name "List2". The @@ -4037,12 +4044,12 @@ The `SocketAppender` is an OutputStreamAppender that writes its output to a remote destination specified by a host and port. The data can be sent over either TCP or UDP and can be sent in any format. You can optionally secure communication with link:#SSL[SSL]. Note that the TCP and SSL -variants write to the socket as a stream and do not expect response from +variants write to the socket as a stream and do not expect a response from the target destination. Due to limitations in the TCP protocol that means that when the target server closes its connection some log events may continue to appear to succeed until a closed connection exception is raised, causing those events to be lost. If guaranteed delivery is -required a protocol that requires acknowledgements must be used. +required a protocol that requires acknowledgments must be used. .`SocketAppender` Parameters [cols="20%,20%,60%",options="header",] @@ -4054,7 +4061,7 @@ required a protocol that requires acknowledgements must be used. log events. This parameter is required. |port |integer |The port on the host that is listening for log events. -This parameter must be specified.If the host name resolves to multiple +This parameter must be specified. If the hostname resolves to multiple IP addresses the TCP and SSL variations will fail over to the next IP address when a connection is lost. @@ -4077,23 +4084,23 @@ disk but could impact performance. |bufferedIO |boolean |When true - the default, events are written to a buffer and the data will be written to the socket when the buffer is -full or, if immediateFlush is set, when the record is written. +full or, if immediateFlush is set when the record is written. |bufferSize |int |When bufferedIO is true, this is the buffer size, the default is 8192 bytes. |layout |Layout |The Layout to use to format the LogEvent. Required, there is no default. _New since 2.9, in previous versions -SerializedLayout was default._ +SerializedLayout was the default._ |reconnectionDelayMillis |integer |If set to a value greater than 0, -after an error the SocketManager will attempt to reconnect to the server -after waiting the specified number of milliseconds. If the reconnect +after an error, the SocketManager will attempt to reconnect to the server +after waiting for the specified number of milliseconds. If the reconnect fails then an exception will be thrown (which can be caught by the application if `ignoreExceptions` is set to `false`). |connectTimeoutMillis |integer |The connect timeout in milliseconds. The -default is 0 (infinite timeout, like Socket.connect() methods). +default is 0 (infinite timeout, like `Socket.connect()` methods). |ignoreExceptions |boolean |The default is `true`, causing exceptions encountered while appending events to be internally logged and then @@ -4131,8 +4138,8 @@ This is a secured link:#SSL[SSL] configuration: - - + + @@ -4156,7 +4163,7 @@ documents the parameters available for SSL configuration. |======================================================================= |Parameter Name |Type |Description |protocol |String |The SSL protocol to use, `TLS` if omitted. A single value -may enable multiple protocoles, see the +may enable multiple protocols, see the https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#sslcontext-algorithms[JVM documentation] for details. @@ -4171,7 +4178,7 @@ counterparty. Determines whether the remote authentication credentials [#KeyStore] === KeyStore -The keystore is meant to contain your private keys and certificates, and +The Keystore is meant to contain your private keys and certificates, and determines which authentication credentials to send to the remote host. .KeyStore Configuration Parameters @@ -4210,7 +4217,7 @@ to trust when a remote party presents its certificate. Determines whether the remote authentication credentials (and thus the connection) should be trusted. -In some cases, they can be one and the same store, although it is often +In some cases, they can be the same store, although it is often better practice to use distinct stores (especially when they are file-based). @@ -4271,13 +4278,13 @@ advertised. |appName |String |The value to use as the APP-NAME in the RFC 5424 syslog record. -|charset |String |The character set to use when converting the syslog +|charset |String |The character set to use when converting the Syslog String to a byte array. The String must be a valid https://download.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html[`Charset`]. If not specified, the default system Charset will be used. |connectTimeoutMillis |integer |The connect timeout in milliseconds. The -default is 0 (infinite timeout, like Socket.connect() methods). +default is 0 (infinite timeout, like `Socket.connect()` methods). |enterpriseNumber |integer |The IANA enterprise number as described in http://tools.ietf.org/html/rfc5424#section-7.2.2[RFC 5424] @@ -4291,20 +4298,19 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV", "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be -specified as upper or lower case characters. +specified as upper or lowercase characters. -|format |String |If set to "RFC5424" the data will be formatted in -accordance with RFC 5424. Otherwise, it will be formatted as a BSD +|format |String |If set to "RFC5424" the data will be formatted by RFC 5424. +Otherwise, it will be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be 1024 bytes or shorter the SyslogLayout does not truncate them. The RFC5424Layout also does not truncate records since the receiver must -accept records of up to 2048 bytes and may accept records that are -longer. +accept records of up to 2048 bytes and may accept longer records. |host |String |The name or address of the system that is listening for log events. This parameter is required. -|id |String |The default structured data id to use when formatting +|id |String |The default structured data-id to use when formatting according to RFC 5424. If the LogEvent contains a StructuredDataMessage the id from the Message will be used instead of this value. @@ -4325,33 +4331,33 @@ disk but could impact performance. |includeMDC |boolean |Indicates whether data from the ThreadContextMap will be included in the RFC 5424 Syslog record. Defaults to true. -|Layout |Layout |A custom layout which overrides the `format` setting. +|Layout |Layout |A custom layout that overrides the `format` setting. |loggerFields |List of KeyValuePairs |Allows arbitrary PatternLayout patterns to be included as specified ThreadContext fields; no default -specified. To use, include a >LoggerFields< nested element, containing -one or more >KeyValuePair< elements. Each >KeyValuePair< must have a key -attribute, which specifies the key name which will be used to identify +specified. To use, include a `LoggerFields` nested element, containing +one or more `KeyValuePair` elements. Each `KeyValuePair` must have a key +attribute, which specifies the key name that will be used to identify the field within the MDC Structured Data element, and a value attribute, which specifies the PatternLayout pattern to use as the value. -|mdcExcludes |String |A comma separated list of mdc keys that should be +|mdcExcludes |String |A comma-separated list of mdc keys that should be excluded from the LogEvent. This is mutually exclusive with the mdcIncludes attribute. This attribute only applies to RFC 5424 syslog records. -|mdcIncludes |String |A comma separated list of mdc keys that should be +|mdcIncludes |String |A comma-separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes attribute. This attribute only applies to RFC 5424 syslog records. -|mdcRequired |String |A comma separated list of mdc keys that must be +|mdcRequired |String |A comma-separated list of `mdc` keys that must be present in the MDC. If a key is not present a LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records. -|mdcPrefix |String |A string that should be prepended to each MDC key in -order to distinguish it from event attributes. The default string is -"mdc:". This attribute only applies to RFC 5424 syslog records. +|mdcPrefix |String |A string that should be prepended to each MDC key +to distinguish it from event attributes. The default string is +`mdc:`. This attribute only applies to RFC 5424 syslog records. |messageId |String |The default value to be used in the MSGID field of RFC 5424 syslog records. @@ -4370,8 +4376,8 @@ This parameter must be specified. TrustStore. See link:#SSL[SSL]. |reconnectionDelayMillis |integer |If set to a value greater than 0, -after an error the SocketManager will attempt to reconnect to the server -after waiting the specified number of milliseconds. If the reconnect +after an error, the SocketManager will attempt to reconnect to the server +after waiting for the specified number of milliseconds. If the reconnect fails then an exception will be thrown (which can be caught by the application if `ignoreExceptions` is set to `false`). |======================================================================= From ced35ab13e86c2c1d0626ca89744f394bbfa6170 Mon Sep 17 00:00:00 2001 From: Christian Grobmeier Date: Mon, 13 May 2024 23:01:16 +0200 Subject: [PATCH 10/24] tiny improvements on wording --- .../ROOT/pages/manual/configuration.adoc | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index ae32f9198d9..8b7a5ba281b 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -21,7 +21,7 @@ Ralph Goers ; Piotr Karwasz Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. -In order to decide which of these statements will be logged and where, users need to configure Log4j Core. +To decide which of these statements will be logged and where users need to configure Log4j Core. Log4j Core can be configured in two ways: @@ -38,7 +38,7 @@ To prevent a chicken-and-egg problem some configuration options, such as the loc [#configuration-file] == Configuration file -TIP: For a quick example of configuration file see the xref:manual/installation.adoc#impl-core-config[Configuring Log4j Core section]. +TIP: For a quick example of a configuration file see the xref:manual/installation.adoc#impl-core-config[Configuring Log4j Core section]. Log4j Core can be configured using multiple configuration file formats. Configuration factories for the XML, JSON, YAML and Java properties format are included in the `log4j-core` artifact. @@ -50,7 +50,7 @@ include::partial$configuration-file-format-deps.adoc[] [WARNING] ==== The format of the configuration file changed between Log4j{nbsp}1 and Log4j{nbsp}2. -Files in the Log4j{nbsp}1 formats are ignored by default. +Files in the Log4j{nbsp}1 format are ignored by default. To enable partial support for old configuration formats see xref:manual/migration.adoc#enabling-the-log4j-1-x-bridge[Enabling the Log4j{nbsp}1 bridge]. ==== @@ -64,7 +64,7 @@ Upon initialization of a new logger context, Log4j assigns it a context name and . Files named `log4j2-test.`, . Files named `log4j2.` . Files named `log4j2.`, -. If no configuration file could be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. +. If no configuration file can be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. The default configuration prints all messages less specific than xref:manual/systemproperties.adoc#log4j2.level[log4j2.level] to the console. @@ -83,7 +83,7 @@ The `` and `` placeholders above have the following mean :: depends on the runtime environment in which Log4j runs: -* for standalone Java SE application it is a random identifier, +* for standalone Java SE applications it is a random identifier, * for web applications it is derived from the application descriptor. See xref:manual/webapp.adoc#configuration[Log4j Web application configuration] for more details. @@ -113,7 +113,7 @@ It is also possible to override the location of the configuration file using the xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] configuration property. -In this case Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. +In this case, Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. ==== @@ -126,7 +126,7 @@ The root of the tree creates a link:../javadoc/log4j-core/org/apache/logging/log A node is a fairly simple structure that represents a single Log4j plugin (cf. xref:plugin-reference.adoc[] for a complete list) such as an appender, layout or logger configuration. Each node has: -* a set of simple string key value pairs called **attributes**. +* a set of simple string key-value pairs called **attributes**. Attributes are **matched by name** against the list of available configuration options of a Log4j plugin. * one distinguished attribute called **plugin type** specifies the kind of Log4j plugin we want to instantiate. @@ -171,8 +171,8 @@ In the JSON configuration format: * JSON properties of type object or array are used to represent nested configuration elements. * The **plugin type** of a JSON object is given by: ** the value of the `type` key, if present, -** or the key associated with the JSON object otherwise, -** if the JSON object representing the node is part of an array, the key associated to the JSON array is used. +** or the key associated with the JSON object otherwise. +** If the JSON object representing the node is part of an array, the key associated with the JSON array is used. ==== + [TIP] @@ -206,8 +206,8 @@ In the YAML configuration format: * YAML properties of collection type are used to represent nested configuration elements. * The **plugin type** of a YAML mapping is given by: ** the value of the `type` key, if present, -** or the key associated with the YAML mapping otherwise, -** if the YAML mapping representing the node is part of a YAML block sequence, the key associated to the YAML sequence is used. +** or the key associated with the YAML mapping otherwise. +** If the YAML mapping representing the node is part of a YAML block sequence, the key associated with the YAML sequence is used. ==== + [TIP] @@ -234,15 +234,15 @@ In the Java properties configuration format: * Configuration attributes are specified by appending the name of the property (e.g. `name`) to the prefix of the node, separated by a dot (e.g. `appender.foo.name`). * The **plugin type** must necessarily be specified as an attribute named `type`. * Nested elements are created by: -** choosing an arbitrary id for the nested component (e.g. `<0>`), -** appending the id to the prefix of the parent component (e.g. `appender.foo.<0>`), -** specifying the type of the nested plugin by assigning a `type` attribute (e.g. `appender.foo.<0>.type`). +** Choosing an arbitrary id for the nested component (e.g. `<0>`) +** Appending the id to the prefix of the parent component (e.g. `appender.foo.<0>`) +** Specifying the type of the nested plugin by assigning a `type` attribute (e.g. `appender.foo.<0>.type`) ==== + [NOTE] ==== -The id assigned to nested components is only used for sorting purposes. -However, some components assign a special meaning to some ids. +The ID assigned to nested components is only used for sorting purposes. +However, some components assign a special meaning to some IDs. See a list of exceptions in <>. ==== @@ -265,14 +265,14 @@ See <> for details. + Appenders are the exit point of the logging pipeline. They decide to which resource (console, file, database, etc.) the log event is sent. -In the examples of this chapter we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender]. +In the examples of this chapter, we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender]. + See xref:manual/appenders.adoc[Appender configuration] for details. Layouts:: + Layouts tell appenders how they should format the log event: text, JSON, XML, etc. -In the examples of this chapter we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] +In the examples of this chapter, we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] and xref:manual/json-template-layout.adoc[JSON template layout]. + @@ -358,7 +358,7 @@ A Log4j Core configuration file can also contain these configuration elements: CustomLevels:: + -Log4j allows to configure custom level names. +Log4j allows the configuration of custom log-level names. + See xref:manual/customloglevels.adoc[Custom log level configuration] for details. @@ -404,7 +404,7 @@ If set to `0`, polling is disabled. [CAUTION] ==== -Unlike other logging backends Log4j Core is designed with **audit** logging in mind. +Unlike other logging backends, Log4j Core is designed with **audit** logging in mind. During a reconfiguration process, no messages are lost. @@ -412,7 +412,7 @@ Unless the new configuration file removes an appender, the old one continues to Since some appender options (like the append mode used to open a file) can not be changed without closing the resource used by an appender, some attribute changes will be **ignored** during a reconfiguration. -In order to modify these options during a reconfiguration you also need to change the resource used by the appender (e.g. the file name used by a file appender). +To modify these options during a reconfiguration you also need to change the resource used by the appender (e.g. the file name used by a file appender). ==== [id=configuration-attribute-status] @@ -531,7 +531,7 @@ While Log4j makes every effort to only compute it if it was requested by a confi [TIP] ==== -This setting only applies to computation of location at **runtime**. +This setting only applies to the computation of location at **runtime**. If the location is computed at build time using link:/log4j/transform/latest/#log4j-transform-maven-plugin[Log4j Transform Maven Plugin] this setting is ignored and location information will always be available for logging. ==== @@ -599,7 +599,7 @@ See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilit Many Log4j components such as loggers use appender references to designate, which appenders will be used to deliver their events. -Unlike Log4j 1, where appender references were simple pointers, in Log4j 2 they have additional filtering capabilities. +Unlike in Log4j 1, where appender references were simple pointers, in Log4j 2, they have additional filtering capabilities. Appender references can have the following configuration attributes and elements: @@ -690,7 +690,7 @@ If both these conditions hold: * the lookup has a value assigned to `name`, -- + -the value for the lookup is a substituted. +the value for the lookup is substituted. Otherwise, the expansion of `$\{name}` is substituted. + If `name` starts with a hyphen `-` (e.g. `-variable`), it must be escaped with a backslash `\` (e.g. `\-variable`). @@ -726,7 +726,7 @@ Otherwise, the expansion of `${name:-default}` is substituted. [NOTE] ==== -To prevent the expansion of one of the expression above, the initial `$` must be doubled as `$$`. +To prevent the expansion of one of the expressions above, the initial `$` must be doubled as `$$`. The same rule applies to the `name` parameter: if it contains a `${` sequence, the sequence must be escaped as `$${`. ==== @@ -736,7 +736,7 @@ The same rule applies to the `name` parameter: if it contains a `${` sequence, t For most attributes property substitution is performed only once at **configuration time**, but there are two categories of 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 @@ -748,8 +748,8 @@ In this case: ** If you want property substitution to happen only once, you 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}` -* Other components defer the evaluation of their children components. -In this case you only need one dollar `$` sign. +* 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: @@ -791,7 +791,7 @@ Therefore, the dollar `$` sign needs to be escaped. [id=arbiters] === [[Arbiters]] Arbiters -While property substitution allows to use the same configuration file in multiple deployment environments, sometimes changing the values of configuration attributes is not enough. +While property substitution allows to use of the same configuration file in multiple deployment environments, sometimes changing the values of configuration attributes is not enough. Arbiters are to configuration elements what property substitution is for configuration attributes: they allow to conditionally add a subtree of configuration elements to a configuration file. @@ -845,7 +845,7 @@ include::example$configuration/arbiters.properties[lines=17..-1] The above example has a problem: if the Java system property `env` has a value different from `dev` or `prod`, the appender will have no layout. -This is a case, when the `Select` plugin is useful: this configuration element contains a list of arbiters and a +This is a case when the `Select` plugin is useful: this configuration element contains a list of arbiters and a `DefaultArbiter` element. If none of the arbiters match, the configuration from the `DefaultArbiter` element will be used: @@ -886,7 +886,7 @@ include::example$configuration/arbiters-select.properties[lines=17..-1] [#CompositeConfiguration] === Composite Configuration -Log4j allows multiple configuration files to be used at the same time by specifying them as a list of comma separated file paths or URLs in the +Log4j allows multiple configuration files to be used at the same time by specifying them as a list of comma-separated file paths or URLs in the xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] configuration property. @@ -953,7 +953,7 @@ Specifies the path to a classpath resource containing an XML schema. If set to `true` all configuration files will be checked against the XML schema provided by the <>. -This setting also enables "XML strict mode" and allows to specify the **plugin type** of an element through a `type` attribute instead of the tag name. +This setting also enables "XML strict mode" and allows one to specify the **plugin type** of an element through a `type` attribute instead of the tag name. [id=xinclude] ===== [[XInlcude]] XInclude @@ -988,7 +988,7 @@ include::example$configuration/xinclude-loggers.xml[lines=1;18..-1] ==== Java properties format The Java properties configuration format is by far the most verbose of the available formats. -In order to make it more usable a series of exceptions to the rules in <> have been introduced over time: +To make it more usable a series of exceptions to the rules in <> have been introduced over time: . The following direct children of `Configuration` have predefined prefixes and do not require to specify a `type` attribute: @@ -1034,4 +1034,4 @@ rootLogger.appenderRef.0.ref = APPENDER . All the keys of the form `logger..appenderRef.`, where `` and `` are arbitrary, are considered appender references. -. To add a filter to a component use a `filter.` prefix instead of just ``. \ No newline at end of file +. To add a filter to a component use a `filter.` prefix instead of just ``. From f797fcbd6d6ec65050ba4b39c462f9f0e784b051 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 16:42:36 +0200 Subject: [PATCH 11/24] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Volkan Yazıcı --- .../modules/ROOT/examples/configuration/properties.xml | 2 +- .../modules/ROOT/examples/configuration/scripts.json | 4 ++-- .../antora/modules/ROOT/pages/manual/configuration.adoc | 9 +++------ 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.xml b/src/site/antora/modules/ROOT/examples/configuration/properties.xml index 06003365ac9..d85cb9002cc 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/properties.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/properties.xml @@ -22,5 +22,5 @@ - + diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.json b/src/site/antora/modules/ROOT/examples/configuration/scripts.json index 5a8aeaa4849..daf3efb805a 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.json +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.json @@ -31,7 +31,7 @@ "Script": { "name": "EventLogger-filter", "language": "groovy", - "scriptText": "if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf(\"FLOW\"))) { return true; } else if (logEvent.getContextMap().containsKey(\"UserId\")) { return true; } return false;" + "scriptText": "if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf('FLOW'))) { return true; } else if (logEvent.getContextMap().containsKey('UserId')) { return true; } return false;" } } }, @@ -52,7 +52,7 @@ "Script": { "name": "selector", "language": "javascript", - "scriptText": "var result; if (logEvent.getLoggerName().equals(\"JavascriptNoLocation\")) { result = \"NoLocation\"; } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf(\"FLOW\")) { result = \"Flow\"; } result;" + "scriptText": "var result; if (logEvent.getLoggerName().equals('JavascriptNoLocation')) { result = 'NoLocation'; } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf('FLOW')) { result = 'Flow'; } result;" }, "ScriptFile": { "name": "Root-filter", diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 8b7a5ba281b..bf5e27ea344 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -28,11 +28,11 @@ Log4j Core can be configured in two ways: * through a <>. Since version 2.0 the configuration file format is considered as part of the public API, and it remains stable even across major version upgrades. -* through xref:manual/customconfig.adoc[Programmatic Configuration], which provides a larger spectrum of possible customizations, but might require code changes even for minor version upgrades, according to https://semver.org/[semantic versioning] rules. +* through xref:manual/customconfig.adoc[Programmatic Configuration], which provides a larger spectrum of possible customizations, but might require code changes during version upgrades. [NOTE] ==== -To prevent a chicken-and-egg problem some configuration options, such as the location of the configuration file can be supplied only through xref:manual/systemproperties.adoc[System properties]. +To prevent a chicken-and-egg problem some configuration options (e.g., the configuration file location) can only be supplied through xref:manual/systemproperties.adoc[system properties]. ==== [#configuration-file] @@ -41,7 +41,7 @@ To prevent a chicken-and-egg problem some configuration options, such as the loc TIP: For a quick example of a configuration file see the xref:manual/installation.adoc#impl-core-config[Configuring Log4j Core section]. Log4j Core can be configured using multiple configuration file formats. -Configuration factories for the XML, JSON, YAML and Java properties format are included in the `log4j-core` artifact. +Configuration factories for the XML, JSON, YAML and Java properties formats are included in the `log4j-core` artifact. Some configuration formats require additional dependencies to be present on the classpath, according to the table below. @@ -142,13 +142,10 @@ XML:: + Since XML was the original configuration format developed, the mapping from configuration nodes and XML elements is trivial: + -[id=configuration-with-xml] -==== * Each configuration node is represented by an XML element. * Each configuration attribute is represented by an XML attribute. * The **plugin type** of a node is equal to the name of the XML tag. * Each configuration nested element is represented by a nested XML element. -==== + [NOTE] ==== From d55b35ae36ab4b3c0f8a241d9869dd950d501b38 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 16:07:38 +0200 Subject: [PATCH 12/24] Simplify arbiters-select example --- .../modules/ROOT/examples/configuration/arbiters-select.json | 4 +--- .../ROOT/examples/configuration/arbiters-select.properties | 1 - .../modules/ROOT/examples/configuration/arbiters-select.xml | 2 +- .../modules/ROOT/examples/configuration/arbiters-select.yaml | 3 +-- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json index a30901cebdf..c934d7868b1 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json @@ -7,9 +7,7 @@ "SystemPropertyArbiter": { // <1> "propertyName": "env", "propertyValue": "dev", - "PatternLayout": { - "pattern": "%d [%t] %p %c - %m%n" - } + "PatternLayout": {} }, "DefaultArbiter": { // <2> "JsonTemplateLayout": {} diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties index bcbce1ecb6c..2339ba93d6e 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties @@ -22,7 +22,6 @@ appender.0.select.0.type = SystemPropertyArbiter # <1> appender.0.select.0.propertyName = env appender.0.select.0.propertyValue = dev appender.0.select.0.layout.type = PatternLayout -appender.0.select.0.layout.pattern = %d [%t] %p %c - %m%n appender.0.select.1.type = DefaultArbiter # <2> appender.0.select.1.layout.type = JsonTemplateLayout diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml index e23cd216240..b2aded3794b 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml @@ -22,7 +22,7 @@ diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml b/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml index 19416155d3f..f030f4733ab 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.xml b/src/site/antora/modules/ROOT/examples/configuration/filters.xml index 370daa1f0f5..fa6d3330b77 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/filters.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml index bb037c9282d..44ec26a0e6e 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml b/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml index c02892df790..784b0bb4a51 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.xml b/src/site/antora/modules/ROOT/examples/configuration/properties.xml index d85cb9002cc..8851bfd36c6 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/properties.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/properties.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.xml b/src/site/antora/modules/ROOT/examples/configuration/routing.xml index 0dd64774c26..ebda4946e52 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/routing.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/routing.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.xml b/src/site/antora/modules/ROOT/examples/configuration/scripts.xml index d145dd2e2f4..8860bf84c82 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.xml @@ -17,7 +17,9 @@ --> + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml index 7f8d7574b99..8eb0e666a0e 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml @@ -18,7 +18,9 @@ + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-config-2.xsd"> diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index bf5e27ea344..ed19eb47c72 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -16,7 +16,6 @@ //// [id=configuration] = Configuration - Ralph Goers ; Piotr Karwasz Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. From fcacdee95371b5a4a1ffd70305946ac98ccda183 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 16:25:21 +0200 Subject: [PATCH 14/24] Remove attribute with default value --- .../modules/ROOT/examples/configuration/main-elements.json | 1 - .../ROOT/examples/configuration/main-elements.properties | 1 - .../modules/ROOT/examples/configuration/main-elements.xml | 2 +- .../modules/ROOT/examples/configuration/main-elements.yaml | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.json b/src/site/antora/modules/ROOT/examples/configuration/main-elements.json index 1ab763c201e..0d17c826861 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/main-elements.json +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.json @@ -3,7 +3,6 @@ "Appenders": { "Console": { // <1> "name": "CONSOLE", - "target": "SYSTEM_OUT", "PatternLayout": { "pattern": "%p - %m%n" } diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties b/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties index 91d13e2c559..2b98fbe6576 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties @@ -16,7 +16,6 @@ # appender.0.type = Console # <1> appender.0.name = CONSOLE -appender.0.target = SYSTEM_OUT appender.0.layout.type = PatternLayout appender.0.layout.pattern = %p - %m%n diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml b/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml index 784b0bb4a51..6f3957d6148 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml @@ -21,7 +21,7 @@ https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-config-2.xsd"> - + diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml b/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml index 8a588f59a80..f7da7e8beda 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml @@ -18,7 +18,6 @@ Configuration: Appenders: Console: # <1> name: "CONSOLE" - target: "SYSTEM_OUT" PatternLayout: pattern: "%p - %m%n" File: From 76bb04f69b2818c3b634960d2cdf7b15ad71607f Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 16:28:59 +0200 Subject: [PATCH 15/24] YAML formatting --- .../modules/ROOT/examples/configuration/arbiters-select.yaml | 4 ++-- .../antora/modules/ROOT/examples/configuration/arbiters.yaml | 2 +- .../modules/ROOT/examples/configuration/main-elements.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml index 724909c8088..926447f64e6 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml @@ -23,9 +23,9 @@ Configuration: SystemPropertyArbiter: # <1> propertyName: "env" propertyValue: "dev" - PatternLayout: { } + PatternLayout: {} DefaultArbiter: # <2> - JsonTemplateLayout: { } + JsonTemplateLayout: {} Loggers: Root: level: "INFO" diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml b/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml index 016e6cfa7d8..53cd2477b1e 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml @@ -26,7 +26,7 @@ Configuration: pattern: "%d [%t] %p %c - %m%n" - propertyName: "env" # <2> propertyValue: "prod" - JsonTemplateLayout: { } + JsonTemplateLayout: {} Loggers: Root: level: "INFO" diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml b/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml index f7da7e8beda..e29280933eb 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml @@ -23,7 +23,7 @@ Configuration: File: - name: "MAIN" # <2> fileName: "logs/main.log" - JsonTemplateLayout: { } + JsonTemplateLayout: {} - name: "DEBUG_LOG" # <3> fileName: "logs/debug.log" PatternLayout: From 01ef75c7a139c1d9bf8e9dc8c64740925df1b2f9 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 17:09:13 +0200 Subject: [PATCH 16/24] Fix reference naming --- .../modules/ROOT/examples/configuration/scripts.json | 10 +++++----- .../ROOT/examples/configuration/scripts.properties | 10 +++++----- .../modules/ROOT/examples/configuration/scripts.xml | 10 +++++----- .../modules/ROOT/examples/configuration/scripts.yaml | 10 +++++----- .../ROOT/examples/configuration/xinclude-appenders.xml | 4 ++-- .../ROOT/examples/configuration/xinclude-loggers.xml | 4 ++-- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.json b/src/site/antora/modules/ROOT/examples/configuration/scripts.json index daf3efb805a..73db82029ca 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.json +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.json @@ -7,7 +7,7 @@ "ScriptPatternSelector": { "defaultPattern": "%d %p %m%n", "ScriptRef": { - "ref": "selector", + "ref": "SELECTOR_SCRIPT", "PatternMatch": [ { "key": "NoLocation", @@ -29,7 +29,7 @@ "onMatch": "ACCEPT", "onMismatch": "DENY", "Script": { - "name": "EventLogger-filter", + "name": "EVENT_LOGGER_FILTER", "language": "groovy", "scriptText": "if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf('FLOW'))) { return true; } else if (logEvent.getContextMap().containsKey('UserId')) { return true; } return false;" } @@ -41,7 +41,7 @@ "onMatch": "ACCEPT", "onMismatch": "DENY", "ScriptRef": { - "ref": "Root-filter" + "ref": "ROOT_FILTER" } }, "AppenderRef": { @@ -50,12 +50,12 @@ }, "Scripts": { "Script": { - "name": "selector", + "name": "SELECTOR_SCRIPT", "language": "javascript", "scriptText": "var result; if (logEvent.getLoggerName().equals('JavascriptNoLocation')) { result = 'NoLocation'; } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf('FLOW')) { result = 'Flow'; } result;" }, "ScriptFile": { - "name": "Root-filter", + "name": "ROOT_FILTER", "path": "scripts/filter.groovy" } } diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.properties b/src/site/antora/modules/ROOT/examples/configuration/scripts.properties index 91c1d0e5947..8c41afe7d59 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.properties +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.properties @@ -21,7 +21,7 @@ appender.0.layout.type = PatternLayout appender.0.layout.selector = ScriptPatternSelector appender.0.layout.selector.defaultPattern = %d %p %m%n appender.0.layout.selector.scriptRef.type = ScriptRef -appender.0.layout.selector.scriptRef.ref = selector +appender.0.layout.selector.scriptRef.ref = SELECTOR_SCRIPT appender.0.layout.selector.match[0].type = PatternMatch appender.0.layout.selector.match[0].key = NoLocation appender.0.layout.selector.match[0].pattern = [%-5level] %c{1.} %msg%n @@ -34,7 +34,7 @@ logger.0.filter.0.type = ScriptFilter logger.0.filter.0.onMatch = ACCEPT logger.0.filter.0.onMismatch = DENY logger.0.filter.0.script.type = Script -logger.0.filter.0.script.name = EventLogger-filter +logger.0.filter.0.script.name = EVENT_LOGGER_FILTER logger.0.filter.0.script.language = groovy logger.0.filter.0.script.scriptText = if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW"))) {\ return true;\ @@ -48,11 +48,11 @@ rootLogger.filter.0.type = ScriptFilter rootLogger.filter.0.onMatch = ACCEPT rootLogger.filter.0.onMismatch = DENY rootLogger.filter.0.scriptRef.type = ScriptRef -rootLogger.filter.0.scriptRef.ref = Root-Filter +rootLogger.filter.0.scriptRef.ref = ROOT_FILTER rootLogger.appenderRef.0.ref = STDOUT script.0.type = Script -script.0.name = selector +script.0.name = SELECTOR_SCRIPT script.0.language = javascript script.0.scriptText = var result;\ if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {\ @@ -63,5 +63,5 @@ script.0.scriptText = var result;\ result; script.1.type = ScriptFile -script.1.name = Root-filter +script.1.name = ROOT_FILTER script.1.path = scripts/filter.groovy diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.xml b/src/site/antora/modules/ROOT/examples/configuration/scripts.xml index 8860bf84c82..f7e8b4cfeb1 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.xml @@ -24,7 +24,7 @@ - + @@ -34,7 +34,7 @@ - - + diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml b/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml index a339d397eed..6b5d6ccca1a 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml @@ -22,7 +22,7 @@ Configuration: ScriptPatternSelector: defaultPattern: "%d %p %m%n" ScriptRef: - ref: "selector" + ref: "SELECTOR_SCRIPT" PatternMatch: - key: "NoLocation" pattern: "[%-5level] %c{1.} %msg%n" @@ -35,7 +35,7 @@ Configuration: onMatch: "ACCEPT" onMismatch: "DENY" Script: - name: "EventLogger-filter" + name: "EVENT_LOGGER_FILTER" language: "groovy" scriptText: | if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) { @@ -50,12 +50,12 @@ Configuration: onMatch: "ACCEPT" onMismatch: "DENY" ScriptRef: - ref: "Root-filter" + ref: "ROOT_FILTER" AppenderRef: ref: "STDOUT" Scripts: Script: - name: "selector" + name: "SELECTOR_SCRIPT" language: "javascript" scriptText: | var result; @@ -66,5 +66,5 @@ Configuration: } result; ScriptFile: - name: "Root-filter" + name: "ROOT_FILTER" path: "scripts/filter.groovy" diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml index f3ef2af16f1..b34c7b2a713 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml @@ -16,10 +16,10 @@ ~ limitations under the License. --> - + - + diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml b/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml index cc2637345ac..eeb674535d3 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml @@ -17,9 +17,9 @@ --> - + - + From 719586173a19b020108d5380c6b24d3a3d17e195 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 17:27:13 +0200 Subject: [PATCH 17/24] Miscellaneous fixes --- .../ROOT/examples/configuration/filters.json | 3 +- .../examples/configuration/filters.properties | 1 - .../ROOT/examples/configuration/filters.xml | 2 +- .../ROOT/examples/configuration/filters.yaml | 1 - src/site/antora/modules/ROOT/nav.adoc | 2 +- .../modules/ROOT/pages/manual/appenders.adoc | 863 +++++++----------- 6 files changed, 332 insertions(+), 540 deletions(-) diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.json b/src/site/antora/modules/ROOT/examples/configuration/filters.json index 62401f52d77..4acc4c43b76 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/filters.json +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.json @@ -31,7 +31,6 @@ } }, "MarkerFilter": { // <1> - "marker": "PRIVATE", - "onMismatch": "NEUTRAL" + "marker": "PRIVATE" } } \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.properties b/src/site/antora/modules/ROOT/examples/configuration/filters.properties index f0a2c6036cd..1077fc44e7e 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/filters.properties +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.properties @@ -36,4 +36,3 @@ logger.0.filter.level = TRACE filter.type = MarkerFilter # <1> filter.marker = PRIVATE -filter.onMismatch = NEUTRAL diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.xml b/src/site/antora/modules/ROOT/examples/configuration/filters.xml index fa6d3330b77..4c86b04faf5 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/filters.xml +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.xml @@ -38,5 +38,5 @@ - + diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.yaml b/src/site/antora/modules/ROOT/examples/configuration/filters.yaml index 12d1862770c..9a4f61f3467 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/filters.yaml +++ b/src/site/antora/modules/ROOT/examples/configuration/filters.yaml @@ -39,4 +39,3 @@ Configuration: level: "TRACE" # <3> MarkerFilter: # <1> marker: "PRIVATE" - onMismatch: "NEUTRAL" diff --git a/src/site/antora/modules/ROOT/nav.adoc b/src/site/antora/modules/ROOT/nav.adoc index dc69a9c656a..b3a7b574d7d 100644 --- a/src/site/antora/modules/ROOT/nav.adoc +++ b/src/site/antora/modules/ROOT/nav.adoc @@ -40,7 +40,7 @@ ** xref:manual/thread-context.adoc[] ** xref:manual/scoped-context.adoc[] ** xref:manual/resource-logger.adoc[] -* Backend Configuration +* Configuration ** xref:manual/configuration.adoc[Configuration file] ** xref:manual/appenders.adoc[] ** xref:manual/layouts.adoc[] diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index a6464040b56..dd33e64af31 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -20,49 +20,39 @@ Ralph Goers; Gary Gregory; Nick Williams; Matt Sicker Appenders are responsible for delivering LogEvents to their destination. Every Appender must implement the link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[`Appender`] -interface. Most Appenders will extend +interface. +Most Appenders will extend link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/AbstractAppender.html[`AbstractAppender`] which adds link:../javadoc/log4j-core/org/apache/logging/log4j/core/LifeCycle.html[`Lifecycle`] and link:../javadoc/log4j-core/org/apache/logging/log4j/core/filter/Filterable.html[`Filterable`] -support. `Lifecycle` allows components to finish initialization after -configuration has been completed and to perform cleanup during shutdown. -`Filterable` allows the component to have `Filter` attached to it which are -evaluated during event processing. - -Appenders usually are only responsible for writing the event data to the -target destination. In most cases, they delegate responsibility for -formatting the event to a xref:manual/layouts.adoc[layout]. Some appenders wrap -other appenders so that they can modify the `LogEvent`, handle a failure -in an `Appender`, route the event to a subordinate `Appender` based on -advanced `Filter` criteria or provide similar functionality that does not -directly format the event for viewing. - -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. +support. `Lifecycle` allows components to finish initialization after configuration has been completed and to perform cleanup during shutdown. +`Filterable` allows the component to have `Filter` attached to it which are evaluated during event processing. + +Appenders usually are only responsible for writing the event data to the target destination. +In most cases, they delegate responsibility for formatting the event to a xref:manual/layouts.adoc[layout]. +Some appenders wrap other appenders so that they can modify the `LogEvent`, handle a failure in an `Appender`, route the event to a subordinate `Appender` based on advanced `Filter` criteria or provide similar functionality that does not directly format the event for viewing. + +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. [#AsyncAppender] == AsyncAppender -The AsyncAppender accepts references to other Appenders and causes -LogEvents to be written to them on a separate Thread. Note that -exceptions while writing to those Appenders will be hidden from the -application. The AsyncAppender should be configured after the appenders -it references to allow it to shut down properly. +The AsyncAppender accepts references to other Appenders and causes LogEvents to be written to them on a separate Thread. +Note that exceptions while writing to those Appenders will be hidden from the application. +The AsyncAppender should be configured after the appenders it references to allow it to shut down properly. By default, AsyncAppender uses https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html[`java.util.concurrent.ArrayBlockingQueue`] -which does not require any external libraries. Note that multi-threaded -applications should exercise care when using this appender as such: the -blocking queue is susceptible to lock contention and our -xref:manual/performance.adoc#asyncLogging[tests showed] performance may -become worse when more threads are logging concurrently. Consider using +which does not require any external libraries. +Note that multi-threaded applications should exercise care when using this appender as such: the blocking queue is susceptible to lock contention and our +xref:manual/performance.adoc#asyncLogging[tests showed] performance may become worse when more threads are logging concurrently. +Consider using xref:manual/async.adoc[lock-free Async Loggers] for optimal performance. .AsyncAppender Parameters @@ -116,12 +106,11 @@ type of `BlockingQueue` to use. See link:#BlockingQueueFactory[below documentation] for more details. |======================================================================= -There are also a few system properties that can be used to maintain -application throughput even when the underlying appender cannot keep up -with the logging rate and the queue is filling up. See the details for -system properties -xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy` -and `log4j2.DiscardThreshold`]. +There are also a few system properties that can be used to maintain application throughput even when the underlying appender cannot keep up with the logging rate and the queue is filling up. +See the details for system properties +xref:manual/systemproperties.adoc#log4j2.asyncQueueFullPolicy[`log4j2.asyncQueueFullPolicy`] +and +xref:manual/systemproperties.adoc#log4j2.discardThreshold[`log4j2.DiscardThreshold`]. A typical AsyncAppender configuration might look like this: @@ -147,11 +136,11 @@ A typical AsyncAppender configuration might look like this: ---- -[[BlockingQueueFactory]] Starting in Log4j 2.7, a custom implementation -of `BlockingQueue` or `TransferQueue` can be specified using a +[[BlockingQueueFactory]] +Starting in Log4j 2.7, a custom implementation of `BlockingQueue` or `TransferQueue` can be specified using a link:../javadoc/log4j-core/org/apache/logging/log4j/core/async/BlockingQueueFactory.html[`BlockingQueueFactory`] -plugin. To override the default `BlockingQueueFactory`, specify the -plugin inside an `` element like so: +plugin. +To override the default `BlockingQueueFactory`, specify the plugin inside an `` element like so: [source,xml] ---- @@ -197,22 +186,19 @@ attribute from AsyncAppender as `LinkedTransferQueue` does not support a maximum capacity. |======================================================================= - [#CassandraAppender] == CassandraAppender The CassandraAppender writes its output to an https://cassandra.apache.org/[Apache Cassandra] -database. A keyspace and table must be configured ahead of time, and the columns of that table are mapped -in a configuration file. Each column can specify either a https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout[StringLayout] (e.g., a -PatternLayout) along with an optional conversion type, or only -a conversion type for `org.apache.logging.log4j.spi.ThreadContextMap` or -`org.apache.logging.log4j.spi.ThreadContextStack` to store the MDC or NDC -in a map or list column respectively. A conversion type compatible with `java.util.Date` will -use the log event timestamp converted to that type (e.g., use `java.util.Date` to fill a +database. +A keyspace and table must be configured ahead of time, and the columns of that table are mapped in a configuration file. +Each column can specify either a https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout[StringLayout] (e.g., a PatternLayout) along with an optional conversion type, or only a conversion type for `org.apache.logging.log4j.spi.ThreadContextMap` or +`org.apache.logging.log4j.spi.ThreadContextStack` to store the MDC or NDC in a map or list column respectively. +A conversion type compatible with `java.util.Date` will use the log event timestamp converted to that type (e.g., use `java.util.Date` to fill a `timestamp` column type in Cassandra). .CassandraAppender Parameters -[cols="1,1,3", options="header"] +[cols="1,1,3",options="header"] |=== | Parameter Name | Type | Description @@ -343,8 +329,8 @@ CREATE TABLE logs ( == [[ConsoleAppender]] ConsoleAppender As one might expect, the ConsoleAppender writes its output to either -`System.out` or `System.err` with `System.out` being the default target. A -Layout must be provided to format the LogEvent. +`System.out` or `System.err` with `System.out` being the default target. +A Layout must be provided to format the LogEvent. .ConsoleAppender Parameters [cols="20%,20%,60%",options="header",] @@ -405,9 +391,8 @@ A typical Console configuration might look like: [#FailoverAppender] == FailoverAppender -The FailoverAppender wraps a set of appenders. If the primary Appender -fails the secondary appenders will be tried in order until one succeeds -or there are no more secondaries to try. +The FailoverAppender wraps a set of appenders. +If the primary Appender fails the secondary appenders will be tried in order until one succeeds or there are no more secondaries to try. .FailoverAppender Parameters [cols="20%,20%,60%",options="header",] @@ -469,14 +454,10 @@ A Failover configuration might look like: [id=fileappender] == [[FileAppender]] FileAppender -The FileAppender is an OutputStreamAppender that writes to the File -defined in the `fileName` parameter. The FileAppender uses a FileManager -(which extends OutputStreamManager) to perform the file I/O. -While FileAppenders from different Configurations cannot be shared, the -FileManagers can be if the Manager is accessible. For example, two web -applications in a servlet container can have their configuration and -safely write to the same file if Log4j is in a ClassLoader that is -common to both of them. +The FileAppender is an OutputStreamAppender that writes to the File defined in the `fileName` parameter. +The FileAppender uses a FileManager (which extends OutputStreamManager) to perform the file I/O. +While FileAppenders from different Configurations cannot be shared, the FileManagers can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. .FileAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -603,29 +584,19 @@ Here is a sample File configuration: _This is an optional component supplied in a separate jar._ -http://flume.apache.org/index.html[Apache Flume] is a distributed, -reliable, and available system for efficiently collecting, aggregating, -and moving large amounts of log data from many different sources to a -centralized data store. The FlumeAppender takes LogEvents and sends them -to a Flume agent as serialized Avro events for consumption. +http://flume.apache.org/index.html[Apache Flume] is a distributed, reliable, and available system for efficiently collecting, aggregating, and moving large amounts of log data from many different sources to a centralized data store. +The FlumeAppender takes LogEvents and sends them to a Flume agent as serialized Avro events for consumption. The Flume Appender supports three modes of operation. -1. It can act as a remote Flume client which sends Flume events via -Avro to a Flume Agent configured with an Avro Source. -2. It can act as an embedded Flume Agent where Flume events pass -directly into Flume for processing. -3. It can persist events to a local BerkeleyDB data store and then -asynchronously send the events to Flume, similar to the embedded Flume -Agent but without most of the Flume dependencies. - -Usage as an embedded agent will cause the messages to be directly passed -to the Flume Channel and then control will be immediately returned to -the application. All interaction with remote agents will occur -asynchronously. Setting the "type" attribute to "Embedded" will force -the use of the embedded agent. In addition, configuring agent properties -in the appender configuration will also cause the embedded agent to be -used. +1. It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured with an Avro Source. +2. It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing. +3. It can persist events to a local BerkeleyDB data store and then asynchronously send the events to Flume, similar to the embedded Flume Agent but without most of the Flume dependencies. + +Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel and then control will be immediately returned to the application. +All interaction with remote agents will occur asynchronously. +Setting the "type" attribute to "Embedded" will force the use of the embedded agent. +In addition, configuring agent properties in the appender configuration will also cause the embedded agent to be used. .FlumeAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -725,9 +696,7 @@ Appender in a link:#FailoverAppender[FailoverAppender]. indicate which variation of the Appender is desired. |======================================================================= -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent compresses the body and formats the body using -the RFC5424Layout: +A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body and formats the body using the RFC5424Layout: [source,xml] ---- @@ -748,9 +717,7 @@ the RFC5424Layout: ---- -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent compresses the body, formats the body using the -RFC5424Layout, and persists encrypted events to disk: +A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body, formats the body using the RFC5424Layout, and persists encrypted events to disk: [source,xml] ---- @@ -772,9 +739,7 @@ RFC5424Layout, and persists encrypted events to disk: ---- -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent compresses the body, and formats the body using -RFC5424Layout and passes the events to an embedded Flume Agent. +A sample FlumeAppender configuration that is configured with a primary and a secondary agent compresses the body, and formats the body using RFC5424Layout and passes the events to an embedded Flume Agent. [source,xml] ---- @@ -801,10 +766,7 @@ RFC5424Layout and passes the events to an embedded Flume Agent. ---- -A sample FlumeAppender configuration that is configured with a primary -and a secondary agent using Flume configuration properties compresses -the body, formats the body using RFC5424Layout and passes the events to -an embedded Flume Agent. +A sample FlumeAppender configuration that is configured with a primary and a secondary agent using Flume configuration properties compresses the body, formats the body using RFC5424Layout and passes the events to an embedded Flume Agent. [source,xml] ---- @@ -855,27 +817,20 @@ an embedded Flume Agent. As of Log4j 2.11.0, JDBC support has moved from the existing module `log4j-core` to the new module `log4j-jdbc`. -The JDBC Appender configured with a `DataSource` requires JNDI support so as of release 2.17.1 -this appender will not function unless `log4j2.enableJndiJdbc=true` is configured as a system property -or environment variable. See the xref:manual/configuration.adoc#enableJndiJdbc[enableJndiJdbc] system property. - -The JDBCAppender writes log events to a relational database table using -standard JDBC. It can be configured to obtain JDBC connections using a -JNDI `DataSource` or a custom factory method. Whichever approach you -take, it *_must_* be backed by a connection pool. Otherwise, logging -performance will suffer greatly. If batch statements are supported by -the configured JDBC driver and a `bufferSize` is configured to be a -positive number, then log events will be batched. Note that as of Log4j -2.8, there are two ways to configure log event to column mappings: the -original `ColumnConfig` style that only allows strings and timestamps, -and the new `ColumnMapping` plugin that uses Log4j's built-in type -conversion to allow for more data types. - -To get off the ground quickly during development, an alternative to -using a connection source based on JNDI is to use the non-pooling -`DriverManager` connection source. This connection source uses a JDBC -connection string, a username, and a password. Optionally, you can also -use properties. +The JDBC Appender configured with a `DataSource` requires JNDI support so as of release 2.17.1 this appender will not function unless `log4j2.enableJndiJdbc=true` is configured as a system property or environment variable. +See the xref:manual/configuration.adoc#enableJndiJdbc[enableJndiJdbc] system property. + +The JDBCAppender writes log events to a relational database table using standard JDBC. +It can be configured to obtain JDBC connections using a JNDI `DataSource` or a custom factory method. +Whichever approach you take, it *_must_* be backed by a connection pool. +Otherwise, logging performance will suffer greatly. +If batch statements are supported by the configured JDBC driver and a `bufferSize` is configured to be a positive number, then log events will be batched. +Note that as of Log4j 2.8, there are two ways to configure log event to column mappings: the original `ColumnConfig` style that only allows strings and timestamps, and the new `ColumnMapping` plugin that uses Log4j's built-in type conversion to allow for more data types. + +To get off the ground quickly during development, an alternative to using a connection source based on JNDI is to use the non-pooling +`DriverManager` connection source. +This connection source uses a JDBC connection string, a username, and a password. +Optionally, you can also use properties. .JDBCAppender Parameters [cols="20%,20%,60%",options="header",] @@ -941,16 +896,13 @@ application if `ignoreExceptions` is set to `false`). New in 2.11.2. |======================================================================= When configuring the JDBCAppender, you must specify a `ConnectionSource` -implementation from which the Appender gets JDBC connections. You must -use exactly one of the following nested elements: +implementation from which the Appender gets JDBC connections. +You must use exactly one of the following nested elements: * link:#JDBCDataSource[``]: Uses JNDI. -* link:#JDBCConnectionFactory[``]: Points to a -class-method pair to provide JDBC connections. -* link:#JDBCDriverManager[``]: A quick and dirty way to -get off the ground, no connection pooling. -* link:#JDBCPoolingDriver[``]: Uses Apache Commons DBCP -to provide connection pooling. +* link:#JDBCConnectionFactory[``]: Points to a class-method pair to provide JDBC connections. +* link:#JDBCDriverManager[``]: A quick and dirty way to get off the ground, no connection pooling. +* link:#JDBCPoolingDriver[``]: Uses Apache Commons DBCP to provide connection pooling. [#JDBCDataSource] .DataSource Parameters @@ -1042,11 +994,9 @@ a pooled connection elsewhere. For example: |validationQueryTimeoutSeconds |int | See http://commons.apache.org/proper/commons-dbcp/api-2.5.0/org/apache/commons/dbcp2/PoolableConnectionFactory.html[Apache Commons DBCP PoolableConnectionFactory.] |======================================================================= -When configuring the JDBCAppender, use the nested `` elements to -specify which columns in the table should be written to and how to write -to them. The JDBCAppender uses this information to formulate a -`PreparedStatement` to insert records without SQL injection -vulnerability. +When configuring the JDBCAppender, use the nested `` elements to specify which columns in the table should be written to and how to write to them. +The JDBCAppender uses this information to formulate a +`PreparedStatement` to insert records without SQL injection vulnerability. .Column Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -1128,9 +1078,7 @@ these. |type |String |Conversion type name, a fully qualified class name. |======================================================================= -Here are a couple of sample configurations for the JDBCAppender, as well as -a sample factory implementation that uses Commons Pooling and Commons -DBCP to pool database connections: +Here are a couple of sample configurations for the JDBCAppender, as well as a sample factory implementation that uses Commons Pooling and Commons DBCP to pool database connections: [source,xml] ---- @@ -1224,8 +1172,7 @@ public class ConnectionFactory { This appender is xref:manual/messages.adoc#MapMessage[`MapMessage`]-aware. -The following configuration uses no layout to indicate that the -appender should match the keys of a `MapMessage` to the names of +The following configuration uses no layout to indicate that the appender should match the keys of a `MapMessage` to the names of `ColumnMapping`s when setting the values of the Appender's SQL INSERT statement. This lets you insert rows for custom values in a database table based on a Log4j `MapMessage` instead of values from `LogEvent`. @@ -1263,12 +1210,15 @@ table based on a Log4j `MapMessage` instead of values from `LogEvent`. The JMS Appender sends the formatted log event to a JMS Destination. -The JMS Appender requires JNDI support so as of release 2.17.0, this appender will not function unless `log4j2.enableJndiJms=true` is configured as a system property or environment variable. See the https://logging.apache.org/log4j/2.x/manual/configuration.html#enableJndiJms[enableJndiJms] system property. +The JMS Appender requires JNDI support so as of release 2.17.0, this appender will not function unless `log4j2.enableJndiJms=true` is configured as a system property or environment variable. +See the https://logging.apache.org/log4j/2.x/manual/configuration.html#enableJndiJms[enableJndiJms] system property. -Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics. However, configurations written for 2.0 that use the `` or `` elements will continue to work with the new `` configuration element. +Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. +Starting in Log4j 2.1, these appenders were combined into the JMS Appender, which makes no distinction between queues and topics. +However, configurations written for 2.0 that use the `` or `` elements will continue to work with the new `` configuration element. .JMS Appender Parameters -[cols="1,1,1,3", options="header"] +[cols="1,1,1,3",options="header"] |=== | Parameter Name | Type | Default | Description @@ -1368,8 +1318,7 @@ Here is a sample JMS Appender configuration: ---- -To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the -layout of the appender to `MessageLayout` with `<MessageLayout />` (Since 2.9.): +To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the layout of the appender to `MessageLayout` with `<MessageLayout />` (Since 2.9.): [source,xml] ---- @@ -1394,9 +1343,9 @@ layout of the appender to `MessageLayout` with `<MessageLayout />` (Since As of Log4j 2.11.0, JPA support has moved from the existing module `log4j-core` to the new module `log4j-jpa`. -The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1. -It requires the API and a provider implementation to be on the classpath. -It also requires a decorated entity configured to persist to the table desired. +The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1. +It requires the API and a provider implementation to be on the classpath. +It also requires a decorated entity configured to persist to the table desired. If you want to use the default mappings, you can extend `org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity` and provide an `@Id` property. If you want to significantly customize the mappings, you can extend `org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity`. @@ -1432,8 +1381,12 @@ See the Javadoc or source code for these two classes for more information and ex |_Required._ The name of the JPA persistence unit that should be used for persisting log events. |=== -Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j configuration file, the second is the `persistence.xml` file. EclipseLink is assumed here, but any JPA 2.1 or higher provider will do. You should _always_ create a _separate_ persistence unit for logging, for two reasons. First, `` _must_ be set to "NONE," which is usually not desired in normal JPA usage. -Also, for performance reasons the logging entity should be isolated in its persistence unit away from all other entities and you should use a non-JTA data source. +Here is a sample configuration for the JPAAppender. +The first XML sample is the Log4j configuration file, the second is the `persistence.xml` file. +EclipseLink is assumed here, but any JPA 2.1 or higher provider will do. +You should _always_ create a _separate_ persistence unit for logging, for two reasons. +First, `` _must_ be set to "NONE," which is usually not desired in normal JPA usage. +Also, for performance reasons the logging entity should be isolated in its persistence unit away from all other entities and you should use a non-JTA data source. Note that your persistence unit _must_ also contain `` elements for all of the `org.apache.logging.log4j.core.appender.db.jpa.converter` converter classes. [source,xml] @@ -1566,14 +1519,13 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity { [#HttpAppender] == HttpAppender -The HttpAppender sends log events over HTTP. A Layout must be provided -to format the LogEvent. +The HttpAppender sends log events over HTTP. +A Layout must be provided to format the LogEvent. -It will set the `Content-Type` header according to the layout. Additional -headers can be specified with embedded Property elements. +It will set the `Content-Type` header according to the layout. +Additional headers can be specified with embedded Property elements. -It will also wait for a response from the server, and throw an error if no 2xx response -is received. +It will also wait for a response from the server, and throw an error if no 2xx response is received. Implemented with https://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html[HttpURLConnection]. @@ -1641,7 +1593,8 @@ Here is a sample HttpAppender configuration snippet: [[KafkaAppender]] == KafkaAppender -The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic. Each log event is sent as a Kafka record. +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"] |=== @@ -1697,9 +1650,11 @@ Here is a sample KafkaAppender configuration snippet: ---- -This appender is synchronous by default and will block until the record has been acknowledged by the Kafka server, timeout for this can be set with the `timeout.ms` property (defaults to 30 seconds). Wrap with https://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender[Async appender] and/or set syncSend to `false` to log asynchronously. +This appender is synchronous by default and will block until the record has been acknowledged by the Kafka server, timeout for this can be set with the `timeout.ms` property (defaults to 30 seconds). +Wrap with https://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender[Async appender] and/or set syncSend to `false` to log asynchronously. -This appender requires the https://kafka.apache.org/[Kafka client library]. Note that you need to use a version of the Kafka client library matching the Kafka server used. +This appender requires the https://kafka.apache.org/[Kafka client library]. +Note that you need to use a version of the Kafka client library matching the Kafka server used. _Note:_ Make sure to not let `org.apache.kafka` log to a Kafka appender on DEBUG level, since that will cause recursive logging: @@ -1718,44 +1673,28 @@ _Note:_ Make sure to not let `org.apache.kafka` log to a Kafka appender on DEBUG ---- - [#MemoryMappedFileAppender] == MemoryMappedFileAppender -_New since 2.1. Be aware that this is a new addition, and although it -has been tested on several platforms, it does not have as much track -record as the other file appenders._ - -The MemoryMappedFileAppender maps a part of the specified file into -memory and writes log events to this memory, relying on the operating -system's virtual memory manager to synchronize the changes to the -storage device. The main benefit of using memory-mapped files is I/O -performance. Instead of making system calls to write to disk, this -appender can simply change the program's local memory, which is orders -of magnitude faster. Also, in most operating systems the memory region -mapped is the kernel's -http://en.wikipedia.org/wiki/Page_cache[page cache] (file cache), -meaning that no copies need to be created in user space. +_New since 2.1. Be aware that this is a new addition, and although it has been tested on several platforms, it does not have as much track record as the other file appenders._ + +The MemoryMappedFileAppender maps a part of the specified file into memory and writes log events to this memory, relying on the operating system's virtual memory manager to synchronize the changes to the storage device. +The main benefit of using memory-mapped files is I/O performance. +Instead of making system calls to write to disk, this appender can simply change the program's local memory, which is orders of magnitude faster. +Also, in most operating systems the memory region mapped is the kernel's +http://en.wikipedia.org/wiki/Page_cache[page cache] (file cache), meaning that no copies need to be created in user space. // TODO: // performance tests that compare performance of this appender to // RandomAccessFileAppender and FileAppender.) -There is some overhead with mapping a file region into memory, -especially very large regions (half a gigabyte or more). The default -region size is 32 MB, which should strike a reasonable balance between -the frequency and the duration of remap operations. +There is some overhead with mapping a file region into memory, especially very large regions (half a gigabyte or more). +The default region size is 32 MB, which should strike a reasonable balance between the frequency and the duration of remap operations. // (TODO: performance test remapping various sizes.) -Similar to the FileAppender and the RandomAccessFileAppender, -MemoryMappedFileAppender uses a MemoryMappedFileManager to actually -perform the file I/O. While MemoryMappedFileAppender from different -Configurations cannot be shared, the MemoryMappedFileManagers can be if -the manager is accessible. For example, two web applications in a -servlet container can have its own configuration and safely write to -the same file if Log4j is in a ClassLoader that is common to both of -them. +Similar to the FileAppender and the RandomAccessFileAppender, MemoryMappedFileAppender uses a MemoryMappedFileManager to actually perform the file I/O. While MemoryMappedFileAppender from different Configurations cannot be shared, the MemoryMappedFileManagers can be if the manager is accessible. +For example, two web applications in a servlet container can have its own configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. .MemoryMappedFileAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -1832,10 +1771,8 @@ Here is a sample MemoryMappedFile configuration: [#NoSQLAppender] == NoSQLAppender -The NoSQLAppender writes log events to a NoSQL database using an -internal lightweight provider interface. Provider implementations -currently exist for MongoDB, and writing a custom -provider is quite simple. +The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface. +Provider implementations currently exist for MongoDB, and writing a custom provider is quite simple. .NoSQLAppender Parameters [cols="20%,20%,60%",options="header",] @@ -1861,17 +1798,12 @@ NoSQLObject>> |_Required._ The NoSQL provider that provides connections to the chosen NoSQL database. |======================================================================= -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. -We recommend you review the source code for the MongoDB -providers as a guide for creating your provider. +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. +We recommend you review the source code for the MongoDB providers as a guide for creating your provider. -The following example demonstrates how log events are persisted in NoSQL -databases if represented in a JSON format: +The following example demonstrates how log events are persisted in NoSQL databases if represented in a JSON format: [source,json] ---- @@ -1937,22 +1869,22 @@ Starting with Log4 2.11.0, we provide the following MongoDB modules: * Added in 2.14.0, deprecated in 2.24.0: `log4j-mongodb4` defines the configuration element link:#NoSQLAppenderMongoDB4[`MongoDb4`] matching the MongoDB Driver version 4. * Added in 2.24.0: `log4j-mongodb` defines the configuration element -link:#NoSQLAppenderMongoDBCurrent[`MongoDb`] matching the current MongoDB Driver (version 5). This module tracks the current MongoDB Driver. +link:#NoSQLAppenderMongoDBCurrent[`MongoDb`] matching the current MongoDB Driver (version 5). +This module tracks the current MongoDB Driver. [#NoSQLAppenderMongoDBCurrent] == NoSQL Appender for MongoDB This section details specializations of the -link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the -current MongoDB driver (version 5). The NoSQLAppender Appender writes log events -to a NoSQL database using an internal lightweight provider interface. +link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the current MongoDB driver (version 5). +The NoSQLAppender Appender writes log events to a NoSQL database using an internal lightweight provider interface. .MongoDB Provider Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|connection |String |_Required._ The MongoDB -http://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] +|connection |String |_Required._ The MongoDB +http://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] in the format `mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]]`. |capped |boolean |Enable support for @@ -1967,8 +1899,7 @@ collection documentation linked above for more information. This appender is xref:manual/messages.adoc#MapMessage[MapMessage]-aware. -Here are a few sample configurations for the NoSQLAppender and MongoDB4 -provider: +Here are a few sample configurations for the NoSQLAppender and MongoDB4 provider: [source,xml] ---- @@ -2036,16 +1967,14 @@ You can define additional fields to log using KeyValuePair elements, for example The `log4j-mongodb4` module is deprecated in favor of link:#NoSQLAppenderMongoDBCurrent[NoSQLAppender for MongoDB]. This section details specializations of the -link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the -MongoDB driver version 4. The NoSQLAppender Appender writes log events -to a NoSQL database using an internal lightweight provider interface. +link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the MongoDB driver version 4. The NoSQLAppender Appender writes log events to a NoSQL database using an internal lightweight provider interface. .MongoDB Provider Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|connection |String |_Required._ The MongoDB -http://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] +|connection |String |_Required._ The MongoDB +http://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html?is-external=true"[connection string] in the format `mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]]`. |capped |boolean |Enable support for @@ -2060,8 +1989,7 @@ collection documentation linked above for more information. This appender is xref:manual/messages.adoc#MapMessage[MapMessage]-aware. -Here are a few sample configurations for the NoSQLAppender and MongoDB4 -provider: +Here are a few sample configurations for the NoSQLAppender and MongoDB4 provider: [source,xml] ---- @@ -2126,7 +2054,8 @@ You can define additional fields to log using KeyValuePair elements, for example [[NoSQLAppenderApacheCouchDB]] == NoSQLAppender for Apache CouchDB -This section details specializations of the link:#NoSQLAppender[NoSQLAppender] provider for CouchDB. The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface. +This section details specializations of the link:#NoSQLAppender[NoSQLAppender] provider for CouchDB. +The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface. [width="100%",options="header"] |=== @@ -2185,35 +2114,24 @@ Here are a few sample configurations for the NoSQLAppender and CouchDB provider: ---- - [#OutputStreamAppender] == OutputStreamAppender -The OutputStreamAppender provides the base for many of the other -Appenders such as the File and Socket appenders that write the event to -an Output Stream. It cannot be directly configured. Support for -immediateFlush and buffering is provided by the OutputStreamAppender. -The OutputStreamAppender uses an OutputStreamManager to handle the -actual I/O, allowing the stream to be shared by Appenders in multiple -configurations. +The OutputStreamAppender provides the base for many of the other Appenders such as the File and Socket appenders that write the event to an Output Stream. +It cannot be directly configured. +Support for immediateFlush and buffering is provided by the OutputStreamAppender. +The OutputStreamAppender uses an OutputStreamManager to handle the actual I/O, allowing the stream to be shared by Appenders in multiple configurations. [#RandomAccessFileAppender] == RandomAccessFileAppender The RandomAccessFileAppender is similar to the standard -link:#FileAppender[FileAppender] except it is always buffered (this -cannot be switched off) and internally it uses a -`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. We -saw a 20-200% performance improvement compared to FileAppender with -"bufferedIO=true" in our -xref:manual/performance.adoc#whichAppender[measurements]. Similar to the -FileAppender, RandomAccessFileAppender uses a RandomAccessFileManager to -perform the file I/O. While RandomAccessFileAppender from -different Configurations cannot be shared, the RandomAccessFileManagers -can be if the Manager is accessible. For example, two web applications -in a servlet container can have their configuration and safely write -to the same file if Log4j is in a ClassLoader that is common to both of -them. +link:#FileAppender[FileAppender] except it is always buffered (this cannot be switched off) and internally it uses a +`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. +We saw a 20-200% performance improvement compared to FileAppender with "bufferedIO=true" in our +xref:manual/performance.adoc#whichAppender[measurements]. +Similar to the FileAppender, RandomAccessFileAppender uses a RandomAccessFileManager to perform the file I/O. While RandomAccessFileAppender from different Configurations cannot be shared, the RandomAccessFileManagers can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. .RandomAccessFileAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -2287,12 +2205,10 @@ Here is a sample RandomAccessFile configuration: [#RewriteAppender] == RewriteAppender -The RewriteAppender allows the LogEvent to be manipulated before it is -processed by another Appender. This can be used to mask sensitive -information such as passwords or to inject information into each event. -The RewriteAppender must be configured with a RewritePolicy. The -RewriteAppender should be configured after any Appenders it references -to allow it to shut down properly. +The RewriteAppender allows the LogEvent to be manipulated before it is processed by another Appender. +This can be used to mask sensitive information such as passwords or to inject information into each event. +The RewriteAppender must be configured with a RewritePolicy. +The RewriteAppender should be configured after any Appenders it references to allow it to shut down properly. .RewriteAppender Parameters [cols="20%,20%,60%",options="header",] @@ -2321,16 +2237,13 @@ Appender in a link:#FailoverAppender[FailoverAppender]. [#RewritePolicy] === RewritePolicy -RewritePolicy is an interface that allows implementations to inspect and -possibly modify LogEvents before they are passed to Appender. -RewritePolicy declares a single method named rewrite that must be -implemented. The method is passed the LogEvent and can return the same -event or create a new one. +RewritePolicy is an interface that allows implementations to inspect and possibly modify LogEvents before they are passed to Appender. +RewritePolicy declares a single method named rewrite that must be implemented. +The method is passed the LogEvent and can return the same event or create a new one. ==== MapRewritePolicy -MapRewritePolicy will evaluate LogEvents that contain a MapMessage and -will add or update elements of the Map. +MapRewritePolicy will evaluate LogEvents that contain a MapMessage and will add or update elements of the Map. [cols="20%,20%,60%",options="header",] |================================================================ @@ -2339,8 +2252,7 @@ will add or update elements of the Map. |keyValuePair |KeyValuePair[] |An array of keys and their values. |================================================================ -The following configuration shows a RewriteAppender configured to add a -product key and its value to the MapMessage.: +The following configuration shows a RewriteAppender configured to add a product key and its value to the MapMessage.: [source,xml] ---- @@ -2367,11 +2279,9 @@ product key and its value to the MapMessage.: ==== PropertiesRewritePolicy -PropertiesRewritePolicy will add properties configured on the policy to -the ThreadContext Map being logged. 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. +PropertiesRewritePolicy will add properties configured on the policy to the ThreadContext Map being logged. +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",] |======================================================================= @@ -2380,8 +2290,7 @@ when the event is logged. keys and values to be added to the ThreadContext Map. |======================================================================= -The following configuration shows a RewriteAppender configured to add a -product key and its value to the MapMessage: +The following configuration shows a RewriteAppender configured to add a product key and its value to the MapMessage: [source,xml] ---- @@ -2409,11 +2318,9 @@ product key and its value to the MapMessage: ==== LoggerNameLevelRewritePolicy -You can use this policy to make loggers in third-party code less chatty -by changing event levels. The LoggerNameLevelRewritePolicy will rewrite -log event levels for a given logger name prefix. You configure a -LoggerNameLevelRewritePolicy with a logger name prefix and a pair of -levels, where a pair defines a source level and a target level. +You can use this policy to make loggers in third-party code less chatty by changing event levels. +The LoggerNameLevelRewritePolicy will rewrite log event levels for a given logger name prefix. +You configure a LoggerNameLevelRewritePolicy with a logger name prefix and a pair of levels, where a pair defines a source level and a target level. [cols="20%,20%,60%",options="header",] |======================================================================= @@ -2425,9 +2332,7 @@ logger name. is a source level, each value a target level. |======================================================================= -The following configuration shows a RewriteAppender configured to map -level INFO to DEBUG and level WARN to INFO for all loggers that start -with `com.foo.bar`. +The following configuration shows a RewriteAppender configured to map level INFO to DEBUG and level WARN to INFO for all loggers that start with `com.foo.bar`. [source,xml] ---- @@ -2456,33 +2361,26 @@ with `com.foo.bar`. [id=rollingfileappender] == [[RollingFileAppender]] RollingFileAppender -The RollingFileAppender is an OutputStreamAppender that writes to the -file named in the fileName parameter and rolls the file over according to -the `TriggeringPolicy` and the `RolloverPolicy`. The `RollingFileAppender` -uses a `RollingFileManager` (which extends `OutputStreamManager`) to -perform the file I/O and perform the rollover. -While `RolloverFileAppenders` from different Configurations cannot be shared, -the `RollingFileManagers` can be if the Manager is accessible. -For example, two web applications in a servlet container can have their -configuration and safely write to the same file if Log4j is in a +The RollingFileAppender is an OutputStreamAppender that writes to the file named in the fileName parameter and rolls the file over according to the `TriggeringPolicy` and the `RolloverPolicy`. +The `RollingFileAppender` +uses a `RollingFileManager` (which extends `OutputStreamManager`) to perform the file I/O and perform the rollover. +While `RolloverFileAppenders` from different Configurations cannot be shared, the `RollingFileManagers` can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a `ClassLoader` that is common to both of them. A RollingFileAppender requires a link:#TriggeringPolicies[TriggeringPolicy] and a -link:#RolloverStrategies[RolloverStrategy]. The triggering policy -determines if a rollover should be performed while the `RolloverStrategy` -defines how the rollover should be done. If no `RolloverStrategy` is -configured, `RollingFileAppender` will use the -link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. Since log4j-2.5, -a link:#CustomDeleteOnRollover[custom delete action] can be configured -in the DefaultRolloverStrategy to run at rollover. Since 2.8 if no file -name is configured then -link:#DirectWriteRolloverStrategy[DirectWriteRolloverStrategy] will be -used instead of DefaultRolloverStrategy. Since log4j-2.9, a +link:#RolloverStrategies[RolloverStrategy]. +The triggering policy determines if a rollover should be performed while the `RolloverStrategy` +defines how the rollover should be done. +If no `RolloverStrategy` is configured, `RollingFileAppender` will use the +link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. +Since log4j-2.5, a link:#CustomDeleteOnRollover[custom delete action] can be configured in the DefaultRolloverStrategy to run at rollover. +Since 2.8 if no file name is configured then +link:#DirectWriteRolloverStrategy[DirectWriteRolloverStrategy] will be used instead of DefaultRolloverStrategy. +Since log4j-2.9, a link:#CustomPosixViewAttributeOnRollover[custom POSIX file attribute -view action] can be configured in the DefaultRolloverStrategy to run at -rollover, if not defined, the inherited POSIX file attribute view from the -RollingFileAppender will be applied. +view action] can be configured in the DefaultRolloverStrategy to run at rollover, if not defined, the inherited POSIX file attribute view from the RollingFileAppender will be applied. File locking is not supported by the RollingFileAppender. @@ -2601,14 +2499,11 @@ file attribute view. === Composite Triggering Policy -The `CompositeTriggeringPolicy` combines multiple triggering policies -and returns true if any of the configured policies return true. The -`CompositeTriggeringPolicy` is configured simply by wrapping other -policies in a `Policies` element. +The `CompositeTriggeringPolicy` combines multiple triggering policies and returns true if any of the configured policies return true. +The +`CompositeTriggeringPolicy` is configured simply by wrapping other policies in a `Policies` element. -For example, the following XML fragment defines policies that rollover -the log when the JVM starts when the log size reaches twenty megabytes, -and when the current date no longer matches the log's start date. +For example, the following XML fragment defines policies that rollover the log when the JVM starts when the log size reaches twenty megabytes, and when the current date no longer matches the log's start date. [source,xml] ---- @@ -2621,11 +2516,9 @@ and when the current date no longer matches the log's start date. === Cron Triggering Policy -The `CronTriggeringPolicy` triggers rollover based on a cron expression. This policy -is controlled by a timer and is asynchronous in processing log events, so it is possible that log events -from the previous or next period may appear at the beginning or end of the log file. -The `filePattern` attribute of the Appender should contain a timestamp otherwise the target file will be -overwritten on each rollover. +The `CronTriggeringPolicy` triggers rollover based on a cron expression. +This policy is controlled by a timer and is asynchronous in processing log events, so it is possible that log events from the previous or next period may appear at the beginning or end of the log file. +The `filePattern` attribute of the Appender should contain a timestamp otherwise the target file will be overwritten on each rollover. .CronTriggeringPolicy Parameters [cols="20%,20%,60%",options="header",] @@ -2644,9 +2537,7 @@ and the current time the file will be immediately rolled over. === OnStartup Triggering Policy -The `OnStartupTriggeringPolicy` policy causes a rollover if the log file -is older than the current JVM's start time and the minimum file size is -met or exceeded. +The `OnStartupTriggeringPolicy` policy causes a rollover if the log file is older than the current JVM's start time and the minimum file size is met or exceeded. .OnStartupTriggeringPolicy Parameters [cols="20%,20%,60%",options="header",] @@ -2658,29 +2549,27 @@ default value is 1, which will prevent rolling over an empty file. |======================================================================= _Google App Engine note:_ + -When running in Google App Engine, the OnStartup policy causes a -rollover if the log file is older than _the time when Log4J -initialized_. (Google App Engine restricts access to certain classes so -Log4J cannot determine JVM start time with +When running in Google App Engine, the OnStartup policy causes a rollover if the log file is older than _the time when Log4J initialized_. +(Google App Engine restricts access to certain classes so Log4J cannot determine JVM start time with `java.lang.management.ManagementFactory.getRuntimeMXBean().getStartTime()` and falls back to Log4J initialization time instead.) === SizeBased Triggering Policy -The `SizeBasedTriggeringPolicy` causes a rollover once the file has reached the specified size. The size can be -specified in bytes, with the suffix KB, MB, GB, or TB for example `20MB`. -size. The size may also contain a fractional value such as `1.5 MB`. The size is evaluated -using the Java root Locale so a period must always be used for the fractional unit. +The `SizeBasedTriggeringPolicy` causes a rollover once the file has reached the specified size. +The size can be specified in bytes, with the suffix KB, MB, GB, or TB for example `20MB`. +size. +The size may also contain a fractional value such as `1.5 MB`. +The size is evaluated using the Java root Locale so a period must always be used for the fractional unit. When combined with a time-based triggering policy the file pattern must contain a `%i`. -Otherwise, the target file will be overwritten on every rollover as the SizeBased Triggering Policy will not cause the timestamp value in the file name to change. +Otherwise, the target file will be overwritten on every rollover as the SizeBased Triggering Policy will not cause the timestamp value in the file name to change. When used without a time-based triggering policy the SizeBased Triggering Policy will cause the timestamp value to change. === TimeBased Triggering Policy -The `TimeBasedTriggeringPolicy` causes a rollover once the date/time -pattern no longer applies to the active file. This policy accepts an -`interval` attribute which indicates how frequently the rollover should -occur based on the time pattern and a `modulate` boolean attribute. +The `TimeBasedTriggeringPolicy` causes a rollover once the date/time pattern no longer applies to the active file. +This policy accepts an +`interval` attribute which indicates how frequently the rollover should occur based on the time pattern and a `modulate` boolean attribute. .TimeBasedTriggeringPolicy Parameters [cols="20%,20%,60%",options="header",] @@ -2712,26 +2601,20 @@ load of doing so across time. Default Rollover Strategy -The default rollover strategy accepts both a date/time pattern and an -integer from the `filePattern` attribute specified on the -RollingFileAppender itself. If the date/time pattern is present it will -be replaced with the current date and time values. If the pattern -contains an integer it will be incremented on each rollover. If the -pattern contains both a date/time and integer in the pattern the integer -will be incremented until the result of the date/time pattern changes. -If the file pattern ends with ".gz", ".zip", ".bz2", ".deflate", -".pack200", or ".xz" the resulting archive will be compressed using the -compression scheme that matches the suffix. The formats bzip2, Deflate, -Pack200 and XZ require +The default rollover strategy accepts both a date/time pattern and an integer from the `filePattern` attribute specified on the RollingFileAppender itself. +If the date/time pattern is present it will be replaced with the current date and time values. +If the pattern contains an integer it will be incremented on each rollover. +If the pattern contains both a date/time and integer in the pattern the integer will be incremented until the result of the date/time pattern changes. +If the file pattern ends with ".gz", ".zip", ".bz2", ".deflate", ".pack200", or ".xz" the resulting archive will be compressed using the compression scheme that matches the suffix. +The formats bzip2, Deflate, Pack200 and XZ require http://commons.apache.org/proper/commons-compress/[Apache Commons -Compress]. In addition, XZ requires http://tukaani.org/xz/java.html[XZ -for Java]. The pattern may also contain lookup references that can be -resolved at runtime such as shown in the example below. +Compress]. +In addition, XZ requires http://tukaani.org/xz/java.html[XZ +for Java]. +The pattern may also contain lookup references that can be resolved at runtime such as shown in the example below. -The default rollover strategy supports three variations for incrementing -the counter. To illustrate how it works, suppose that the min attribute -is set to 1, the max attribute is set to 3, the file name is "foo.log", -and the file name pattern is "foo-%i.log". +The default rollover strategy supports three variations for incrementing the counter. +To illustrate how it works, suppose that the min attribute is set to 1, the max attribute is set to 3, the file name is "foo.log", and the file name pattern is "foo-%i.log". [cols="15%,15%,15%,55%",options="header",] |======================================================================= @@ -2756,9 +2639,7 @@ foo-1.log, foo-3.log is renamed to foo-2.log and foo.log is renamed to foo-3.log. A new foo.log file is created and starts being written to. |======================================================================= -By way of contrast, when the `fileIndex` attribute is set to "min" all -the other settings are the same the "fixed window" strategy will be -performed. +By way of contrast, when the `fileIndex` attribute is set to "min" all the other settings are the same the "fixed window" strategy will be performed. [cols="15%,15%,15%,55%",options="header",] |======================================================================= @@ -2785,9 +2666,7 @@ foo-1.log. A new foo.log file is created and starts being written to. |======================================================================= Finally, as of release 2.8, if the `fileIndex` attribute is set to `nomax` -then the min and max values will be ignored and file numbering will -increment by 1 and each rollover will have an incrementally higher value -with no maximum number of files. +then the min and max values will be ignored and file numbering will increment by 1 and each rollover will have an incrementally higher value with no maximum number of files. .DefaultRolloverStrategy Parameters [cols="20%,20%,60%",options="header",] @@ -2817,24 +2696,18 @@ archived log file during compression. DirectWrite Rollover Strategy -The DirectWriteRolloverStrategy causes log events to be written directly -to files represented by the file pattern. With this strategy file -renames are not performed. If the size-based triggering policy causes -multiple files to be written during the specified period they will -be numbered starting at one and continually incremented until a -time-based rollover occurs. +The DirectWriteRolloverStrategy causes log events to be written directly to files represented by the file pattern. +With this strategy file renames are not performed. +If the size-based triggering policy causes multiple files to be written during the specified period they will be numbered starting at one and continually incremented until a time-based rollover occurs. -Warning: If the file pattern has a suffix indicating compression should -take place the current file will not be compressed when the application -is shut down. Furthermore, if the time changes such that the file -pattern no longer matches the current file it will not be compressed at -startup either. +Warning: If the file pattern has a suffix indicating compression should take place the current file will not be compressed when the application is shut down. +Furthermore, if the time changes such that the file pattern no longer matches the current file it will not be compressed at startup either. .DirectWriteRolloverStrategy Parameters [cols="20%,20%,60%",options="header",] |======================================================================= |Parameter Name |Type |Description -|maxFiles |String |The maximum number of files to allow in the period matching +|maxFiles |String |The maximum number of files to allow in the period matching the file pattern. If the number of files is exceeded the oldest file will be deleted. If specified, the value must be greater than 1. If the value is less than zero or omitted then the number of @@ -2848,10 +2721,7 @@ ZIP files. archived log file during compression. |======================================================================= -Below is a sample configuration that uses a RollingFileAppender with -both the time and size-based triggering policies will create up to 7 -archives on the same day (1-7) that are stored in a directory based on -the current year and month, and will compress each archive using gzip: +Below is a sample configuration that uses a RollingFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip: [source,xml] ---- @@ -2877,8 +2747,7 @@ the current year and month, and will compress each archive using gzip: ---- -This second example shows a rollover strategy that will keep up to 20 -files before removing them. +This second example shows a rollover strategy that will keep up to 20 files before removing them. [source,xml] ---- @@ -2905,11 +2774,7 @@ files before removing them. ---- -Below is a sample configuration that uses a RollingFileAppender with -both the time and size-based triggering policies will create up to 7 -archives on the same day (1-7) that are stored in a directory based on -the current year and month, and will compress each archive using gzip -and will roll every 6 hours when the hour is divisible by 6: +Below is a sample configuration that uses a RollingFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every 6 hours when the hour is divisible by 6: [source,xml] ---- @@ -2935,10 +2800,8 @@ and will roll every 6 hours when the hour is divisible by 6: ---- -This sample configuration uses a RollingFileAppender with both the cron -and size-based triggering policies, and writes directly to an unlimited -number of archive files. The cron trigger causes a rollover every hour -while the file size is limited to 250MB: +This sample configuration uses a RollingFileAppender with both the cron and size-based triggering policies, and writes directly to an unlimited number of archive files. +The cron trigger causes a rollover every hour while the file size is limited to 250MB: [source,xml] ---- @@ -2963,8 +2826,7 @@ while the file size is limited to 250MB: ---- -This sample configuration is the same as the previous one but limits the -number of files saved each hour to 10: +This sample configuration is the same as the previous one but limits the number of files saved each hour to 10: [source,xml] ---- @@ -2995,16 +2857,11 @@ number of files saved each hour to 10: Log Archive Retention Policy: Delete on Rollover -Log4j-2.5 introduces a `Delete` action that gives users more control -over what files are deleted at rollover time than what was possible with -the DefaultRolloverStrategy `max` attribute. The Delete action lets -users configure one or more conditions that select the files to delete -relative to a base directory. +Log4j-2.5 introduces a `Delete` action that gives users more control over what files are deleted at rollover time than what was possible with the DefaultRolloverStrategy `max` attribute. +The Delete action lets users configure one or more conditions that select the files to delete relative to a base directory. -Note that it is possible to delete any file, not just rolled-over log -files, so use this action with care! With the `testMode` parameter you -can test your configuration without accidentally deleting the wrong -files. +Note that it is possible to delete any file, not just rolled-over log files, so use this action with care! +With the `testMode` parameter you can test your configuration without accidentally deleting the wrong files. .Delete Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -3162,11 +3019,9 @@ conditions are only evaluated if the outer condition accepts a file (if the threshold accumulated file size has been exceeded). |======================================================================= -Below is a sample configuration that uses a RollingFileAppender with the -cron triggering policy configured to trigger every day at midnight. +Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy configured to trigger every day at midnight. Archives are stored in a directory based on the current year and month. -All files under the base directory that match the "*/app-*.log.gz" glob -and are 60 days old or older are deleted at rollover time. +All files under the base directory that match the "*/app-*.log.gz" glob and are 60 days old or older are deleted at rollover time. [source,xml] ---- @@ -3196,14 +3051,8 @@ and are 60 days old or older are deleted at rollover time. ---- -Below is a sample configuration that uses a RollingFileAppender with -both the time and size-based triggering policies will create up to 100 -archives on the same day (1-100) that are stored in a directory based on -the current year and month, and will compress each archive using gzip -and will roll every hour. During every rollover, this configuration will -delete files that match "*/app-*.log.gz" and are 30 days old or older, -but keep the most recent 100 GB or the most recent 10 files, whichever -comes first. +Below is a sample configuration that uses a RollingFileAppender with both the time and size-based triggering policies will create up to 100 archives on the same day (1-100) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every hour. +During every rollover, this configuration will delete files that match "*/app-*.log.gz" and are 30 days old or older, but keep the most recent 100 GB or the most recent 10 files, whichever comes first. [source,xml] ---- @@ -3288,12 +3137,10 @@ variables. |? |String |Any properties declared in the configuration. |======================================================================= -Below is a sample configuration that uses a RollingFileAppender with the -cron triggering policy configured to trigger every day at midnight. +Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy configured to trigger every day at midnight. Archives are stored in a directory based on the current year and month. -The script returns a list of rolled-over files under the base directory -dated Friday the 13th. The Delete action will delete all files returned -by the script. +The script returns a list of rolled-over files under the base directory dated Friday the 13th. +The Delete action will delete all files returned by the script. [source,xml] ---- @@ -3356,13 +3203,10 @@ by the script. [#CustomPosixViewAttributeOnRollover] == CustomPosixViewAttributeOnRollover -Log Archive File Attribute View Policy: Custom file attribute on -Rollover +Log Archive File Attribute View Policy: Custom file attribute on Rollover -Log4j-2.9 introduces a `PosixViewAttribute` action that gives users more -control over which file attribute permissions, owner and group should be -applied. The PosixViewAttribute action lets users configure one or more -conditions that select the eligible files relative to a base directory. +Log4j-2.9 introduces a `PosixViewAttribute` action that gives users more control over which file attribute permissions, owner and group should be applied. +The PosixViewAttribute action lets users configure one or more conditions that select the eligible files relative to a base directory. .PosixViewAttribute Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -3416,9 +3260,7 @@ file attribute view. |======================================================================= -Below is a sample configuration that uses a RollingFileAppender and -defines different POSIX file attribute views for current and rolled log -files. +Below is a sample configuration that uses a RollingFileAppender and defines different POSIX file attribute views for current and rolled log files. [source,xml] ---- @@ -3454,32 +3296,24 @@ files. == RollingRandomAccessFileAppender The RollingRandomAccessFileAppender is similar to the standard -link:#RollingFileAppender[RollingFileAppender] except it is always -buffered (this cannot be switched off) and internally it uses a -`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. We -saw a 20-200% performance improvement compared to RollingFileAppender -with "bufferedIO=true" in our -xref:manual/performance.adoc#whichAppender[measurements]. The -`RollingRandomAccessFileAppender` writes to the file named in the fileName -parameter and rolls the file over according to the TriggeringPolicy and the -RolloverPolicy. Similar to the RollingFileAppender, -RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager to -perform the file I/O and perform the rollover. While -RollingRandomAccessFileAppender from different Configurations cannot be -shared, the RollingRandomAccessFileManagers can be if the Manager is -accessible. For example, two web applications in a servlet container can -have their configuration and safely write to the same file if Log4j -is in a ClassLoader that is common to both of them. +link:#RollingFileAppender[RollingFileAppender] except it is always buffered (this cannot be switched off) and internally it uses a +`ByteBuffer + RandomAccessFile` instead of a `BufferedOutputStream`. +We saw a 20-200% performance improvement compared to RollingFileAppender with "bufferedIO=true" in our +xref:manual/performance.adoc#whichAppender[measurements]. +The +`RollingRandomAccessFileAppender` writes to the file named in the fileName parameter and rolls the file over according to the TriggeringPolicy and the RolloverPolicy. +Similar to the RollingFileAppender, RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager to perform the file I/O and perform the rollover. +While RollingRandomAccessFileAppender from different Configurations cannot be shared, the RollingRandomAccessFileManagers can be if the Manager is accessible. +For example, two web applications in a servlet container can have their configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of them. A RollingRandomAccessFileAppender requires a link:#TriggeringPolicies[TriggeringPolicy] and a -link:#RolloverStrategies[RolloverStrategy]. The triggering policy -determines if a rollover should be performed while the `RolloverStrategy` -defines how the rollover should be done. If no RolloverStrategy is -configured, RollingRandomAccessFileAppender will use the -link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. Since log4j-2.5, -a link:#CustomDeleteOnRollover[custom delete action] can be configured -in the DefaultRolloverStrategy to run at rollover. +link:#RolloverStrategies[RolloverStrategy]. +The triggering policy determines if a rollover should be performed while the `RolloverStrategy` +defines how the rollover should be done. +If no RolloverStrategy is configured, RollingRandomAccessFileAppender will use the +link:#DefaultRolloverStrategy[DefaultRolloverStrategy]. +Since log4j-2.5, a link:#CustomDeleteOnRollover[custom delete action] can be configured in the DefaultRolloverStrategy to run at rollover. File locking is not supported by the RollingRandomAccessFileAppender. @@ -3580,11 +3414,7 @@ See xref:#TriggeringPolicies[RollingFileAppender Triggering Policies]. See link:#RolloverStrategies[RollingFileAppender Rollover Strategies]. -Below is a sample configuration that uses a -RollingRandomAccessFileAppender with both the time and size-based -triggering policies will create up to 7 archives on the same day (1-7) -that are stored in a directory based on the current year and month, and -will compress each archive using gzip: +Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip: [source,xml] ---- @@ -3610,8 +3440,7 @@ will compress each archive using gzip: ---- -This second example shows a rollover strategy that will keep up to 20 -files before removing them. +This second example shows a rollover strategy that will keep up to 20 files before removing them. [source,xml] ---- @@ -3638,12 +3467,7 @@ files before removing them. ---- -Below is a sample configuration that uses a -RollingRandomAccessFileAppender with both the time and size-based -triggering policies will create up to 7 archives on the same day (1-7) -that are stored in a directory based on the current year and month, and -will compress each archive using gzip and will roll every 6 hours when -the hour is divisible by 6: +Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time and size-based triggering policies will create up to 7 archives on the same day (1-7) that are stored in a directory based on the current year and month, and will compress each archive using gzip and will roll every 6 hours when the hour is divisible by 6: [source,xml] ---- @@ -3672,15 +3496,11 @@ the hour is divisible by 6: [#RoutingAppender] == RoutingAppender -The `RoutingAppender` evaluates LogEvents and then routes them to a -subordinate Appender. The target Appender may be an appender previously -configured and may be referenced by its name or the Appender can be -dynamically created as needed. The `RoutingAppender` should be configured -after any Appenders it references to allow it to shut down properly. +The `RoutingAppender` evaluates LogEvents and then routes them to a subordinate Appender. +The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. +The `RoutingAppender` should be configured after any Appenders it references to allow it to shut down properly. -You can also configure a `RoutingAppender` with scripts: you can run a -script when the appender starts and when a route is chosen for an log -event. +You can also configure a `RoutingAppender` with scripts: you can run a script when the appender starts and when a route is chosen for an log event. .RoutingAppender Parameters [width="100%",cols="20%,20%,60%",options="header",] @@ -3707,12 +3527,12 @@ This script is passed the following variables: .RoutingAppender Script Parameters [cols="20%,20%,60%",options="header",] |======================================================================= -|Parameter Name |Type |Description -|configuration |Configuration |The active Configuration. -|staticVariables |Map |A Map shared between all script invocations for -this appender instance. This is the same map passed to the Routes -Script. +|Parameter Name |Type |Description |configuration |Configuration |The active Configuration. + +|staticVariables |Map |A Map shared between all script invocations for this appender instance. +This is the same map passed to the Routes Script. + |======================================================================= |ignoreExceptions |boolean |The default is `true`, causing exceptions @@ -3722,10 +3542,8 @@ caller, instead. You must set this to `false` when wrapping this Appender in a link:#FailoverAppender[FailoverAppender]. |======================================================================= -In this example, the script causes the "ServiceWindows" route to be the -default route on Windows and "ServiceOther" on all other operating -systems. Note that the List Appender is one of our test appenders, any -appender can be used, it is only used as a shorthand. +In this example, the script causes the "ServiceWindows" route to be the default route on Windows and "ServiceOther" on all other operating systems. +Note that the List Appender is one of our test appenders, any appender can be used, it is only used as a shorthand. [source,xml] ---- @@ -3757,26 +3575,24 @@ appender can be used, it is only used as a shorthand. [#Routes] === Routes -The `Routes` element accepts a single attribute named "pattern". The -pattern is evaluated against all the registered Lookups and the result -is used to select a `Route`. Each `Route` may be configured with a key. If -the key matches the result of evaluating the pattern then that `Route` -will be selected. If no key is specified on a `Route` then that `Route` is -the default. Only one `Route` can be configured as the default. +The `Routes` element accepts a single attribute named "pattern". +The pattern is evaluated against all the registered Lookups and the result is used to select a `Route`. +Each `Route` may be configured with a key. +If the key matches the result of evaluating the pattern then that `Route` +will be selected. +If no key is specified on a `Route` then that `Route` is the default. +Only one `Route` can be configured as the default. -The `Routes` element may contain a `Script` child element. If specified, the -`Script` is run for each log event and returns the String Route key to -use. +The `Routes` element may contain a `Script` child element. +If specified, the +`Script` is run for each log event and returns the String Route key to use. -You must specify either the pattern attribute or the `Script` element, but -not both. +You must specify either the pattern attribute or the `Script` element, but not both. -Each `Route` must reference an `Appender`. If the `Route` contains a ref -attribute then the `Route` will reference an `Appender` that was defined in -the configuration. 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`. +Each `Route` must reference an `Appender`. +If the `Route` contains a ref attribute then the `Route` will reference an `Appender` that was defined in the configuration. +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`. This script is passed the following variables: @@ -3793,8 +3609,7 @@ Script. |logEvent |LogEvent |The log event. |======================================================================= -In this example, the script runs for each log event and picks a route -based on the presence of a Marker named "AUDIT". +In this example, the script runs for each log event and picks a route based on the presence of a Marker named "AUDIT". [source,xml] ---- @@ -3845,21 +3660,12 @@ based on the presence of a Marker named "AUDIT". [#Purge] === Purge Policy -The RoutingAppender can be configured with a PurgePolicy whose purpose -is to stop and remove dormant Appenders that have been dynamically -created by the RoutingAppender. Log4j currently provides the -IdlePurgePolicy is the only PurgePolicy available for cleaning up the -Appenders. The IdlePurgePolicy accepts 2 attributes; timeToLive, which -is the number of timeUnits the Appender should survive without having -any events sent to it, and timeUnit, the String representation of -java.util.concurrent.TimeUnit which is used with the timeToLive -attribute. +The RoutingAppender can be configured with a PurgePolicy whose purpose is to stop and remove dormant Appenders that have been dynamically created by the RoutingAppender. +Log4j currently provides the IdlePurgePolicy is the only PurgePolicy available for cleaning up the Appenders. +The IdlePurgePolicy accepts 2 attributes; timeToLive, which is the number of timeUnits the Appender should survive without having any events sent to it, and timeUnit, the String representation of java.util.concurrent.TimeUnit which is used with the timeToLive attribute. -Below is a sample configuration that uses a RoutingAppender to route all -Audit events to a FlumeAppender and all other events will be routed to a -RollingFileAppender captures only the specific event type. Note -that the AuditAppender was predefined while the RollingFileAppenders are -created as needed. +Below is a sample configuration that uses a RoutingAppender to route all Audit events to a FlumeAppender and all other events will be routed to a RollingFileAppender captures only the specific event type. +Note that the AuditAppender was predefined while the RollingFileAppenders are created as needed. [source,xml] ---- @@ -3900,9 +3706,15 @@ created as needed. Sends an e-mail when a specific logging event occurs, typically on errors or fatal errors. -The number of logging events delivered in this e-mail depends on the value of the `BufferSize` option. The `SMTPAppender` keeps only the last `BufferSize` logging events in its cyclic buffer. This keeps memory requirements at a reasonable level while still delivering useful application context. All events in the buffer are included in the email. The buffer will contain the most recent events of level TRACE to WARN preceding the event that triggered the email. +The number of logging events delivered in this e-mail depends on the value of the `BufferSize` option. +The `SMTPAppender` keeps only the last `BufferSize` logging events in its cyclic buffer. +This keeps memory requirements at a reasonable level while still delivering useful application context. +All events in the buffer are included in the email. +The buffer will contain the most recent events of level TRACE to WARN preceding the event that triggered the email. -The default behavior is to trigger sending an email whenever an ERROR or higher severity event is logged and to format it as HTML. The circumstances of when the email is sent can be controlled by setting one or more filters on the Appender. As with other Appenders, the formatting can be controlled by specifying a Layout for the Appender. +The default behavior is to trigger sending an email whenever an ERROR or higher severity event is logged and to format it as HTML. +The circumstances of when the email is sent can be controlled by setting one or more filters on the Appender. +As with other Appenders, the formatting can be controlled by specifying a Layout for the Appender. [width="100%",options="header"] |=== @@ -3998,22 +3810,19 @@ The default behavior is to trigger sending an email whenever an ERROR or higher ---- - [#ScriptAppenderSelector] == ScriptAppenderSelector -When the configuration is built, the `ScriptAppenderSelector` appender -calls a `ScriptPlugin` to compute an appender name. Log4j then creates one of -the appender named listed under `AppenderSet` using the name of the -`ScriptAppenderSelector`. After configuration, Log4j ignores the -`ScriptAppenderSelector`. Log4j only builds the one selected appender -from the configuration tree and ignores other `AppenderSet` child -nodes. +When the configuration is built, the `ScriptAppenderSelector` appender calls a `ScriptPlugin` to compute an appender name. +Log4j then creates one of the appender named listed under `AppenderSet` using the name of the +`ScriptAppenderSelector`. +After configuration, Log4j ignores the +`ScriptAppenderSelector`. +Log4j only builds the one selected appender from the configuration tree and ignores other `AppenderSet` child nodes. -In the following example, the script returns the name "List2". The -appender name is recorded under the name of the -`ScriptAppenderSelector`, not the name of the selected appender, in this -example, "SelectIt". +In the following example, the script returns the name "List2". +The appender name is recorded under the name of the +`ScriptAppenderSelector`, not the name of the selected appender, in this example, "SelectIt". [source,xml] ---- @@ -4040,16 +3849,12 @@ example, "SelectIt". [#SocketAppender] == SocketAppender -The `SocketAppender` is an OutputStreamAppender that writes its output -to a remote destination specified by a host and port. The data can be -sent over either TCP or UDP and can be sent in any format. You can -optionally secure communication with link:#SSL[SSL]. Note that the TCP and SSL -variants write to the socket as a stream and do not expect a response from -the target destination. Due to limitations in the TCP protocol that -means that when the target server closes its connection some log events -may continue to appear to succeed until a closed connection exception -is raised, causing those events to be lost. If guaranteed delivery is -required a protocol that requires acknowledgments must be used. +The `SocketAppender` is an OutputStreamAppender that writes its output to a remote destination specified by a host and port. +The data can be sent over either TCP or UDP and can be sent in any format. +You can optionally secure communication with link:#SSL[SSL]. +Note that the TCP and SSL variants write to the socket as a stream and do not expect a response from the target destination. +Due to limitations in the TCP protocol that means that when the target server closes its connection some log events may continue to appear to succeed until a closed connection exception is raised, causing those events to be lost. +If guaranteed delivery is required a protocol that requires acknowledgments must be used. .`SocketAppender` Parameters [cols="20%,20%,60%",options="header",] @@ -4154,9 +3959,8 @@ This is a secured link:#SSL[SSL] configuration: [#SSL] == SSL -Several appenders can be configured to use either a plain network -connection or a Secure Socket Layer (SSL) connection. This section -documents the parameters available for SSL configuration. +Several appenders can be configured to use either a plain network connection or a Secure Socket Layer (SSL) connection. +This section documents the parameters available for SSL configuration. .SSL Configuration Parameters [cols="20%,20%,60%",options="header",] @@ -4178,8 +3982,7 @@ counterparty. Determines whether the remote authentication credentials [#KeyStore] === KeyStore -The Keystore is meant to contain your private keys and certificates, and -determines which authentication credentials to send to the remote host. +The Keystore is meant to contain your private keys and certificates, and determines which authentication credentials to send to the remote host. .KeyStore Configuration Parameters [cols="20%,20%,60%",options="header",] @@ -4212,14 +4015,10 @@ algorithms]. [#TrustStore] === TrustStore -The trust store is meant to contain the CA certificates you are willing -to trust when a remote party presents its certificate. Determines -whether the remote authentication credentials (and thus the connection) -should be trusted. +The trust store is meant to contain the CA certificates you are willing to trust when a remote party presents its certificate. +Determines whether the remote authentication credentials (and thus the connection) should be trusted. -In some cases, they can be the same store, although it is often -better practice to use distinct stores (especially when they are -file-based). +In some cases, they can be the same store, although it is often better practice to use distinct stores (especially when they are file-based). .TrustStore Configuration Parameters [cols="20%,20%,60%",options="header",] @@ -4263,10 +4062,8 @@ algorithms]. [#SyslogAppender] == SyslogAppender -The `SyslogAppender` is a `SocketAppender` that writes its output to a -remote destination specified by a host and port in a format that -conforms with either the BSD Syslog format or the RFC 5424 format. The -data can be sent over either TCP or UDP. +The `SyslogAppender` is a `SocketAppender` that writes its output to a remote destination specified by a host and port in a format that conforms with either the BSD Syslog format or the RFC 5424 format. +The data can be sent over either TCP or UDP. .`SyslogAppender` Parameters [cols="20%,20%,60%",options="header",] @@ -4300,7 +4097,7 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be specified as upper or lowercase characters. -|format |String |If set to "RFC5424" the data will be formatted by RFC 5424. +|format |String |If set to "RFC5424" the data will be formatted by RFC 5424. Otherwise, it will be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be 1024 bytes or shorter the SyslogLayout does not truncate them. The @@ -4355,7 +4152,7 @@ attribute. This attribute only applies to RFC 5424 syslog records. present in the MDC. If a key is not present a LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records. -|mdcPrefix |String |A string that should be prepended to each MDC key +|mdcPrefix |String |A string that should be prepended to each MDC key to distinguish it from event attributes. The default string is `mdc:`. This attribute only applies to RFC 5424 syslog records. @@ -4382,8 +4179,7 @@ fails then an exception will be thrown (which can be caught by the application if `ignoreExceptions` is set to `false`). |======================================================================= -A sample syslogAppender configuration that is configured with two -`SyslogAppender`s, one using the BSD format and one using RFC 5424. +A sample syslogAppender configuration that is configured with two `SyslogAppender`s, one using the BSD format and one using RFC 5424. [source,xml] ---- @@ -4407,9 +4203,7 @@ A sample syslogAppender configuration that is configured with two ---- -For link:#SSL[SSL] this appender writes its output to a remote -destination specified by a host and port over SSL in a format that -conforms with either the BSD Syslog format or the RFC 5424 format. +For link:#SSL[SSL] this appender writes its output to a remote destination specified by a host and port over SSL in a format that conforms with either the BSD Syslog format or the RFC 5424 format. [source,xml] ---- @@ -4456,7 +4250,8 @@ This is a simple JeroMQ configuration: ---- -The table below describes all options. Please consult the JeroMQ and ZeroMQ documentation for details. +The table below describes all options. +Please consult the JeroMQ and ZeroMQ documentation for details. [width="100%",options="header"] |=== From a786e62d717afffd6f00ac81dbf6debfafab34ed Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 May 2024 17:36:28 +0200 Subject: [PATCH 18/24] Paragraph formatting problems --- src/site/antora/modules/ROOT/pages/manual/configuration.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index ed19eb47c72..28b34bce31e 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -19,7 +19,6 @@ Ralph Goers ; Piotr Karwasz Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. - To decide which of these statements will be logged and where users need to configure Log4j Core. Log4j Core can be configured in two ways: @@ -111,8 +110,8 @@ See xref:manual/webapp.adoc#configuration[Log4j It is also possible to override the location of the configuration file using the xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] configuration property. - In this case, Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. + See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. ==== From 61c2c6ffa0f795f7cfd36e4b6ad895eb18d4d909 Mon Sep 17 00:00:00 2001 From: Christian Grobmeier Date: Tue, 14 May 2024 19:50:38 +0200 Subject: [PATCH 19/24] tiny wording/spelling improvements --- .../ROOT/pages/manual/architecture.adoc | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc index 8cdaf8aab33..f188ffcc3d8 100644 --- a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc @@ -30,13 +30,13 @@ created it will be associated with the LoggerConfig that contains either a) the same name as the Logger, b) the name of a parent package, or c) the root LoggerConfig. LoggerConfig objects are created from Logger declarations in the configuration. The LoggerConfig is associated with -the Appenders that actually deliver the LogEvents. +the Appenders that deliver the LogEvents. [id=logger-hierarchy] === Logger Hierarchy The first and foremost advantage of any logging API over plain -`System.out.println` resides in its ability to disable certain log +`System.out.println()` resides in its ability to disable certain log statements while allowing others to print unhindered. This capability assumes that the logging space, that is, the space of all possible logging statements, is categorized according to some developer-chosen @@ -99,8 +99,8 @@ xref:manual/logsep.adoc[Log Separation] section. Every LoggerContext has an active link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html[`Configuration`]. The Configuration contains all the Appenders, context-wide Filters, -LoggerConfigs and contains the reference to the StrSubstitutor. During -reconfiguration two Configuration objects will exist. Once all Loggers +LoggerConfigs and contains the reference to the StrSubstitutor. +During reconfiguration, two Configuration objects will exist. Once all Loggers have been redirected to the new Configuration, the old Configuration will be stopped and discarded. @@ -118,7 +118,7 @@ causing their behavior to be modified. Retrieving Loggers Calling the `LogManager.getLogger` method with the same name will always -return a reference to the exact same Logger object. +return a reference to the same Logger object. For example, in @@ -230,7 +230,7 @@ In example 3, the loggers`root`, `X` and `X.Y.Z` each have a configured LoggerConfig with the same name. The Logger `X.Y` does not have a configured LoggerConfig with a matching name so uses the configuration of LoggerConfig `X` since that is the LoggerConfig whose name has the -longest match to the start of the Logger's name. +the longest match to the start of the Logger's name. .Example 4 [cols=",,,",options="header",] @@ -245,7 +245,7 @@ longest match to the start of the Logger's name. In example 4, the loggers `root` and `X` each have a Configured LoggerConfig with the same name. The loggers `X.Y` and `X.Y.Z` do not have configured LoggerConfigs and so get their Level from the -LoggerConfig assigned to them,`X`, since it is the LoggerConfig whose +LoggerConfig assigned to them, `X`, since it is the LoggerConfig whose name has the longest match to the start of the Logger's name. .Example 5 @@ -258,10 +258,10 @@ name has the longest match to the start of the Logger's name. |X.YZ |X |ERROR |ERROR |============================================================= -In example 5, the loggers`root`.`X`, and `X.Y` each have a Configured +In example 5, the loggers `root`.`X`, and `X.Y` each has a configured LoggerConfig with the same name. The logger `X.YZ` does not have configured LoggerConfig and so gets its Level from the LoggerConfig -assigned to it,`X`, since it is the LoggerConfig whose name has the +assigned to it, `X`, since it is the LoggerConfig whose name has the longest match to the start of the Logger's name. It is not associated with LoggerConfig `X.Y` since tokens after periods must match exactly. @@ -275,13 +275,13 @@ with LoggerConfig `X.Y` since tokens after periods must match exactly. |X.Y.Z |X.Y | |ERROR |=== -In example 6, LoggerConfig X.Y it has no configured level so it inherits +In example 6, LoggerConfig X.Y has no configured level so it inherits its level from LoggerConfig X. Logger X.Y.Z uses LoggerConfig X.Y since it doesn't have a LoggerConfig with a name that exactly matches. It too inherits its logging level from LoggerConfig X. -The table below illustrates how Level filtering works. In the table, the -vertical header shows the Level of the LogEvent, while the horizontal +The table below illustrates how Level filtering works. In the table, +the vertical header shows the Level of the LogEvent, while the horizontal header shows the Level associated with the appropriate LoggerConfig. The intersection identifies whether the LogEvent would be allowed to pass for further processing (Yes) or discarded (No). @@ -348,7 +348,7 @@ be attached to a Logger. An Appender can be added to a Logger by calling the link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration.html#addLoggerAppender(org.apache.logging.log4j.core.Logger,%20org.apache.logging.log4j.core.Appender)[`addLoggerAppender`] method of the current Configuration. If a LoggerConfig matching the name -of the Logger does not exist, one will be created, the Appender will be +of the Logger does not exist, one will be created, and the Appender will be attached to it and then all Loggers will be notified to update their LoggerConfig references. @@ -434,7 +434,7 @@ sending the formatted output to its destination. The link:../javadoc/log4j-core/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`], part of the standard log4j distribution, lets the user specify the output format according to conversion patterns similar to the C language -`printf` function. +`printf()` function. For example, the PatternLayout with the conversion pattern "%r [%t] %-5p %c - %m%n" will output something akin to: @@ -455,7 +455,7 @@ use cases such as JSON, XML, HTML, and Syslog (including the new RFC specified fields instead of a particular textual layout. Just as importantly, log4j will render the content of the log message -according to user specified criteria. For example, if you frequently +according to user-specified criteria. For example, if you frequently need to log `Oranges`, an object type used in your current project, then you can create an OrangeMessage that accepts an Orange instance and pass that to Log4j so that the Orange object can be formatted into an @@ -467,16 +467,16 @@ The link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`] class and link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`] -interface were borrowed from +interface was borrowed from https://commons.apache.org/proper/commons-lang/[Apache Commons Lang] and then modified to support evaluating LogEvents. In addition the link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/Interpolator.html[`Interpolator`] class was borrowed from Apache Commons Configuration to allow the -StrSubstitutor to evaluate variables that from multiple StrLookups. It +StrSubstitutor to evaluate variables from multiple StrLookups. It too was modified to support evaluating LogEvents. Together these provide a mechanism to allow the configuration to reference variables coming from System Properties, the configuration file, the ThreadContext Map, StructuredData in the LogEvent. The variables can either be resolved -when the configuration is processed or as each event is processed, if +when the configuration is processed or as each event is processed if the component is capable of handling it. See xref:manual/lookups.adoc[Lookups] for more information. From e84a46ceb7fb5740f16a012da47b04cc87b1f0b7 Mon Sep 17 00:00:00 2001 From: Christian Grobmeier Date: Tue, 14 May 2024 20:32:27 +0200 Subject: [PATCH 20/24] tiny wording improvments and corrections --- .../modules/ROOT/pages/manual/async.adoc | 72 +++--- .../modules/ROOT/pages/manual/filters.adoc | 87 ++++---- .../ROOT/pages/manual/garbagefree.adoc | 97 ++++---- .../ROOT/pages/manual/installation.adoc | 16 +- .../antora/modules/ROOT/pages/manual/jmx.adoc | 6 +- .../modules/ROOT/pages/manual/layouts.adoc | 210 +++++++++--------- 6 files changed, 238 insertions(+), 250 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/async.adoc b/src/site/antora/modules/ROOT/pages/manual/async.adoc index c334ccb2f07..0f576da2671 100644 --- a/src/site/antora/modules/ROOT/pages/manual/async.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/async.adoc @@ -18,11 +18,11 @@ Remko Popma Asynchronous logging can improve your application's performance by -executing the I/O operations in a separate thread. Log4j 2 makes a -number of improvements in this area. +executing the I/O operations in a separate thread. +Log4j 2 makes several improvements in this area. -* *Asynchronous Loggers* are a new addition in Log4j 2. Their aim is to -return from the call to Logger.log to the application as soon as +* *Asynchronous Loggers* are a new addition in Log4j 2. They aim to +return the call to Logger.log to the application as soon as possible. You can choose between making all Loggers asynchronous or using a mixture of synchronous and asynchronous Loggers. Making all Loggers asynchronous will give the best performance, while mixing gives @@ -35,8 +35,8 @@ latency. been enhanced to flush to disk at the end of a batch (when the queue is empty). This produces the same result as configuring "immediateFlush=true", that is, all received log events are always -available on disk, but is more efficient because it does not need to -touch the disk on each and every log event. (Async Appenders use +available on disk but are more efficient because it does not need to +touch the disk on every log event. (Async Appenders use ArrayBlockingQueue internally and do not need the disruptor jar on the classpath.) @@ -58,7 +58,7 @@ to log bursts of messages. Async logging can help prevent or dampen latency spikes by shortening the wait time until the next message can be logged. If the queue size is configured large enough to handle the burst, asynchronous logging will help prevent your application from -falling behind (as much) during a sudden increase of activity. +falling behind (as much) during a sudden increase in activity. * Lower logging response time link:#Latency[latency]. Response time latency is the time it takes for a call to Logger.log to return under a given workload. Asynchronous Loggers have consistently lower latency @@ -71,8 +71,8 @@ exception is thrown, it is less easy for an asynchronous logger or appender to signal this problem to the application. This can partly be alleviated by configuring an `ExceptionHandler`, but this may still not cover all cases. For this reason, if logging is part of your business -logic, for example if you are using Log4j as an audit logging framework, -we would recommend to synchronously log those audit messages. (Note that +logic, for example, if you are using Log4j as an audit logging framework, +we would recommend synchronously logging those audit messages. (Note that you can still link:#MixedSync-Async[combine] them and use asynchronous logging for debug/trace logging in addition to synchronous logging for the audit trail.) @@ -85,7 +85,7 @@ modified later. It is safe to asynchronously log mutable objects because most link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`] implementations built-in to Log4j take a snapshot of the parameters. -There are some exceptions however: +There are some exceptions, however: link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[`MapMessage`] and link:../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html[`StructuredDataMessage`] @@ -98,6 +98,7 @@ link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message implementations should be designed with asynchronous use in mind, and either take a snapshot of their parameters at construction time, or document their thread-safety characteristics. + * If your application is running in an environment where CPU resources are scarce, like a machine with one CPU with a single core, starting another thread is not likely to give better performance. @@ -105,7 +106,7 @@ another thread is not likely to give better performance. is faster than the maximum sustained throughput of the underlying appender, the queue will fill up and the application will end up logging at the speed of the slowest appender. If this happens, consider -selecting a xref:manual/performance.adoc#whichAppender[faster appender], or +selecting an xref:manual/performance.adoc#whichAppender[faster appender], or logging less. If neither of these is an option, you may get better throughput and fewer latency spikes by logging synchronously. @@ -116,7 +117,7 @@ NOTE: _Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required._ -This is simplest to configure and gives the best performance. +This is the simplest to configure and gives the best performance. To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property xref:manual/systemproperties.adoc#log4j2.contextSelector[log4j2.contextSelector] to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` or `org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector`. By default, link:#Location[location] is not passed to the I/O thread by @@ -190,17 +191,17 @@ and `log4j2.discardThreshold`]. == Mixing Synchronous and Asynchronous Loggers NOTE: _Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the -classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was -required. There is no need to set system property "Log4jContextSelector" +classpath. Before Log4j-2.9, disruptor-3.0.0.jar or higher was +required. There is no need to set the system property "Log4jContextSelector" to any value._ Synchronous and asynchronous loggers can be combined in configuration. This gives you more flexibility at the cost of a slight loss in performance (compared to making all loggers asynchronous). Use the -`` or `` configuration elements to specify the +`` or `` configuration elements specify the loggers that need to be asynchronous. A configuration can contain only one root logger (either a `` or an `` element), but -otherwise async and non-async loggers may be combined. For example, a +otherwise, async and non-async loggers may be combined. For example, a configuration file containing `` elements can also contain `` and `` elements for the synchronous loggers. @@ -308,7 +309,7 @@ public interface AsyncWaitStrategyFactory { The specified class must also have a public no-argument constructor; Log4j will instantiate an instance of the specified factory class and use this factory to create the WaitStrategy used by all Async Loggers. -WaitStrategy-related system properties are ignored if a `AsyncWaitStrategyFactory` is configured. +WaitStrategy-related system properties are ignored if an `AsyncWaitStrategyFactory` is configured. [#Location] @@ -338,7 +339,7 @@ logging with location is 30-100 times slower than without location. For this reason, asynchronous loggers and asynchronous appenders do not include location information by default. -You can override the default behaviour in your logger or asynchronous +You can override the default behavior in your logger or asynchronous appender configuration by specifying `includeLocation="true"`. [#Performance] @@ -378,10 +379,10 @@ higher throughput than sync loggers.] === Asynchronous Throughput Comparison with Other Logging Packages -We also compared peak throughput of asynchronous loggers to the +We also compared the peak throughput of asynchronous loggers to the synchronous loggers and asynchronous appenders available in other logging packages, specifically log4j-1.2.17 and logback-1.0.10, with -similar results. For asynchronous appenders, total logging throughput of +similar results. For asynchronous appenders, the total logging throughput of all threads together remains roughly constant when adding more threads. Asynchronous loggers make more effective use of the multiple cores available on the machine in multi-threaded scenarios. @@ -457,14 +458,13 @@ threads This section has been rewritten with the Log4j 2.6 release. The previous version only reported _service time_ instead of _response -time_. See the xref:manual/performance.adoc#responseTime[response time] side -bar on the performance page on why this is too optimistic. Furthermore -the previous version reported average latency, which does not make sense +time_. See the xref:manual/performance.adoc#responseTime[response time] sidebar on the performance page on why this is too optimistic. +Furthermore, the previous version reported average latency, which does not make sense since latency is not a normal distribution. Finally, the previous version of this section only reported the maximum latency of up to 99.99% of the measurements, which does not tell you how bad the worst 0.01% were. This is unfortunate because often the "outliers" are all -that matter when it comes to response time. From this release we will +that matter when it comes to response time. From this release, we will try to do better and report response time latency across the full range of percentages, including all the outliers. Our thanks to Gil Tene for his http://www.infoq.com/presentations/latency-response-time[How NOT to @@ -473,11 +473,11 @@ the "Oh s#@t!" presentation.) xref:manual/performance.adoc#responseTime[Response time] is how long it takes to log a message under a certain load. What is often reported as -latency is actually _service time_: how long it took to perform the -operation. This hides the fact that a single spike in service time adds -queueing delay for many of the subsequent operations. Service time is +latency is _service time_: how long it took to operate. +This hides the fact that a single spike in service time adds +a queueing delay for many of the subsequent operations. Service time is easy to measure (and often looks good on paper) but is irrelevant for -users since it omits the time spent waiting for service. For this reason +users since it omits the time spent waiting for service. For this reason, we report response time: service time plus wait time. The response time test results below were all derived from running the @@ -494,9 +494,9 @@ wait strategy reduces some jitter.) * -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle * -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime --XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses) +-XX:+PrintGCApplicationStoppedTime (to eyeball GC and savepoint pauses) -The graph below compares response time latency of the +The graph below compares the response time latency of the ArrayBlockingQueue-based asynchronous appenders in Logback 1.1.7, Log4j 1.2.17 to the various options for asynchronous logging that Log4j 2.6 offers. Under a workload of 128,000 messages per second, using 16 @@ -506,14 +506,14 @@ orders of magnitude larger than Log4j 2. image:ResponseTimeAsyncLogging16Threads_8kEach.png[When 16 threads generate a total workload of 128,000 msg/sec, Logback 1.1.7 and -Log4j 1.2.17 experience latency spikes that are orders of magnitude +Log4j 1.2.17 experiences latency spikes that are orders of magnitude larger than Log4j 2] The graph below zooms in on the Log4j 2 results for the same test. We see that the worst-case response time is highest for the ArrayBlockingQueue-based Async Appender. xref:manual/garbagefree.adoc[Garbage-free] async loggers have the best response -time behaviour. +time behavior. image:ResponseTimeAsyncLogging16Threads_8kEachLog4j2Only-labeled.png[image] @@ -522,14 +522,14 @@ image:ResponseTimeAsyncLogging16Threads_8kEachLog4j2Only-labeled.png[image] Asynchronous Loggers are implemented using the https://lmax-exchange.github.io/disruptor/[LMAX Disruptor] inter-thread -messaging library. From the LMAX web site: +messaging library. From the LMAX website: ____ ...using queues to pass data between stages of the system was -introducing latency, so we focused on optimising this area. The +introducing latency, so we focused on optimizing this area. The Disruptor is the result of our research and testing. We found that cache -misses at the CPU-level, and locks requiring kernel arbitration are both -extremely costly, so we created a framework which has "mechanical +misses at the CPU level, and locks requiring kernel arbitration are both +extremely costly, so we created a framework that has "mechanical sympathy" for the hardware it's running on, and that's lock-free. ____ diff --git a/src/site/antora/modules/ROOT/pages/manual/filters.adoc b/src/site/antora/modules/ROOT/pages/manual/filters.adoc index 52c4bdfc36d..872e4ef4467 100644 --- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc @@ -75,7 +75,7 @@ If the logger is additive, the filter on the parent logger is applied recursivel [CAUTION] ==== -For performance reasons log events should be filtered as soon as possible in the logging pipeline. +For performance reasons, log events should be filtered as soon as possible in the logging pipeline. This reduces the costs (formatting, transfer through an asynchronous barrier) of disabled log events. ==== @@ -90,8 +90,7 @@ Using the `level` property of appender references will give a better performance == BurstFilter The BurstFilter provides a mechanism to control the rate at which -LogEvents are processed by silently discarding events after the maximum -limit has been reached. +LogEvents are processed by silently discarding events after the maximum limit has been reached. .Burst Filter Parameters [cols="1m,1,4"] @@ -117,12 +116,12 @@ times the rate. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -154,8 +153,8 @@ A configuration containing the BurstFilter might look like: == CompositeFilter The CompositeFilter provides a way to specify more than one filter. It -is added to the configuration as a filters element and contains other -filters to be evaluated. The filters element accepts no parameters. +is added to the configuration as a filter element and contains other +filters to be evaluated. The filter element accepts no parameters. A configuration containing the CompositeFilter might look like: @@ -218,7 +217,7 @@ specified ThreadContext item NEUTRAL will be returned. |String |Level of messages to be filtered. The default threshold only applies if the log event contains the specified -ThreadContext Map item and its value does not match any key in the +ThreadContext Map item and its value do not match any key in the key/value pairs. |keyValuePair @@ -229,12 +228,12 @@ key matches. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -329,7 +328,7 @@ MapMessage. |keyValuePair |KeyValuePair[] |One or more KeyValuePair elements that -define the key in the map and the value to match on. If the same key is +define the key in the map and the value to match. If the same key is specified more than once then the check for that key will automatically be an "or" since a Map can only contain a single value. @@ -341,12 +340,12 @@ key/value pairs must match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -458,12 +457,12 @@ matches either the Log Event's Marker or one of its parents. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -495,7 +494,7 @@ appender if the Marker matches: [#MutableThreadContextMapFilter] == MutableThreadContextMapFilter -The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. By default this is the ThreadContext Map. The values to compare are defined externally and can be periodically polled for changes. +The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. By default, this is the ThreadContext Map. The values to compare are defined externally and can be periodically polled for changes. .Mutable Context Map Filter Parameters [cols="1m,1,4"] @@ -514,16 +513,16 @@ key/value pairs must match. |pollInterval |int -|The number of seconds to wait before checking to see if the configuration has been modified. When using HTTP or HTTPS the server must support the If-Modified-Since header and return a Last-Modified header containing the date and time the file was last modified. Note that by default only the https, file, and jar protocols are allowed. Support for other protocols can be enabled by specifying them in the log4j2.Configuration.allowedProtocols system property +|The number of seconds to wait before checking to see if the configuration has been modified. When using HTTP or HTTPS the server must support the If-Modified-Since header and return a Last-Modified header containing the date and time the file was last modified. Note that by default only the https, file, and jar protocols are allowed. Support for other protocols can be enabled by specifying them in the `log4j2.Configuration.allowedProtocols` system property |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -567,8 +566,8 @@ The configuration file supplied to the filter should look similar to: [#NoMarkerFilter] == NoMarkerFilter -The NoMarkerFilter checks that there is no marker included in the LogEvent. A match occurs when there is no -marker in the Log Event. +The NoMarkerFilter checks that there is no marker included in the LogEvent. +A match occurs when there is no marker in the Log Event. .No Marker Filter Parameters [cols="1m,1,3"] @@ -577,12 +576,12 @@ marker in the Log Event. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -629,17 +628,17 @@ compared against a regular expression. |useRawMsg |boolean |If true the unformatted message will be used, -otherwise the formatted message will be used. The default value is +otherwise, the formatted message will be used. The default value is false. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -683,12 +682,12 @@ The ScriptFilter executes a script that returns true or false. |onMatch |String -|Action to take when the script returns true. May be +|Action to take when the script returns true. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter returns false. May +|Action to take when the filter returns false. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -741,7 +740,7 @@ Throwable as part of the Message. |substitutor |StrSubstitutor -|The StrSubstitutor used to replace lookup variables. +|The StrSubstitutor is used to replace lookup variables. |=== The sample below shows how to declare script fields and then reference @@ -801,7 +800,7 @@ the event id, type and message. |KeyValuePair[] |One or more KeyValuePair elements that define the key in the map and the value to match on. "id", "id.name", -"type", and "message" should be used to match on the StructuredDataId, +"type", and "message" should be used to match the StructuredDataId, the name portion of the StructuredDataId, the type, and the formatted message respectively. If the same key is specified more than once then the check for that key will automatically be an "or" since a Map can @@ -815,12 +814,12 @@ key/value pairs must match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -857,7 +856,7 @@ particular events: == ThreadContextMapFilter The ThreadContextMapFilter or ContextMapFilter allows filtering against -data elements that are in the current context. By default this is the +data elements that are in the current context. By default, this is the ThreadContext Map. .Context Map Filter Parameters @@ -868,7 +867,7 @@ ThreadContext Map. |keyValuePair |KeyValuePair[] |One or more KeyValuePair elements that -define the key in the map and the value to match on. If the same key is +define the key in the map and the value to match. If the same key is specified more than once then the check for that key will automatically be an "or" since a Map can only contain a single value. @@ -880,12 +879,12 @@ key/value pairs must match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -950,9 +949,9 @@ The ContextMapFilter can also be applied to a logger for filtering: == ThresholdFilter This filter returns the onMatch result if the level in the LogEvent is -the same or more specific than the configured level and the onMismatch +the same or more specific than the configured level and the `onMismatch` value otherwise. For example, if the ThresholdFilter is configured with -Level ERROR and the LogEvent contains Level DEBUG then the onMismatch +Level ERROR and the LogEvent contains Level DEBUG then the `onMismatch` value will be returned since ERROR events are more specific than DEBUG. .Threshold Filter Parameters @@ -962,16 +961,16 @@ value will be returned since ERROR events are more specific than DEBUG. |level |String -|A valid Level name to match on. +|A valid Level name to match. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== @@ -1003,7 +1002,7 @@ appender if the level matches: [#TimeFilter] == TimeFilter -The time filter can be used to restrict filter to only a certain portion +The time filter can be used to restrict the filter to only a certain portion of the day. .Time Filter Parameters @@ -1027,12 +1026,12 @@ timestamp. |onMatch |String -|Action to take when the filter matches. May be ACCEPT, +|Action to take when the filter matches. Can be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL. |onMismatch |String -|Action to take when the filter does not match. May +|Action to take when the filter does not match. Can be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== diff --git a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc index 426af6b5d83..3393c21a3a1 100644 --- a/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/garbagefree.adoc @@ -32,14 +32,14 @@ many systems significant effort is spent on controlling these pauses. Many logging libraries, including previous versions of Log4j, allocate temporary objects like log event objects, Strings, char arrays, byte -arrays and more during steady state logging. This contributes to +arrays and more during steady-state logging. This contributes to pressure on the garbage collector and increases the frequency with which GC pauses occur. -From version 2.6, Log4j runs in "garbage free" mode by default where +From version 2.6, Log4j runs in "garbage-free" mode by default where objects and buffers are reused and no temporary objects are allocated as much as possible. There is also a "low garbage" mode which is not -completely garbage free but does not use ThreadLocal fields. This is the +completely garbage-free but does not use ThreadLocal fields. This is the default mode when Log4j link:#Config[detects] it is running in a web application. Finally, it is possible to switch off all garbage-free logic and run in "classic mode" instead. For details, see the @@ -121,7 +121,7 @@ for multi-threaded applications in this mode due to synchronization on the shared buffer. If your application is multi-threaded and logging performance is important, consider using Async Loggers. * The ThreadContext map is _not_ garbage-free by default, but from Log4j -2.7 it can be configured to be garbage-free by setting system property +2.7 it can be configured to be garbage-free by setting the system property xref:manual/systemproperties.adoc#log4j2.garbagefreeThreadContextMap[log4j2.garbagefreeThreadContextMap] to "true". Instead of system properties, the above properties can also be specified @@ -158,16 +158,16 @@ steady-state logging: * CompositeFilter (adding and removing element filters creates temporary objects for thread safety) * DynamicThresholdFilter -* LevelRangeFilter (garbage free since 2.8) -* MapFilter (garbage free since 2.8) -* MarkerFilter (garbage free since 2.8) -* StructuredDataFilter (garbage free since 2.8) -* ThreadContextMapFilter (garbage free since 2.8) -* ThresholdFilter (garbage free since 2.8) -* TimeFilter (garbage free since 2.8 except when range must be recalculated once per day) +* LevelRangeFilter (garbage-free since 2.8) +* MapFilter (garbage-free since 2.8) +* MarkerFilter (garbage-free since 2.8) +* StructuredDataFilter (garbage-free since 2.8) +* ThreadContextMapFilter (garbage-free since 2.8) +* ThresholdFilter (garbage-free since 2.8) +* TimeFilter (garbage-free since 2.8 except when range must be recalculated once per day) Other filters like BurstFilter, RegexFilter and ScriptFilter are not -trivial to make garbage free, and there is currently no plan to change +trivial to make garbage-free, and there is currently no plan to change them. [#Layouts] @@ -186,7 +186,7 @@ xref:manual/json-template-layout.adoc#faq-garbage-free[a few exceptions]. PatternLayout with the following limited set of conversion patterns is garbage-free. Format modifiers to control such things as field width, -padding, left and right justification will not generate garbage. +padding, and left and right justification will not generate garbage. [cols="1m,2"] |=== @@ -198,7 +198,7 @@ padding, left and right justification will not generate garbage. |%d, %date a| Note: Only the predefined date formats are garbage-free: (millisecond -separator may be either a comma ',' or a period '.') +the separator may be either a comma ',' or a period '.') [cols="1m,1"] !=== @@ -248,11 +248,11 @@ garbage-free since 2.8 %equalsIgnoreCase\{pattern}\{test}\{substitution} |Replaces occurrences of 'test', a string, with its replacement 'substitution' in the string -resulting from evaluation of the pattern - garbage-free since 2.8 +resulting from the evaluation of the pattern - garbage-free since 2.8 |%highlight\{pattern}\{style} |Adds ANSI colors - garbage-free since 2.7 -(unless nested pattern is not garbage free) +(unless the nested pattern is not garbage-free) |%K\{key}, %map\{key}, %MAP\{key} |Outputs the entries in a @@ -272,11 +272,11 @@ since 2.8 parents) |%maxLen, %maxLength -|Truncates another pattern to some max number of +|Truncates another pattern to some maximum number of characters - garbage-free since 2.8 |%n -|The platform dependent line separator +|The platform-dependent line separator |%N, %nano |System.nanoTime() when the event was logged @@ -300,7 +300,7 @@ every event - garbage-free since 2.8 |%style\{pattern}{ANSI style} |Style the message - garbage-free since -2.7 (unless nested pattern is not garbage free) +2.7 (unless the nested pattern is not garbage-free) |%T, %tid, %threadId |The ID of the thread that generated the logging @@ -324,13 +324,13 @@ garbage-free since 2.8 substitution) |=== -Other PatternLayout conversion patterns, and other Layouts may be +Other PatternLayout conversion patterns and other Layouts may be updated to avoid creating temporary objects in future releases. (Patches welcome!) NOTE: Logging exceptions and stack traces will create temporary objects with any layout. (However, Layouts will only create these -temporary objects when an exception actually occurs.) We haven't figured +temporary objects when an exception occurs.) We haven't figured out a way to log exceptions and stack traces without creating temporary objects. That is unfortunate, but you probably still want to log them when they happen. @@ -393,10 +393,10 @@ not possible. When logging primitive values (i.e. int, double, boolean, etc.) the JVM autoboxes these primitive values to their Object wrapper equivalents, creating garbage. -Log4j provides an `Unbox` utility to prevent autoboxing of primitive +Log4j provides an `Unbox` utility to prevent the autoboxing of primitive parameters. This utility contains a thread-local pool of reused `StringBuilder`s. The `Unbox.box(primitive)` methods write directly into -a StringBuilder, and the resulting text will be copied into the final +a `StringBuilder`, and the resulting text will be copied into the final log message text without creating temporary objects. [source,java] @@ -410,16 +410,16 @@ public void garbageFree() { ---- **** -NOTE: not all logging is garbage free. Specifically: +NOTE: not all logging is garbage-free. Specifically: -* The ThreadContext map is not garbage-free by default, but can be -configured to be garbage-free by setting system property +* The ThreadContext map is not garbage-free by default but can be +configured to be garbage-free by setting the system property `log4j2.garbagefreeThreadContextMap` to "true". * The ThreadContext stack is not garbage-free. * Logging more than 10 parameters creates vararg arrays. * Logging very large messages (more than 518 characters) when all loggers are Async Loggers will cause the internal StringBuilder in the -RingBuffer to be trimmed back to their max size. +RingBuffer is to be trimmed back to its max size. * Logging messages containing '${': substituting a `$\{variable}` creates temporary objects. * Logging a lambda _as a parameter_ @@ -428,7 +428,7 @@ creates a vararg array. Logging a lambda expression by itself is garbage-free: `logger.debug(() -> callExpensiveMethod())`. * The `Logger.traceEntry` and `Logger.traceExit` methods create temporary objects. -* Time calculations are not garbage free when log4j2.usePreciseClock is set to true. +* Time calculations are not garbage-free when log4j2.usePreciseClock is set to true. The default is false. **** @@ -439,12 +439,12 @@ The default is false. === Response Time Latency Response time is how long it takes to log a message under a certain -load. What is often reported as latency is actually _service time_: how -long it took to perform the operation. This hides the fact that a single -spike in service time adds queueing delay for many of the subsequent +load. What is often reported as latency is _service time_: how +long it took to operate. This hides the fact that a single +spike in service time adds a queueing delay for many of the subsequent operations. Service time is easy to measure (and often looks good on paper) but is irrelevant for users since it omits the time spent waiting -for service. For this reason we report response time: service time plus +for service. For this reason, we report response time: service time plus wait time. See the xref:manual/performance.adoc#responseTime[response time section] of the performance page for more detail. @@ -462,25 +462,25 @@ wait strategy reduces some jitter.) * -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle * -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime --XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses) +-XX:+PrintGCApplicationStoppedTime (to eyeball GC and savepoint pauses) === Async Loggers The graph below compares "classic" logging to garbage-free logging -response time behaviour for Log4j's Async Loggers. In the graph, "100k" -means logging at a sustained load of 100,000 messages/second, "800k" is +response time behavior for Log4j's Async Loggers. In the graph, "100k" +means logging at a sustained load of 100,000 messages/second, and "800k" is a sustained load of 800,000 messages/second. image:ResponseTimeAsyncClassicVsGcFree-label.png[image] -In *classic* mode we see numerous minor garbage collections which pause +In *classic* mode we see numerous minor garbage collections that pause the application threads for 3 milliseconds or more. This quickly adds up to response time delays of almost 10 milliseconds. As you can see in the graph, increasing the load shifts the curve to the left (there are more spikes). This makes sense: logging more means more pressure on the garbage collector resulting in more minor GC pauses. We experimented a little with reducing the load to 50,000 or even 5000 messages/second, -but this did not eliminate the 3 millisecond pauses, it just made them +but this did not eliminate the 3-millisecond pauses, it just made them occur less frequently. Note that all GC pauses in this test are minor GC pauses. We did not see any full garbage collections. @@ -488,19 +488,19 @@ In *garbage-free* mode, maximum response time remains well below 1 millisecond under a wide range of loads. (Max 780 us at 800,000 messages/sec, max 407 us at 600,000 messages/sec, with the 99% around 5 us for all loads up to 800,000 messages/sec.) Increasing or decreasing -the load does not change the response time behaviour. We did not +the load does not change the response time behavior. We did not investigate the cause of the 200-300 microsecond pauses we saw in these tests. -When we increased the load further we begin to see larger response time +When we increased the load further we began to see larger response time pauses for both classic and garbage-free logging. At sustained loads of 1 million messages/second or more we start to approach the maximum throughput of the underlying RandomAccessFile Appender (see the -synchronous logging throughput chart below). At these loads the -ringbuffer starts to fill up and backpressure kicks in: attempting to +synchronous logging throughput chart below). At these loads, the +ringbuffer starts to fill up and backpressure kicks in, attempting to add another message when the ringbuffer is full will block until a free slot becomes available. We start to see response times of tens of -milliseconds or more; and attempting to increase the load even more +milliseconds or more, and attempting to increase the load even more results in larger and larger response time spikes. === Synchronous File Logging @@ -509,11 +509,11 @@ With synchronous file logging, garbage-free logging still performs better than classic logging, but the difference is less pronounced. At a workload of 100,000 messages/second, classic logging max response -time was a little over 2 milliseconds where garbage-free logging was a +time was a little over 2 milliseconds whereas garbage-free logging was a little over 1 millisecond. When the workload is increased to 300,000 messages/second, classic logging shows response time pauses of 6 milliseconds where the garbage-free response times were less than 3 -milliseconds. It may be possible to improve on this, we did not +milliseconds. It may be possible to improve on this, but we did not investigate further yet. image:ResponseTimeSyncClassicVsGcFree.png[image] @@ -535,7 +535,7 @@ classic mode and Log4j 2.5. image:garbage-free2.6-SyncThroughputLinux.png[Throughput of Log4j 2.6 in garbage-free mode is slightly worse than in classic mode, -but on par with 2.5 and much better than alternatives logging libraries] +but on par with 2.5 and much better than alternative logging libraries] The results above are obtained with the http://openjdk.java.net/projects/code-tools/jmh/[JMH] Java benchmark @@ -564,12 +564,11 @@ directly write into. `AbstractOutputStreamAppender` has been modified to make the ConsoleAppender, (Rolling)FileAppender, (Rolling)RandomAccessFileAppender and MemoryMappedFileAppender -garbage-free. An effort has been made to minimize impact on custom +garbage-free. An effort has been made to minimize the impact on custom Appenders that extend `AbstractOutputStreamAppender`, but it is -impossible to guarantee that changing the superclass will not impact any -and all subclasses. Custom Appenders that extend +impossible to guarantee that changing the superclass will not impact any subclasses. Custom Appenders that extend `AbstractOutputStreamAppender` should verify that they still function -correctly. In case there is a problem, system property +correctly. In case there is a problem, the system property `log4j2.enable.direct.encoders` can be set to "false" to revert to the pre-Log4j 2.6 behaviour. diff --git a/src/site/antora/modules/ROOT/pages/manual/installation.adoc b/src/site/antora/modules/ROOT/pages/manual/installation.adoc index c2d46c7d452..cf84dac6c76 100644 --- a/src/site/antora/modules/ROOT/pages/manual/installation.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/installation.adoc @@ -33,7 +33,7 @@ Below we share some shortcuts for the impatient. [WARNING] ==== -We strongly advise you to skim through this page to get a grip on fundamental logging concepts and understand which recipe fits to your bill best. +We strongly advise you to skim through this page to get a grip on fundamental logging concepts and understand which recipe fits your bill best. ==== Are you a library developer?:: @@ -262,7 +262,7 @@ implementation 'org.apache.logging.log4j:log4j-api' [#impl] == Installing a logging implementation -Log4j provides several modules to facilitate deployment of different logging implementations: +Log4j provides several modules to facilitate the deployment of different logging implementations: `log4j-core`:: The reference implementation. @@ -280,7 +280,7 @@ https://logback.qos.ch/[Logback] implements SLF4J natively, refer to < While xref:manual/layouts.adoc#PatternLayout[Pattern Layout] is a good first choice and preferable for tests, we recommend using a structured format such as xref:manual/json-template-layout.adoc[] for production deployments. -In order to use these formats, the following additional dependencies are required: +To use these formats, the following additional dependencies are required: include::partial$configuration-file-format-deps.adoc[] diff --git a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc index a6a5f933614..43dba1504fa 100644 --- a/src/site/antora/modules/ROOT/pages/manual/jmx.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/jmx.adoc @@ -50,7 +50,7 @@ system property to `false`. The JConsole tool that is included in the Java JDK can be used to monitor your application. Start JConsole by typing `$JAVA_HOME/bin/jconsole` in a command shell. For more details, -see Oracle's documentation on +see Oracle's documentation at https://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html[how to use JConsole]. @@ -69,7 +69,7 @@ and In the property above, `portNum` is the port number through which you want to enable JMX RMI connections. -For more details, see Oracle's documentation on +For more details, see Oracle's documentation at https://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdenl[Remote Monitoring and Management]. @@ -83,7 +83,7 @@ documentation] for the `sun.rmi.dgc.server.gcInterval` and properties is 3600000 milliseconds (one hour). Before Java 6, it was one minute. -The two sun.rmi arguments reflect whether your JVM is running in server +The two `sun.rmi` arguments reflect whether your JVM is running in server or client mode. If you want to modify the GC interval time it may be best to specify both properties to ensure the argument is picked up by the JVM. diff --git a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc index 1b16a5eddf5..1859d2b4c9d 100644 --- a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc @@ -52,8 +52,7 @@ The CSV layout can be used in two ways: First, using `CsvParameterLayout` to log event parameters to create a custom database, usually to a logger and file appender uniquely configured for this purpose. Second, using `CsvLogEventLayout` to log events to create -a database, as an alternative to using a full DBMS or using a JDBC -driver that supports the CSV format. +a database, as an alternative to using a full DBMS or using a JDBC driver that supports the CSV format. The `CsvParameterLayout` converts an event's parameters into a CSV record, ignoring the message. To log CSV records, you can use the usual @@ -70,7 +69,7 @@ Which will create the CSV record: value1, value2, value3 .... -Alternatively, you can use a `ObjectArrayMessage`, which only carries +Alternatively, you can use an `ObjectArrayMessage`, which only carries parameters: [source,java] @@ -131,7 +130,7 @@ specified value. One of: `ALL`, `MINIMAL`, `NON_NUMERIC`, `NONE`. |Desc. |=== -Logging as a CSV events looks like this: +Logging as a CSV event looks like this: [source,java] ---- @@ -273,7 +272,7 @@ expensive operation and may impact performance. Use with caution. |fontSize |String -|The `font-size` to use. The default is "small". +|The `font size` to use. The default is "small". |datePattern |String @@ -281,12 +280,12 @@ expensive operation and may impact performance. Use with caution. |timezone |String -|The timezone id of the logging event. If not specified, this layout uses the https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getDefault()[java.util.TimeZone.getDefault] as default timezone. Like link:#PatternDate[date pattern] of PatternLayout, you can use timezone id from +|The timezone id of the logging event. If not specified, this layout uses the https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getDefault()[java.util.TimeZone.getDefault] as the default timezone. Like link:#PatternDate[date pattern] of PatternLayout, you can use the timezone id from https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(java.lang.String)[java.util.TimeZone.getTimeZone]. |=== -Configure as follows to use dataPattern and timezone in HtmlLayout: +Configure as follows to use `dataPattern` and timezone in `HtmlLayout`: [source,xml] ---- @@ -371,7 +370,7 @@ Log event follows this pattern: === Pretty vs. compact JSON -The compact attribute determines whether the output will be "pretty" or not. The default value is "false", which means the appender uses end-of-line characters and indents lines to format the text. If `compact="true"`, then no end-of-line or indentation is used, which will cause the output to take less space. Of course, the message content may contain, escaped end-of-lines. +The compact attribute determines whether the output will be "pretty" or not. The default value is "false", which means the appender uses end-of-line characters and indent lines to format the text. If `compact="true"`, then no end-of-line or indentation is used, which will cause the output to take less space. Of course, the message content may contain, escaped end-of-lines. [options="header"] |=== @@ -391,7 +390,7 @@ The compact attribute determines whether the output will be "pretty" or not. The | objectMessageAsJsonObject | boolean | If true, ObjectMessage is serialized as JSON object to the "message" field of the output log. Defaults to false. |=== -To include any custom field in the output, use following syntax: +To include any custom field in the output, use the following syntax: [source,xml] ---- @@ -409,8 +408,8 @@ Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for [#JSONTemplateLayout] == JSON Template Layout -`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON -emitting layout. It encodes ``LogEvent``s according to the structure described +`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON-emitting layout. +It encodes ``LogEvent``s according to the structure described by the JSON template provided. For instance, given the following JSON template modelling https://github.com/logstash/log4j-jsonevent-layout[the official Logstash `JSONEventLayoutV1`] @@ -515,12 +514,12 @@ documentation. [id=pattern-layout] == [[PatternLayout]] Pattern Layout -A flexible layout configurable with pattern string. The goal of this +A flexible layout is configurable with a pattern string. The goal of this class is to format a LogEvent and return the results. The format of the result depends on the _conversion pattern_. The conversion pattern is closely related to the conversion pattern of -the printf function in C. A conversion pattern is composed of literal +the `printf()` function in C. A conversion pattern is composed of literal text and format control expressions called _conversion specifiers_. _Note that any literal text, including *Special Characters*, may be @@ -531,7 +530,7 @@ Each conversion specifier starts with a percent sign (%) and is followed by optional _format modifiers_ and a _conversion character_. The conversion character specifies the type of data, e.g. category, priority, date, thread name. The format modifiers control such things as -field width, padding, left and right justification. The following is a +field width, padding, and left and right justification. The following is a simple example. Let the conversion pattern be *"%-5p [%t]: %m%n"* and assume that the @@ -558,7 +557,7 @@ logging event should be left justified to a width of five characters. If the pattern string does not contain a specifier to handle a Throwable being logged, parsing of the pattern will act as if the `%xEx` specifier -had be added to the end of the string. To suppress formatting of the +had been added to the end of the string. To suppress the formatting of the Throwable completely simply add `%ex\{0}` as a specifier in the pattern string. @@ -632,7 +631,7 @@ escape codes. |regex |String -|A Java-compliant regular expression to match in the resulting string. See +|A Java-compliant regular expression to match the resulting string. See https://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html[Pattern]. |replacement @@ -658,7 +657,7 @@ with a decimal integer. When the precision specifier is an integer value, it reduces the size of the logger name. If the number is positive, the layout prints the -corresponding number of rightmost logger name components. If negative, +corresponding number of the rightmost logger name components. If negative, the layout removes the corresponding number of leftmost logger name components. If the precision contains periods then the number before the first period identifies the length to be printed from items that precede tokens in the rest of the pattern. @@ -824,7 +823,7 @@ You can define custom date formats: `%d\{UNIX}` outputs the UNIX time in seconds. `%d\{UNIX_MILLIS}` outputs the UNIX time in milliseconds. The UNIX time is the difference, in seconds -for UNIX and in milliseconds for UNIX_MILLIS, between the current time +for UNIX and milliseconds for UNIX_MILLIS, between the current time and midnight, January 1, 1970 UTC. While the time unit is milliseconds, the granularity depends on the operating system (http://msdn.microsoft.com/en-us/windows/hardware/gg463266.aspx[Windows]). @@ -835,11 +834,11 @@ involved. Log4j 2.11 adds limited support for timestamps more precise than milliseconds when running on Java 9. Note that not all https://docs.oracle.com/javase/9/docs/api/java/time/format/DateTimeFormatter.html[DateTimeFormatter] -formats are supported. Only timestamps in the formats mentioned in the -table above may use the "nano-of-second" pattern letter `n` instead of +formats are supported. Only timestamps in the formats mentioned in the table +above may use the "nano-of-second" pattern letter `n` instead of the "fraction-of-second" pattern letter `S`. -Users may revert back to a millisecond-precision clock when running on +Users may revert to a millisecond-precision clock when running on Java 9 by setting system property `log4j2.Clock` to `SystemMillisClock`. |*enc*\{pattern}{[HTML\|XML\|JSON\|CRLF]} + @@ -847,9 +846,8 @@ Java 9 by setting system property `log4j2.Clock` to `SystemMillisClock`. |Encodes and escapes special characters suitable for output in specific markup languages. By default, this encodes for HTML if only one option is specified. The second option is used to specify which encoding format -should be used. This converter is particularly useful for encoding user -provided data so that the output data is not written improperly or -insecurely. +should be used. This converter is particularly useful for encoding user-provided +data so that the output data is not written improperly or insecurely. A typical usage would encode the message `%enc{%m}` but user input could come from other locations as well, such as the MDC `%enc{%mdc\{key}}` @@ -911,9 +909,9 @@ Using the CRLF encoding format, the following characters are replaced: |*equals*\{pattern}\{test}\{substitution} + *equalsIgnoreCase*\{pattern}\{test}\{substitution} |Replaces occurrences of 'test', a string, with its replacement -'substitution' in the string resulting from evaluation of the pattern. +'substitution' in the string resulting from the evaluation of the pattern. For example, "%equals{[%marker]}{[]}\{}" will replace '[]' strings -produces by events without markers with an empty string. +produced by events without markers with an empty string. The pattern can be arbitrarily complex and in particular can contain multiple conversion keywords. @@ -968,7 +966,7 @@ Use `{filters(packages)}` where _packages_ is a list of package names to suppress matching stack frames from stack traces. Use `{suffix(pattern)}` to add the output of _pattern_ at the end of -each stack frames. +each stack frame. Use a `{separator(...)}` as the end-of-line string. For example: `separator(\|)`. The default value is the `line.separator` system @@ -1014,8 +1012,7 @@ The color names are ANSI names defined in the link:../javadoc/log4j-core/org/apache/logging/log4j/core/pattern/AnsiEscape.html[`AnsiEscape`] class. -The color and attribute names and are standard, but the exact shade, -hue, or value. +The color and attribute names are standard, but the exact shade, hue, or value. .Color table !=== @@ -1039,14 +1036,13 @@ example: %highlight{%d [%t] %-5level: %msg%n%throwable}{FATAL=white, ERROR=red, WARN=blue, INFO=black, DEBUG=green, TRACE=blue} .... -You can highlight only the a portion of the log event: +You can highlight only the portion of the log event: .... %d [%t] %highlight{%-5level: %msg%n%throwable} .... -You can style one part of the message and highlight the rest the log -event: +You can style one part of the message and highlight the rest of the log event: .... %style{%d [%t]}{black} %highlight{%-5level: %msg%n%throwable} @@ -1085,16 +1081,16 @@ The STYLE value can be one of: link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[MapMessage], if one is present in the event. The `K` conversion character can be followed by the key for the map placed between braces, as in -`%K\{clientNumber}` where `clientNumber` is the key. The value in the -Map corresponding to the key will be output. If no additional sub-option -is specified, then the entire contents of the Map key value pair set is +`%K\{clientNumber}` where `clientNumber` is the key. The value of the Map +corresponding to the key will be output. If no additional sub-option +is specified, then the entire contents of the Map key-value pair set is output using a format {{key1,val1},{key2,val2}} |[[PatternLocation]] *l* + *location* -|Outputs location information of the caller which generated the logging event. +|Outputs location information of the caller which generates the logging event. -The location information depends on the JVM implementation but usually +The location information depends on the JVM implementation but it usually consists of the fully qualified name of the calling method followed by the callers source the file name and line number between parentheses. @@ -1112,7 +1108,7 @@ with caution. |[[PatternMessage]] *m*\{lookups}\{ansi} + *msg*\{lookups}\{ansi} + *message\{lookups}\{ansi} -|Outputs the application supplied message associated with the logging +|Outputs the application-supplied message associated with the logging event. Add `\{ansi}` to render messages with ANSI escape codes (requires JAnsi, @@ -1192,7 +1188,7 @@ example: `%maxLen{%m}\{20}` will be limited to 20 characters and no trailing ellipsis. |[[PatternNewLine]] *n* -|Outputs the platform dependent line separator character or characters. +|Outputs the platform-dependent line separator character or characters. This conversion character offers practically the same performance as using non-portable line separator strings such as "\n", or "\r\n". Thus, @@ -1200,8 +1196,7 @@ it is the preferred way of specifying a line separator. |[[NanoTime]] *N* + *nano* -|Outputs the result of `System.nanoTime()` at the time the log -event was created. +|Outputs the result of `System.nanoTime()` at the time the log event was created. |[[Process_ID]] *pid*{[defaultValue]} + *processId*{[defaultValue]} @@ -1225,7 +1220,7 @@ For example: ...} **p**\|*level*{length=_n_} **p**\|*level*{lowerCase=__true__\|_false_} |Outputs the level of the logging event. You provide a level name map in -the form "level=value, level=value" where level is the name of the Level +the form "level=value, level=value" where the level is the name of the Level and value is the value that should be displayed instead of the name of the Level. @@ -1257,11 +1252,10 @@ You can combine the two kinds of options: %level{ERROR=Error, length=2} .... -This give you the `Error` level name and all other level names of length +This gives you the `Error` level name and all other level names of length 2. -Finally, you can output lower-case level names (the default is -upper-case): +Finally, you can output lower-case level names (the default is upper-case): .... %level{lowerCase=true} @@ -1279,11 +1273,11 @@ For example, "%repeat{\*}\{2}" will result in the string "**". |[[PatternReplace]] *replace*\{pattern}\{regex}\{substitution} |Replaces occurrences of 'regex', a regular expression, with its -replacement 'substitution' in the string resulting from evaluation of +replacement 'substitution' in the string resulting from the evaluation of the pattern. For example, "%replace{%msg}{\s}\{}" will remove all spaces contained in the event message. -The pattern can be arbitrarily complex and in particular can contain +The pattern can be arbitrarily complex and in particular, can contain multiple conversion keywords. For instance, "%replace{%logger %msg}{\.}{/}" will replace all dots in the logger or the message of the event with a forward slash. @@ -1329,7 +1323,7 @@ within applications that share the same converter Class object. |[[PatternStyle]] *style*\{pattern}{ANSI style} |Uses ANSI escape sequences to style the result of the enclosed pattern. -The style can consist of a comma separated list of style names from the +The style can consist of a comma-separated list of style names from the following table. (See Jansi link:#enable-jansi[configuration].) !=== @@ -1357,55 +1351,55 @@ following table. (See Jansi link:#enable-jansi[configuration].) ! !Black or FG_Black -!Set foreground color to black +!Set the foreground color to black !Red or FG_Red -!Set foreground color to red +!Set the foreground color to red !Green or FG_Green -!Set foreground color to green +!Set the foreground color to green !Yellow or FG_Yellow -!Set foreground color to yellow +!Set the foreground color to yellow !Blue or FG_Blue -!Set foreground color to blue +!Set the foreground color to blue !Magenta or FG_Magenta -!Set foreground color to magenta +!Set the foreground color to magenta !Cyan or FG_Cyan -!Set foreground color to cyan +!Set the foreground color to cyan !White or FG_White -!Set foreground color to white +!Set the foreground color to white !Default or FG_Default -!Set foreground color to default (white) +!Set the foreground color to default (white) !BG_Black -!Set background color to black +!Set the background color to black !BG_Red -!Set background color to red +!Set the background color to red !BG_Green -!Set background color to green +!Set the background color to green !BG_Yellow -!Set background color to yellow +!Set the background color to yellow !BG_Blue -!Set background color to blue +!Set the background color to blue !BG_Magenta -!Set background color to magenta +!Set the background color to magenta !BG_Cyan -!Set background color to cyan +!Set the background color to cyan !BG_White -!Set background color to white +!Set the background color to white !=== For example: @@ -1464,14 +1458,14 @@ for the map placed between braces, as in *%X\{clientNumber}* where `clientNumber` is the key. The value in the MDC corresponding to the key will be output. -If a list of keys are provided, such as *%X{name, number}*, then each +If a list of keys is provided, such as *%X{name, number}*, then each key that is present in the ThreadContext will be output using the format {name=val1, number=val2}. The key/value pairs will be printed in the order they appear in the list. -If no sub-options are specified then the entire contents of the MDC key -value pair set is output using a format {key1=val1, key2=val2}. The -key/value pairs will be printed in sorted order. +If no sub-options are specified then the entire contents of the MDC key-value pair +set is output using a format {key1=val1, key2=val2}. +The key/value pairs will be printed in sorted order. See the link:../javadoc/log4j-api/org/apache/logging/log4j/ThreadContext.html[ThreadContext] @@ -1480,10 +1474,10 @@ class for more details. |[[PatternUUID]] *u*{"RANDOM" \| "TIME"} + *uuid* |Includes either a random or a time-based UUID. The time-based -UUID is a Type 1 UUID that can generate up to 10,000 unique ids per -millisecond, will use the MAC address of each host, and to try to insure -uniqueness across multiple JVMs and/or ClassLoaders on the same host a -random number between 0 and 16,384 will be associated with each instance +UUID is a Type 1 UUID that can generate up to 10,000 unique IDs per +millisecond will use the MAC address of each host, and to try to insure +uniqueness across multiple JVMs and/or ClassLoaders on the same host +a random number between 0 and 16,384 will be associated with each instance of the UUID generator Class and included in each time-based UUID generated. Because time-based UUIDs contain the MAC address and timestamp they should be used with care as they can cause a security @@ -1524,9 +1518,9 @@ Use a `separator` string to separate the lines of a stack trace. For example: `separator(\|)`. The default value is the `line.separator` system property, which is operating system dependent. -The `ansi` option renders stack traces with ANSI escapes code using the +The `ansi` option renders stack traces with ANSI escape code using the JAnsi library. (See link:#enable-jansi[configuration].) Use `\{ansi}` to -use the default color mapping. You can specify your own mappings with +use the default color mapping. You can specify your mappings with `key=value` pairs. The keys are: * Prefix @@ -1568,8 +1562,8 @@ print. |The sequence %% outputs a single percent sign. |=== -By default the relevant information is output as is. However, with the -aid of format modifiers it is possible to change the minimum field +By default, the relevant information is output as is. However, with +the aid of format modifiers it is possible to change the minimum field width, the maximum field width and justification. The optional format modifier is placed between the percent sign and the @@ -1591,9 +1585,9 @@ This behavior can be changed using the _maximum field width_ modifier which is designated by a period followed by a decimal constant. If the data item is longer than the maximum field, then the extra characters are removed from the _beginning_ of the data item and not from the end. -For example, it the maximum field width is eight and the data item is +For example, if the maximum field width is eight and the data item is ten characters long, then the first two characters of the data item are -dropped. This behavior deviates from the printf function in C where +dropped. This behavior deviates from the `printf()` function in C where truncation is done from the end. Truncation from the end is possible by appending a minus character right @@ -1626,15 +1620,14 @@ less than 20 characters long. |NA |none |30 -|Truncate from the beginning if the category name -is longer than 30 characters. +|Truncate from the beginning if the category name is longer than 30 characters. |%20.30c |false |20 |30 |Left pad with spaces if the category name is -shorter than 20 characters. However, if category name is longer than 30 +shorter than 20 characters. However, if the category name is longer than 30 characters, then truncate from the beginning. |%-20.30c @@ -1642,7 +1635,7 @@ characters, then truncate from the beginning. |20 |30 |Right pad with spaces if the category name is -shorter than 20 characters. However, if category name is longer than 30 +shorter than 20 characters. However, if the category name is longer than 30 characters, then truncate from the beginning. |%-20.-30c @@ -1650,7 +1643,7 @@ characters, then truncate from the beginning. |20 |30 |Right pad with spaces if the category name is -shorter than 20 characters. However, if category name is longer than 30 +shorter than 20 characters. However, if the category name is longer than 30 characters, then truncate from the end. |=== @@ -1663,9 +1656,9 @@ http://jansi.fusesource.org/[Jansi] jar to your application and set property `log4j.skipJansi` to `false`. This allows Log4j to use Jansi to add ANSI escape codes when writing to the console. -NOTE: Prior to Log4j 2.10, Jansi was enabled by default. The fact that +NOTE: Before Log4j 2.10, Jansi was enabled by default. The fact that Jansi requires native code means that Jansi can only be loaded by a -single class loader. For web applications this means the Jansi jar has +single class loader. For web applications, this means the Jansi jar has to be in the web container's classpath. To avoid causing problems for web applications, Log4j will no longer automatically try to load Jansi without explicit configuration from Log4j 2.10 onward. @@ -1728,7 +1721,7 @@ that can be selected. The LevelPatternSelector selects patterns based on the log level of the log event. If the Level in the log event is equal to (ignoring case) - the name specified on the PatternMatch key attribute, then +the name specified on the PatternMatch key attribute, then the pattern specified on that PatternMatch element will be used. [source,xml] @@ -1760,11 +1753,11 @@ the pattern specified on that PatternMatch element will be used. [#ScriptPatternSelector] ==== ScriptPatternSelector -The ScriptPatternSelector executes a script as descibed in the +The ScriptPatternSelector executes a script as described in the xref:manual/configuration.adoc#Scripts[Scripts] section of the Configuration chapter. The script is passed all the properties configured in the Properties section of the configuration, the StrSubstitutor used by the -Confguration in the "substitutor" variables, and the log event in the +Configuration in the "substitutor" variables, and the log event in the "logEvent" variable, and is expected to return the value of the PatternMatch key that should be used, or null if the default pattern should be used. @@ -1791,9 +1784,8 @@ should be used. [#RFC5424Layout] == RFC5424 Layout -As the name implies, the Rfc5424Layout formats LogEvents in accordance -with http://tools.ietf.org/html/rfc5424[RFC 5424], the enhanced Syslog -specification. Although the specification is primarily directed at +As the name implies, the Rfc5424Layout formats LogEvents by http://tools.ietf.org/html/rfc5424[RFC 5424], the enhanced Syslog specification. +Although the specification is primarily directed at sending messages via Syslog, this format is quite useful for other purposes since items are passed in the message as self-describing key/value pairs. @@ -1811,7 +1803,7 @@ syslog record. |charset |String |The character set to use when converting the syslog -String to a byte array. The String must be a valid +String to a byte array. The String must be valid http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html[Charset]. If not specified, the default system Charset will be used. @@ -1835,21 +1827,20 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV", "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be -specified as upper or lower case characters. +specified as upper or lowercase characters. |format |String -|If set to "RFC5424" the data will be formatted in -accordance with RFC 5424. Otherwise, it will be formatted as a BSD +|If set to "RFC5424" the data will be formatted by RFC 5424. +Otherwise, it will be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be 1024 bytes or shorter the SyslogLayout does not truncate them. The RFC5424Layout also does not truncate records since the receiver must -accept records of up to 2048 bytes and may accept records that are -longer. +accept records of up to 2048 bytes and may accept longer records. |id |String -|The default structured data id to use when formatting +|The default structured data-id to use when formatting according to RFC 5424. If the LogEvent contains a StructuredDataMessage the id from the Message will be used instead of this value. @@ -1870,29 +1861,28 @@ which specifies the PatternLayout pattern to use as the value. |mdcExcludes |String -|A comma separated list of mdc keys that should be +|A comma-separated list of mdc keys that should be excluded from the LogEvent. This is mutually exclusive with the mdcIncludes attribute. This attribute only applies to RFC 5424 syslog records. |mdcIncludes |String -|A comma separated list of mdc keys that should be +|A comma-separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes attribute. This attribute only applies to RFC 5424 syslog records. |mdcRequired |String -|A comma separated list of mdc keys that must be +|A comma-separated list of mdc keys that must be present in the MDC. If a key is not present a LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records. |mdcPrefix |String -|A string that should be prepended to each MDC key in -order to distinguish it from event attributes. The default string is -"mdc:". This attribute only applies to RFC 5424 syslog records. +|A string that should be prepended to each MDC key to distinguish it from event attributes. +The default string is "mdc:". This attribute only applies to RFC 5424 syslog records. |mdcId |String @@ -1917,7 +1907,7 @@ order to distinguish it from event attributes. The default string is The SerializedLayout simply serializes the LogEvent into a byte array using Java Serialization. The SerializedLayout accepts no parameters. -This layout is deprecated since version 2.9. Java Serialization has +This layout has been deprecated since version 2.9. Java Serialization has inherent security weaknesses, using this layout is no longer recommended. @@ -1925,7 +1915,7 @@ recommended. == Syslog Layout The SyslogLayout formats the LogEvent as BSD Syslog records matching the -same format used by Log4j 1.2. +the same format used by Log4j 1.2. .SyslogLayout Parameters [cols="1m,1,4"] @@ -1946,7 +1936,7 @@ The facility option must be set to one of "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV", "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5", "LOCAL6", or "LOCAL7". These values may be -specified as upper or lower case characters. +specified as upper or lowercase characters. |newLine |boolean @@ -2025,7 +2015,7 @@ Markers are represented by a `Marker` element within the `Event` element. The `M === Pretty vs. compact XML -By default, the XML layout is not compact (a.k.a. not "pretty") with `compact="false"`, which means the appender uses end-of-line characters and indents lines to format the XML. If `compact="true"`, then no end-of-line or indentation is used. Message content may contain, of course, end-of-lines. +By default, the XML layout is not compact (a.k.a. not "pretty") with `compact="false"`, which means the appender uses end-of-line characters and indent lines to format the XML. If `compact="true"`, then no end-of-line or indentation is used. Message content may contain, of course, end-of-lines. [options="header"] |=== @@ -2155,5 +2145,5 @@ logging with location is 30-100 times slower than without location. For this reason, asynchronous loggers and asynchronous appenders do not include location information by default. -You can override the default behaviour in your logger or asynchronous +You can override the default behavior in your logger or asynchronous appender configuration by specifying `includeLocation="true"`. From be54ca2aefd708b8159548277d99e12aea948980 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Wed, 15 May 2024 10:35:57 +0200 Subject: [PATCH 21/24] Apply suggestions from code review (2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Volkan Yazıcı --- .../configuration/arbiters-select.json | 2 + .../configuration/arbiters-select.properties | 2 + .../configuration/arbiters-select.xml | 2 + .../configuration/arbiters-select.yaml | 2 + .../{ => manual}/configuration/arbiters.json | 0 .../configuration/arbiters.properties | 0 .../{ => manual}/configuration/arbiters.xml | 0 .../{ => manual}/configuration/arbiters.yaml | 0 .../configuration/logger-properties.json | 0 .../logger-properties.properties | 0 .../configuration/logger-properties.xml | 0 .../configuration/logger-properties.yaml | 0 .../configuration/main-elements.json | 0 .../configuration/main-elements.properties | 0 .../configuration/main-elements.xml | 0 .../configuration/main-elements.yaml | 0 .../configuration/properties.json | 0 .../configuration/properties.properties | 0 .../{ => manual}/configuration/properties.xml | 0 .../configuration/properties.yaml | 0 .../{ => manual}/configuration/routing.json | 0 .../configuration/routing.properties | 0 .../{ => manual}/configuration/routing.xml | 0 .../{ => manual}/configuration/routing.yaml | 0 .../{ => manual}/configuration/scripts.json | 0 .../configuration/scripts.properties | 0 .../{ => manual}/configuration/scripts.xml | 0 .../{ => manual}/configuration/scripts.yaml | 0 .../configuration/xinclude-appenders.xml | 0 .../configuration/xinclude-loggers.xml | 0 .../configuration/xinclude-main.xml | 0 .../filters}/filters.json | 0 .../filters}/filters.properties | 0 .../filters}/filters.xml | 0 .../filters}/filters.yaml | 0 .../ROOT/pages/manual/configuration.adoc | 136 ++++--- .../modules/ROOT/pages/manual/filters.adoc | 106 +++--- .../modules/ROOT/pages/manual/layouts.adoc | 353 ++++++++---------- .../ROOT/pages/manual/systemproperties.adoc | 42 +-- .../modules/ROOT/pages/plugin-reference.adoc | 2 + .../properties-async-logger-config.adoc | 0 .../properties-async-logger.adoc | 0 .../systemproperties}/properties-async.adoc | 0 .../properties-configuration-factory.adoc | 0 .../properties-context-selector.adoc | 0 .../properties-garbage-collection.adoc | 0 .../systemproperties}/properties-jansi.adoc | 0 .../systemproperties}/properties-jmx.adoc | 0 .../systemproperties}/properties-jndi.adoc | 0 .../properties-loader-util.adoc | 0 .../properties-log4j-core-misc.adoc | 0 .../properties-log4j-jul.adoc | 0 .../properties-log4j-spring-boot.adoc | 0 .../systemproperties}/properties-meta.adoc | 0 .../properties-provider.adoc | 0 .../properties-simple-logger.adoc | 0 .../properties-status-logger.adoc | 0 .../properties-thread-context.adoc | 0 .../properties-transport-security.adoc | 0 59 files changed, 309 insertions(+), 338 deletions(-) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters-select.json (91%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters-select.properties (97%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters-select.xml (96%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters-select.yaml (96%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters.json (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters.properties (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/arbiters.yaml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/logger-properties.json (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/logger-properties.properties (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/logger-properties.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/logger-properties.yaml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/main-elements.json (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/main-elements.properties (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/main-elements.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/main-elements.yaml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/properties.json (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/properties.properties (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/properties.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/properties.yaml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/routing.json (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/routing.properties (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/routing.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/routing.yaml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/scripts.json (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/scripts.properties (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/scripts.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/scripts.yaml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/xinclude-appenders.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/xinclude-loggers.xml (100%) rename src/site/antora/modules/ROOT/examples/{ => manual}/configuration/xinclude-main.xml (100%) rename src/site/antora/modules/ROOT/examples/{configuration => manual/filters}/filters.json (100%) rename src/site/antora/modules/ROOT/examples/{configuration => manual/filters}/filters.properties (100%) rename src/site/antora/modules/ROOT/examples/{configuration => manual/filters}/filters.xml (100%) rename src/site/antora/modules/ROOT/examples/{configuration => manual/filters}/filters.yaml (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-async-logger-config.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-async-logger.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-async.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-configuration-factory.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-context-selector.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-garbage-collection.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-jansi.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-jmx.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-jndi.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-loader-util.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-log4j-core-misc.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-log4j-jul.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-log4j-spring-boot.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-meta.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-provider.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-simple-logger.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-status-logger.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-thread-context.adoc (100%) rename src/site/antora/modules/ROOT/partials/{ => manual/systemproperties}/properties-transport-security.adoc (100%) diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.json similarity index 91% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.json index c934d7868b1..a8a4eb0b9bb 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.json +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.json @@ -3,6 +3,7 @@ "Appenders": { "File": { "name": "MAIN", + // tag::select[] "Select": { "SystemPropertyArbiter": { // <1> "propertyName": "env", @@ -13,6 +14,7 @@ "JsonTemplateLayout": {} } } + // end::select[] } }, "Loggers": { diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.properties similarity index 97% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.properties index 2339ba93d6e..8fa74a1d8ee 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.properties +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.properties @@ -16,6 +16,7 @@ # appender.0.type = File appender.0.name = MAIN +# tag::select[] appender.0.select.type = Select appender.0.select.0.type = SystemPropertyArbiter # <1> @@ -25,6 +26,7 @@ appender.0.select.0.layout.type = PatternLayout appender.0.select.1.type = DefaultArbiter # <2> appender.0.select.1.layout.type = JsonTemplateLayout +# end::select[] rootLogger.level = INFO rootLogger.appenderRef.0.ref = MAIN diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.xml similarity index 96% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.xml index 24e8392074f..a7190f30183 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.xml +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.xml @@ -22,6 +22,7 @@ https://logging.apache.org/xml/ns/log4j-config-2.xsd"> + + diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.yaml similarity index 96% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.yaml index 926447f64e6..046b09fc08a 100644 --- a/src/site/antora/modules/ROOT/examples/configuration/arbiters-select.yaml +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters-select.yaml @@ -19,6 +19,7 @@ Configuration: File: name: "MAIN" fileName: "logs/app.log" + # tag::select[] Select: SystemPropertyArbiter: # <1> propertyName: "env" @@ -26,6 +27,7 @@ Configuration: PatternLayout: {} DefaultArbiter: # <2> JsonTemplateLayout: {} + # end::select[] Loggers: Root: level: "INFO" diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.json b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/arbiters.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/arbiters.yaml diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.json b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/logger-properties.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/logger-properties.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/logger-properties.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/logger-properties.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/logger-properties.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/logger-properties.yaml diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.json b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/main-elements.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/main-elements.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/main-elements.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/main-elements.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/main-elements.yaml diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.json b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/properties.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/properties.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/properties.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/properties.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/properties.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/properties.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/properties.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/properties.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/properties.yaml diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.json b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/routing.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/routing.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/routing.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/routing.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/routing.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/routing.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/routing.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/routing.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/routing.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/routing.yaml diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.json b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/scripts.json rename to src/site/antora/modules/ROOT/examples/manual/configuration/scripts.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/scripts.properties rename to src/site/antora/modules/ROOT/examples/manual/configuration/scripts.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/scripts.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/scripts.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/scripts.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/scripts.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/scripts.yaml rename to src/site/antora/modules/ROOT/examples/manual/configuration/scripts.yaml diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-appenders.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/xinclude-appenders.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-appenders.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-loggers.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/xinclude-loggers.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-loggers.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-main.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/xinclude-main.xml rename to src/site/antora/modules/ROOT/examples/manual/configuration/xinclude-main.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.json b/src/site/antora/modules/ROOT/examples/manual/filters/filters.json similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/filters.json rename to src/site/antora/modules/ROOT/examples/manual/filters/filters.json diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.properties b/src/site/antora/modules/ROOT/examples/manual/filters/filters.properties similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/filters.properties rename to src/site/antora/modules/ROOT/examples/manual/filters/filters.properties diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.xml b/src/site/antora/modules/ROOT/examples/manual/filters/filters.xml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/filters.xml rename to src/site/antora/modules/ROOT/examples/manual/filters/filters.xml diff --git a/src/site/antora/modules/ROOT/examples/configuration/filters.yaml b/src/site/antora/modules/ROOT/examples/manual/filters/filters.yaml similarity index 100% rename from src/site/antora/modules/ROOT/examples/configuration/filters.yaml rename to src/site/antora/modules/ROOT/examples/manual/filters/filters.yaml diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 28b34bce31e..b7038547b7e 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -16,7 +16,6 @@ //// [id=configuration] = Configuration -Ralph Goers ; Piotr Karwasz Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. To decide which of these statements will be logged and where users need to configure Log4j Core. @@ -30,14 +29,12 @@ Since version 2.0 the configuration file format is considered as part of the pub [NOTE] ==== -To prevent a chicken-and-egg problem some configuration options (e.g., the configuration file location) can only be supplied through xref:manual/systemproperties.adoc[system properties]. +To prevent a chicken-and-egg problem some configuration options (e.g., the configuration file location) can only be supplied through xref:manual/systemproperties.adoc[configuration properties]. ==== [#configuration-file] == Configuration file -TIP: For a quick example of a configuration file see the xref:manual/installation.adoc#impl-core-config[Configuring Log4j Core section]. - Log4j Core can be configured using multiple configuration file formats. Configuration factories for the XML, JSON, YAML and Java properties formats are included in the `log4j-core` artifact. @@ -71,10 +68,12 @@ to the console. ==== The configuration files prefixed by `log4j2-test` should only be used on the test classpath. -If multiple configuration files in the same category are found, Log4j uses a deterministic order to choose one of them (cf. link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Order[@Order]). -Nevertheless, application developers are advised not to use multiple configuration files that differ only by the extension. +If multiple configuration files in the same category are found, Log4j uses a deterministic order to choose one of them (see link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Order[@Order]). +Nevertheless: + +* if you are developing an application you should not use configuration files that only differ by the extension, +* if you are developing a library you should only add configuration files to your test classpath. -Most libraries should not contain Log4j configuration files in their default location to allow applications to define their own. ==== The `` and `` placeholders above have the following meaning @@ -118,10 +117,14 @@ See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurat [id=configuration-syntax] === [[ConfigurationSyntax]] Syntax -All configuration files are parsed into a tree of link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node[Node]s, each representing a different Log4j component. +The Log4j runtime is composed of xref:manual/plugins.adoc[plugins], which are analogous to beans in Spring Framework and Java EE. +Appenders, layouts, filters, configuration loaders, etc. are all accessed as plugins. + +All configuration files are represented internally as a tree of +link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node[Node]s, which is translated into a tree of Log4j plugins. The root of the tree creates a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration[Configuration] object. -A node is a fairly simple structure that represents a single Log4j plugin (cf. xref:plugin-reference.adoc[] for a complete list) such as an appender, layout or logger configuration. +A node is a fairly simple structure that represents a single Log4j plugin (see xref:plugin-reference.adoc[] for a complete list) such as an appender, layout or logger configuration. Each node has: * a set of simple string key-value pairs called **attributes**. @@ -147,12 +150,12 @@ Since XML was the original configuration format developed, the mapping from conf + [NOTE] ==== -There is an alternative XML configuration format called "XML strict format" that is activated by setting the `strict` attribute of the main `` element to `true`. - +There is an alternative XML configuration format called "XML strict format" that is activated by setting the `strict` +attribute of the main `` element to `true`. It allows users to use arbitrary tag names as long as they provide the plugin type using a `type` property. -It was conceived as a simplified XML format that can be validated by an XML schema. -Nowadays, the automatically generated schemas published at https://logging.apache.org/xml/ns/ offer a better alternative and allow users to use the more concise syntax. +The _XML strict format_ was conceived as a simplified XML format that can be validated by an XML schema, but has fallen into disuse: nowadays, the automatically generated schemas published at https://logging.apache.org/xml/ns/ +offer a better alternative and allow users to use a more concise syntax. ==== JSON:: @@ -220,7 +223,6 @@ File: Java properties:: + -The Java properties format is not well suited to represent hierarchical structures. In the Java properties configuration format: + [id=configuration-with-properties] @@ -237,12 +239,11 @@ In the Java properties configuration format: [NOTE] ==== The ID assigned to nested components is only used for sorting purposes. -However, some components assign a special meaning to some IDs. -See a list of exceptions in <>. ==== - ===== +See also <> for exceptions to the rules above. + [id=main-configuration-elements] === Main configuration elements @@ -281,28 +282,28 @@ XML:: + [source,xml] ---- -include::example$configuration/main-elements.xml[lines=1;18..-1] +include::example$manual/configuration/main-elements.xml[lines=1;18..-1] ---- JSON:: + [source,json] ---- -include::example$configuration/main-elements.json[] +include::example$manual/configuration/main-elements.json[] ---- YAML:: + [source,yaml] ---- -include::example$configuration/main-elements.yaml[lines=17..-1] +include::example$manual/configuration/main-elements.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/main-elements.properties[lines=17..-1] +include::example$manual/configuration/main-elements.properties[lines=17..-1] ---- ==== @@ -392,14 +393,12 @@ See xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-lo |=== Determines the polling interval used by Log4j to check for changes to the configuration file. - If a change in the configuration file is detected, Log4j automatically reconfigures the logger context. - If set to `0`, polling is disabled. [CAUTION] ==== -Unlike other logging backends, Log4j Core is designed with **audit** logging in mind. +Unlike other logging backends, Log4j Core is designed with reliability in mind. During a reconfiguration process, no messages are lost. @@ -463,8 +462,11 @@ The logger components can have the following configuration attributes and elemen [cols="1h,5"] |=== -| Type | `String` -| Applies to | `Logger` and `AsyncLogger` +| Type +| `String` + +| Applies to +| `Logger` and `AsyncLogger` |=== Specifies the name of the logger configuration. @@ -481,19 +483,24 @@ Since loggers are usually named using fully qualified class names, this value us | Applies to | `Logger` and `AsyncLogger` |=== -If `true` (default), all the messages received by this logger will also be transmitted to its parent logger. +If `true` (default), all the messages received by this logger will also be transmitted to its +xref:manual/architecture.adoc#logger-hierarchy[parent logger]). [id=logger-attributes-level] ==== `level` [cols="1h,5"] |=== -| Type | link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] +| Type +| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[Level] + | Default value a| * xref:manual/systemproperties.adoc#log4j2.level[log4j2.level], for `Root` and `AsyncRoot`, -* inherited from the parent logger, for `Logger` and `AsyncLogger`. +* inherited from the +xref:manual/architecture.adoc#logger-hierarchy[parent logger], +for `Logger` and `AsyncLogger`. |=== Specifies the level threshold that a log event must have to be logged. @@ -506,7 +513,9 @@ See also xref:manual/filters.adoc#filters[Filters] if you require additional fil [cols="1h,5"] |=== -| Type | `boolean` +| Type +| `boolean` + | Default value a| * `false`, if an asynchronous `ContextSelector` is used. @@ -520,16 +529,12 @@ for more details. |=== Specifies whether Log4j is allowed to compute location information. +If set to `false`, Log4j will make no attempt to infer the location of the logging call, unless said location was provided explicitly using one of the available +https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/LogBuilder.html[LogBuilder +.withLocation()] +methods. -Computing the location information of a logging statement is an expensive operation (a couple of microseconds). -While Log4j makes every effort to only compute it if it was requested by a configured layout (cf. xref:manual/layouts.adoc[Layouts]), this setting provides a kill switch to disable it. - -[TIP] -==== -This setting only applies to the computation of location at **runtime**. - -If the location is computed at build time using link:/log4j/transform/latest/#log4j-transform-maven-plugin[Log4j Transform Maven Plugin] this setting is ignored and location information will always be available for logging. -==== +See xref:manual/layouts.adoc#location-information[Location information] for more details. [id=logger-elements-appenderrefs] ==== Appender references @@ -559,28 +564,28 @@ XML:: + [source,xml] ---- -include::example$configuration/logger-properties.xml[tag=loggers] +include::example$manual/configuration/logger-properties.xml[tag=loggers] ---- JSON:: + [source,json] ---- -include::example$configuration/logger-properties.json[tag=loggers] +include::example$manual/configuration/logger-properties.json[tag=loggers] ---- YAML:: + [source,yaml] ---- -include::example$configuration/logger-properties.yaml[tag=loggers] +include::example$manual/configuration/logger-properties.yaml[tag=loggers] ---- Java properties:: + [source,properties] ---- -include::example$configuration/logger-properties.properties[tag=loggers] +include::example$manual/configuration/logger-properties.properties[tag=loggers] ---- ==== @@ -637,28 +642,28 @@ XML:: + [source,xml] ---- -include::example$configuration/properties.xml[lines=1;18..24;26] +include::example$manual/configuration/properties.xml[lines=1;18..24;26] ---- JSON:: + [source,json] ---- -include::example$configuration/properties.json[] +include::example$manual/configuration/properties.json[] ---- YAML:: + [source,yaml] ---- -include::example$configuration/properties.yaml[lines=17..-1] +include::example$manual/configuration/properties.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/properties.properties[lines=17..-1] +include::example$manual/configuration/properties.properties[lines=17..-1] ---- ==== @@ -754,28 +759,28 @@ XML:: + [source,xml] ---- -include::example$configuration/routing.xml[tag=appender] +include::example$manual/configuration/routing.xml[tag=appender] ---- JSON:: + [source,json] ---- -include::example$configuration/routing.json[tag=appender] +include::example$manual/configuration/routing.json[tag=appender] ---- YAML:: + [source,yaml] ---- -include::example$configuration/routing.yaml[tag=appender] +include::example$manual/configuration/routing.yaml[tag=appender] ---- Java properties:: + [source,properties] ---- -include::example$configuration/routing.properties[tag=appender] +include::example$manual/configuration/routing.properties[tag=appender] ---- ==== @@ -810,28 +815,28 @@ XML:: + [source,xml] ---- -include::example$configuration/arbiters.xml[lines=1;18..-1] +include::example$manual/configuration/arbiters.xml[lines=1;18..-1] ---- JSON:: + [source,json] ---- -include::example$configuration/arbiters.json[] +include::example$manual/configuration/arbiters.json[] ---- YAML:: + [source,yaml] ---- -include::example$configuration/arbiters.yaml[lines=17..-1] +include::example$manual/configuration/arbiters.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/arbiters.properties[lines=17..-1] +include::example$manual/configuration/arbiters.properties[lines=17..-1] ---- ==== @@ -850,28 +855,28 @@ XML:: + [source,xml] ---- -include::example$configuration/arbiters-select.xml[lines=1;18..-1] +include::example$manual/configuration/arbiters-select.xml[tag=select] ---- JSON:: + [source,json] ---- -include::example$configuration/arbiters-select.json[] +include::example$manual/configuration/arbiters-select.json[tag=select] ---- YAML:: + [source,yaml] ---- -include::example$configuration/arbiters-select.yaml[lines=17..-1] +include::example$manual/configuration/arbiters-select.yaml[tag=select] ---- Java properties:: + [source,properties] ---- -include::example$configuration/arbiters-select.properties[lines=17..-1] +include::example$manual/configuration/arbiters-select.properties[tag=select] ---- ==== @@ -964,24 +969,31 @@ Here is an example log4j2.xml file that includes two other files: .log4j2.xml [source,xml] ---- -include::example$configuration/xinclude-main.xml[lines=1;18..-1] +include::example$manual/configuration/xinclude-main.xml[lines=1;18..-1] ---- .xinclude-appenders.xml [source,xml] ---- -include::example$configuration/xinclude-appenders.xml[lines=1;18..-1] +include::example$manual/configuration/xinclude-appenders.xml[lines=1;18..-1] ---- .xinclude-loggers.xml [source,xml] ---- -include::example$configuration/xinclude-loggers.xml[lines=1;18..-1] +include::example$manual/configuration/xinclude-loggers.xml[lines=1;18..-1] ---- [id=java-properties-features] ==== Java properties format +[TIP] +==== +The Java properties format is not well suited to represent hierarchical structures. + +Consider switching to XML, if you don't want additional dependencies, or YAML, if you are looking for a format similar to Java properties, but less verbose. +==== + The Java properties configuration format is by far the most verbose of the available formats. To make it more usable a series of exceptions to the rules in <> have been introduced over time: diff --git a/src/site/antora/modules/ROOT/pages/manual/filters.adoc b/src/site/antora/modules/ROOT/pages/manual/filters.adoc index 872e4ef4467..d841e27a6b9 100644 --- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc @@ -16,8 +16,8 @@ //// [id=filters] = Filters -Ralph Goers -Volkan Yazıcı + +Ralph Goers Volkan Yazıcı Log4j supports filtering of log events at each level of the logging pipeline using two features: @@ -40,30 +40,31 @@ XML:: + [source,xml] ---- -include::example$configuration/filters.xml[lines=1;18..-1] +include::example$manual/filters/filters.xml[lines=1;18..-1] ---- JSON:: + [source,json] ---- -include::example$configuration/filters.json[] +include::example$manual/filters/filters.json[] ---- YAML:: + [source,yaml] ---- -include::example$configuration/filters.yaml[lines=17..-1] +include::example$manual/filters/filters.yaml[lines=17..-1] ---- Java properties:: + [source,properties] ---- -include::example$configuration/filters.properties[lines=17..-1] +include::example$manual/filters/filters.properties[lines=17..-1] ---- ==== + <1> First the context-wide filter is consulted. If it returns `ACCEPT` the log message goes directly to point 3. <2> Then Log4j checks the message against the configured logger level. @@ -89,8 +90,7 @@ Using the `level` property of appender references will give a better performance [#BurstFilter] == BurstFilter -The BurstFilter provides a mechanism to control the rate at which -LogEvents are processed by silently discarding events after the maximum limit has been reached. +The BurstFilter provides a mechanism to control the rate at which LogEvents are processed by silently discarding events after the maximum limit has been reached. .Burst Filter Parameters [cols="1m,1,4"] @@ -152,9 +152,9 @@ A configuration containing the BurstFilter might look like: [#CompositeFilter] == CompositeFilter -The CompositeFilter provides a way to specify more than one filter. It -is added to the configuration as a filter element and contains other -filters to be evaluated. The filter element accepts no parameters. +The CompositeFilter provides a way to specify more than one filter. +It is added to the configuration as a filter element and contains other filters to be evaluated. +The filter element accepts no parameters. A configuration containing the CompositeFilter might look like: @@ -198,11 +198,9 @@ A configuration containing the CompositeFilter might look like: [#DynamicThresholdFilter] == DynamicThresholdFilter -The DynamicThresholdFilter allows filtering by log level based on -specific attributes. For example, if the user's loginId is being -captured in the ThreadContext Map then it is possible to enable debug -logging for only that user. If the log event does not contain the -specified ThreadContext item NEUTRAL will be returned. +The DynamicThresholdFilter allows filtering by log level based on specific attributes. +For example, if the user's loginId is being captured in the ThreadContext Map then it is possible to enable debug logging for only that user. +If the log event does not contain the specified ThreadContext item NEUTRAL will be returned. .Dynamic Threshold Filter Parameters [cols="1m,1,4"] @@ -317,8 +315,7 @@ The filter will return `onMismatch` result (i.e., `DENY`, the default) for log e [#MapFilter] == MapFilter -The MapFilter allows filtering against data elements that are in a -MapMessage. +The MapFilter allows filtering against data elements that are in a MapMessage. .Map Filter Parameters [cols="1m,1,4"] @@ -349,8 +346,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -As in this configuration, the MapFilter can be used to log particular -events: +As in this configuration, the MapFilter can be used to log particular events: [source,xml] ---- @@ -378,8 +374,7 @@ events: ---- -This sample configuration will exhibit the same behavior as the -preceding example since the only logger configured is the root. +This sample configuration will exhibit the same behavior as the preceding example since the only logger configured is the root. [source,xml] ---- @@ -408,9 +403,7 @@ preceding example since the only logger configured is the root. ---- -This third sample configuration will exhibit the same behavior as the -preceding examples since the only logger configured is the root and the -root is only configured with a single appender reference. +This third sample configuration will exhibit the same behavior as the preceding examples since the only logger configured is the root and the root is only configured with a single appender reference. [source,xml] ---- @@ -442,9 +435,8 @@ root is only configured with a single appender reference. [#MarkerFilter] == MarkerFilter -The MarkerFilter compares the configured Marker value against the Marker -that is included in the LogEvent. A match occurs when the Marker name -matches either the Log Event's Marker or one of its parents. +The MarkerFilter compares the configured Marker value against the Marker that is included in the LogEvent. +A match occurs when the Marker name matches either the Log Event's Marker or one of its parents. .Marker Filter Parameters [cols="1m,1,4"] @@ -466,8 +458,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if the Marker matches: +A sample configuration that only allows the event to be written by the appender if the Marker matches: [source,xml] ---- @@ -494,7 +485,9 @@ appender if the Marker matches: [#MutableThreadContextMapFilter] == MutableThreadContextMapFilter -The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. By default, this is the ThreadContext Map. The values to compare are defined externally and can be periodically polled for changes. +The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. +By default, this is the ThreadContext Map. +The values to compare are defined externally and can be periodically polled for changes. .Mutable Context Map Filter Parameters [cols="1m,1,4"] @@ -526,8 +519,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if the Marker matches: +A sample configuration that only allows the event to be written by the appender if the Marker matches: [source,xml] ---- @@ -553,6 +545,7 @@ appender if the Marker matches: ---- The configuration file supplied to the filter should look similar to: + [source,json] ---- { @@ -566,7 +559,7 @@ The configuration file supplied to the filter should look similar to: [#NoMarkerFilter] == NoMarkerFilter -The NoMarkerFilter checks that there is no marker included in the LogEvent. +The NoMarkerFilter checks that there is no marker included in the LogEvent. A match occurs when there is no marker in the Log Event. .No Marker Filter Parameters @@ -585,8 +578,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if no marker is there: +A sample configuration that only allows the event to be written by the appender if no marker is there: [source,xml] ---- @@ -613,8 +605,7 @@ appender if no marker is there: [#RegexFilter] == RegexFilter -The RegexFilter allows the formatted or unformatted message to be -compared against a regular expression. +The RegexFilter allows the formatted or unformatted message to be compared against a regular expression. .Regex Filter Parameters [cols="1m,1,4"] @@ -642,8 +633,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if it contains the word "test": +A sample configuration that only allows the event to be written by the appender if it contains the word "test": [source,xml] ---- @@ -668,7 +658,6 @@ appender if it contains the word "test": ---- [[Script]] - The ScriptFilter executes a script that returns true or false. .Script Filter Parameters @@ -743,11 +732,9 @@ Throwable as part of the Message. |The StrSubstitutor is used to replace lookup variables. |=== -The sample below shows how to declare script fields and then reference -them in specific components. See -xref:manual/appenders.adoc#ScriptCondition[ScriptCondition] for an example of -how the `ScriptPlugin` element can be used to embed script code directly in -the configuration. +The sample below shows how to declare script fields and then reference them in specific components. +See +xref:manual/appenders.adoc#ScriptCondition[ScriptCondition] for an example of how the `ScriptPlugin` element can be used to embed script code directly in the configuration. [source,xml] ---- @@ -788,8 +775,7 @@ the configuration. [#StructuredDataFilter] == StructuredDataFilter -The StructuredDataFilter is a MapFilter that also allows filtering on -the event id, type and message. +The StructuredDataFilter is a MapFilter that also allows filtering on the event id, type and message. .StructuredData Filter Parameters [cols="1m,1,4"] @@ -823,8 +809,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -As in this configuration, the StructuredDataFilter can be used to log -particular events: +As in this configuration, the StructuredDataFilter can be used to log particular events: [source,xml] ---- @@ -855,9 +840,8 @@ particular events: [#ThreadContextMapFilter] == ThreadContextMapFilter -The ThreadContextMapFilter or ContextMapFilter allows filtering against -data elements that are in the current context. By default, this is the -ThreadContext Map. +The ThreadContextMapFilter or ContextMapFilter allows filtering against data elements that are in the current context. +By default, this is the ThreadContext Map. .Context Map Filter Parameters [cols="1m,1,4"] @@ -948,10 +932,9 @@ The ContextMapFilter can also be applied to a logger for filtering: [#ThresholdFilter] == ThresholdFilter -This filter returns the onMatch result if the level in the LogEvent is -the same or more specific than the configured level and the `onMismatch` -value otherwise. For example, if the ThresholdFilter is configured with -Level ERROR and the LogEvent contains Level DEBUG then the `onMismatch` +This filter returns the onMatch result if the level in the LogEvent is the same or more specific than the configured level and the `onMismatch` +value otherwise. +For example, if the ThresholdFilter is configured with Level ERROR and the LogEvent contains Level DEBUG then the `onMismatch` value will be returned since ERROR events are more specific than DEBUG. .Threshold Filter Parameters @@ -974,8 +957,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender if the level matches: +A sample configuration that only allows the event to be written by the appender if the level matches: [source,xml] ---- @@ -1002,8 +984,7 @@ appender if the level matches: [#TimeFilter] == TimeFilter -The time filter can be used to restrict the filter to only a certain portion -of the day. +The time filter can be used to restrict the filter to only a certain portion of the day. .Time Filter Parameters [cols="1m,1,4"] @@ -1035,8 +1016,7 @@ DENY or NEUTRAL. The default value is NEUTRAL. be ACCEPT, DENY or NEUTRAL. The default value is DENY. |=== -A sample configuration that only allows the event to be written by the -appender from 5:00 to 5:30 am each day using the default timezone: +A sample configuration that only allows the event to be written by the appender from 5:00 to 5:30 am each day using the default timezone: [source,xml] ---- diff --git a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc index 1859d2b4c9d..a890f45049b 100644 --- a/src/site/antora/modules/ROOT/pages/manual/layouts.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/layouts.adoc @@ -17,25 +17,39 @@ = Layouts Ralph Goers ; Gary Gregory ; Volkan Yazıcı -An Appender uses a Layout to format a LogEvent into a form that meets -the needs of whatever will be consuming the log event. In Log4j 1.x and -Logback Layouts were expected to transform an event into a String. In -Log4j 2 Layouts return a byte array. This allows the result of the -Layout to be useful in many more types of Appenders. However, this means -you need to configure most Layouts with a +An Appender uses a Layout to format a LogEvent into a form that meets the needs of whatever will be consuming the log event. +In Log4j 1.x and Logback Layouts were expected to transform an event into a String. +In Log4j 2 Layouts return a byte array. +This allows the result of the Layout to be useful in many more types of Appenders. +However, this means you need to configure most Layouts with a https://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html[`Charset`] to ensure the byte array contains correct values. The root class for layouts that use a Charset is -`org.apache.logging.log4j.core.layout.AbstractStringLayout` where the -default is UTF-8. Each layout that extends `AbstractStringLayout` can -provide its own default. See each layout below. +`org.apache.logging.log4j.core.layout.AbstractStringLayout` where the default is UTF-8. Each layout that extends `AbstractStringLayout` can provide its own default. +See each layout below. -A custom character encoder was added to Log4j 2.4.1 for the ISO-8859-1 -and US-ASCII charsets, to bring some of the performance improvements -built-in to Java 8 to Log4j for use on Java 7. For applications that log -only ISO-8859-1 characters, specifying this charset will improve -performance significantly. +A custom character encoder was added to Log4j 2.4.1 for the ISO-8859-1 and US-ASCII charsets, to bring some of the performance improvements built-in to Java 8 to Log4j for use on Java 7. For applications that log only ISO-8859-1 characters, specifying this charset will improve performance significantly. + +[#common-concerns] +== Common concerns + +[#location-information] +=== Location information + +Computing the location information of a logging statement is an expensive operation. +For this reason many Log4j components implement the +link:../javadoc/log4j-core/org/apache/logging/log4j/core/impl/LocationAware.html[LocationAware] +interface to only compute location information when needed. + +While the methods of determining if location information is required are specific to each layout, most layouts implement `LocationAware`. + +[NOTE] +==== +Even if a layout is configured not to **request** location information, it might use it if the information is already available. +This is always the case of information location computed at build time using the +link:/log4j/transform/latest/#log4j-transform-maven-plugin[Log4j Transform Maven Plugin]. +==== [#CSVLayouts] == CSV Layouts @@ -49,14 +63,11 @@ Value (CSV)] records and requires https://commons.apache.org/proper/commons-csv/[Apache Commons CSV] 1.4. The CSV layout can be used in two ways: First, using -`CsvParameterLayout` to log event parameters to create a custom -database, usually to a logger and file appender uniquely configured for -this purpose. Second, using `CsvLogEventLayout` to log events to create -a database, as an alternative to using a full DBMS or using a JDBC driver that supports the CSV format. +`CsvParameterLayout` to log event parameters to create a custom database, usually to a logger and file appender uniquely configured for this purpose. +Second, using `CsvLogEventLayout` to log events to create a database, as an alternative to using a full DBMS or using a JDBC driver that supports the CSV format. -The `CsvParameterLayout` converts an event's parameters into a CSV -record, ignoring the message. To log CSV records, you can use the usual -Logger methods `info()`, `debug()`, and so on: +The `CsvParameterLayout` converts an event's parameters into a CSV record, ignoring the message. +To log CSV records, you can use the usual Logger methods `info()`, `debug()`, and so on: [source,java] ---- @@ -69,16 +80,14 @@ Which will create the CSV record: value1, value2, value3 .... -Alternatively, you can use an `ObjectArrayMessage`, which only carries -parameters: +Alternatively, you can use an `ObjectArrayMessage`, which only carries parameters: [source,java] ---- logger.info(new ObjectArrayMessage(value1, value2, value3)); ---- -The layouts `CsvParameterLayout` and `CsvLogEventLayout` are configured -with the following parameters: +The layouts `CsvParameterLayout` and `CsvLogEventLayout` are configured with the following parameters: .CsvParameterLayout and CsvLogEventLayout [cols="1m,1,4"] @@ -139,15 +148,15 @@ logger.debug("one={}, two={}, three={}", 1, 2, 3); Produces a CSV record with the following fields: -1. Time Nanos -2. Time Millis -3. Level -4. Thread ID -5. Thread Name -6. Thread Priority -7. Formatted Message -8. Logger FQCN -9. Logger Name +1. Time Nanos +2. Time Millis +3. Level +4. Thread ID +5. Thread Name +6. Thread Priority +7. Formatted Message +8. Logger FQCN +9. Logger Name 10. Marker 11. Thrown Proxy 12. Source @@ -158,15 +167,15 @@ Produces a CSV record with the following fields: 0,1441617184044,DEBUG,main,"one=1, two=2, three=3",org.apache.logging.log4j.spi.AbstractLogger,,,,org.apache.logging.log4j.core.layout.CsvLogEventLayoutTest.testLayout(CsvLogEventLayoutTest.java:98),{},[] .... -Additional xref:runtime-dependencies.adoc[runtime dependencies] are -required for using CSV layouts. +Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using CSV layouts. [#GELFLayout] == GELF Layout Lays out events in the Graylog Extended Log Format (GELF) 1.1. -This layout compresses JSON to GZIP or ZLIB (`compressionType`) if log event data is larger than 1024 bytes (`compressionThreshold`). This layout does not implement chunking. +This layout compresses JSON to GZIP or ZLIB (`compressionType`) if log event data is larger than 1024 bytes (`compressionThreshold`). +This layout does not implement chunking. Configure as follows to send to a Graylog 2.x server with UDP: @@ -222,18 +231,17 @@ To include any custom field in the output, use following syntax: ---- -Custom fields are included in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are included in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. See also: * The https://docs.graylog.org/en/latest/pages/gelf.html#gelf[GELF specification] - [#HTMLLayout] == HTML Layout -The HtmlLayout generates an HTML page and adds each LogEvent to a row in -a table. +The HtmlLayout generates an HTML page and adds each LogEvent to a row in a table. .HtmlLayout Parameters [cols="1m,1,4"] @@ -286,6 +294,7 @@ https://docs.oracle.com/javase/6/docs/api/java/util/TimeZone.html#getTimeZone(ja |=== Configure as follows to use `dataPattern` and timezone in `HtmlLayout`: + [source,xml] ---- @@ -298,13 +307,15 @@ Configure as follows to use `dataPattern` and timezone in `HtmlLayout`: [[JSONLayout]] == JSON Layout -NOTE: JsonTemplate is considered deprecated. JsonTemplateLayout provides more capabilities and should be used instead. +NOTE: JsonTemplate is considered deprecated. +JsonTemplateLayout provides more capabilities and should be used instead. Appends a series of JSON events as strings serialized as bytes. === Complete well-formed JSON vs. fragment JSON -If you configure `complete="true"`, the appender outputs a well-formed JSON document. By default, with `complete="false"`, you should include the output as an _external file_ in a separate file to form a well-formed JSON document. +If you configure `complete="true"`, the appender outputs a well-formed JSON document. +By default, with `complete="false"`, you should include the output as an _external file_ in a separate file to form a well-formed JSON document. If `complete="false"`, the appender does not write the JSON open array character "[" at the start of the document, "]" at the end, nor comma "," between records. @@ -370,7 +381,10 @@ Log event follows this pattern: === Pretty vs. compact JSON -The compact attribute determines whether the output will be "pretty" or not. The default value is "false", which means the appender uses end-of-line characters and indent lines to format the text. If `compact="true"`, then no end-of-line or indentation is used, which will cause the output to take less space. Of course, the message content may contain, escaped end-of-lines. +The compact attribute determines whether the output will be "pretty" or not. +The default value is "false", which means the appender uses end-of-line characters and indent lines to format the text. +If `compact="true"`, then no end-of-line or indentation is used, which will cause the output to take less space. +Of course, the message content may contain, escaped end-of-lines. [options="header"] |=== @@ -400,18 +414,17 @@ To include any custom field in the output, use the following syntax: ---- -Custom fields are always last, in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are always last, in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using JsonLayout. - [#JSONTemplateLayout] == JSON Template Layout -`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON-emitting layout. -It encodes ``LogEvent``s according to the structure described -by the JSON template provided. For instance, given the following JSON template -modelling https://github.com/logstash/log4j-jsonevent-layout[the official +`JsonTemplateLayout` is a customizable, efficient, and garbage-free JSON-emitting layout. +It encodes ``LogEvent``s according to the structure described by the JSON template provided. +For instance, given the following JSON template modelling https://github.com/logstash/log4j-jsonevent-layout[the official Logstash `JSONEventLayoutV1`] [source,json] @@ -508,33 +521,28 @@ JSON Template Layout will render JSON documents as follows: } ---- -See xref:manual/json-template-layout.adoc[JSON Template Layout] page for the complete -documentation. +See xref:manual/json-template-layout.adoc[JSON Template Layout] page for the complete documentation. [id=pattern-layout] == [[PatternLayout]] Pattern Layout -A flexible layout is configurable with a pattern string. The goal of this -class is to format a LogEvent and return the results. The format of the -result depends on the _conversion pattern_. +A flexible layout is configurable with a pattern string. +The goal of this class is to format a LogEvent and return the results. +The format of the result depends on the _conversion pattern_. -The conversion pattern is closely related to the conversion pattern of -the `printf()` function in C. A conversion pattern is composed of literal -text and format control expressions called _conversion specifiers_. +The conversion pattern is closely related to the conversion pattern of the `printf()` function in C. A conversion pattern is composed of literal text and format control expressions called _conversion specifiers_. -_Note that any literal text, including *Special Characters*, may be -included in the conversion pattern._ Special Characters include *\t*, -*\n*, *\r*, *\f*. Use *\\* to insert a single backslash into the output. +_Note that any literal text, including *Special Characters*, may be included in the conversion pattern._ Special Characters include *\t*, +*\n*, *\r*, *\f*. +Use *\\* to insert a single backslash into the output. -Each conversion specifier starts with a percent sign (%) and is followed -by optional _format modifiers_ and a _conversion character_. The -conversion character specifies the type of data, e.g. category, -priority, date, thread name. The format modifiers control such things as -field width, padding, and left and right justification. The following is a -simple example. +Each conversion specifier starts with a percent sign (%) and is followed by optional _format modifiers_ and a _conversion character_. +The conversion character specifies the type of data, e.g. category, priority, date, thread name. +The format modifiers control such things as field width, padding, and left and right justification. +The following is a simple example. -Let the conversion pattern be *"%-5p [%t]: %m%n"* and assume that the -Log4j environment was set to use a PatternLayout. Then the statements +Let the conversion pattern be *"%-5p [%t]: %m%n"* and assume that the Log4j environment was set to use a PatternLayout. +Then the statements .... Logger logger = LogManager.getLogger("MyLogger"); @@ -549,17 +557,12 @@ DEBUG [main]: Message 1 WARN [main]: Message 2 .... -Note that there is no explicit separator between text and conversion -specifiers. The pattern parser knows when it has reached the end of a -conversion specifier when it reads a conversion character. In the -example above the conversion specifier `%-5p` means the priority of the -logging event should be left justified to a width of five characters. +Note that there is no explicit separator between text and conversion specifiers. +The pattern parser knows when it has reached the end of a conversion specifier when it reads a conversion character. +In the example above the conversion specifier `%-5p` means the priority of the logging event should be left justified to a width of five characters. -If the pattern string does not contain a specifier to handle a Throwable -being logged, parsing of the pattern will act as if the `%xEx` specifier -had been added to the end of the string. To suppress the formatting of the -Throwable completely simply add `%ex\{0}` as a specifier in the pattern -string. +If the pattern string does not contain a specifier to handle a Throwable being logged, parsing of the pattern will act as if the `%xEx` specifier had been added to the end of the string. +To suppress the formatting of the Throwable completely simply add `%ex\{0}` as a specifier in the pattern string. .PatternLayout Parameters [cols="1m,1,4"] @@ -834,7 +837,7 @@ involved. Log4j 2.11 adds limited support for timestamps more precise than milliseconds when running on Java 9. Note that not all https://docs.oracle.com/javase/9/docs/api/java/time/format/DateTimeFormatter.html[DateTimeFormatter] -formats are supported. Only timestamps in the formats mentioned in the table +formats are supported. Only timestamps in the formats mentioned in the table above may use the "nano-of-second" pattern letter `n` instead of the "fraction-of-second" pattern letter `S`. @@ -846,7 +849,7 @@ Java 9 by setting system property `log4j2.Clock` to `SystemMillisClock`. |Encodes and escapes special characters suitable for output in specific markup languages. By default, this encodes for HTML if only one option is specified. The second option is used to specify which encoding format -should be used. This converter is particularly useful for encoding user-provided +should be used. This converter is particularly useful for encoding user-provided data so that the output data is not written improperly or insecurely. A typical usage would encode the message `%enc{%m}` but user input could @@ -1081,7 +1084,7 @@ The STYLE value can be one of: link:../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html[MapMessage], if one is present in the event. The `K` conversion character can be followed by the key for the map placed between braces, as in -`%K\{clientNumber}` where `clientNumber` is the key. The value of the Map +`%K\{clientNumber}` where `clientNumber` is the key. The value of the Map corresponding to the key will be output. If no additional sub-option is specified, then the entire contents of the Map key-value pair set is output using a format {{key1,val1},{key2,val2}} @@ -1463,8 +1466,8 @@ key that is present in the ThreadContext will be output using the format {name=val1, number=val2}. The key/value pairs will be printed in the order they appear in the list. -If no sub-options are specified then the entire contents of the MDC key-value pair -set is output using a format {key1=val1, key2=val2}. +If no sub-options are specified then the entire contents of the MDC key-value pair +set is output using a format {key1=val1, key2=val2}. The key/value pairs will be printed in sorted order. See the @@ -1476,7 +1479,7 @@ class for more details. |Includes either a random or a time-based UUID. The time-based UUID is a Type 1 UUID that can generate up to 10,000 unique IDs per millisecond will use the MAC address of each host, and to try to insure -uniqueness across multiple JVMs and/or ClassLoaders on the same host +uniqueness across multiple JVMs and/or ClassLoaders on the same host a random number between 0 and 16,384 will be associated with each instance of the UUID generator Class and included in each time-based UUID generated. Because time-based UUIDs contain the MAC address and @@ -1562,41 +1565,31 @@ print. |The sequence %% outputs a single percent sign. |=== -By default, the relevant information is output as is. However, with -the aid of format modifiers it is possible to change the minimum field -width, the maximum field width and justification. +By default, the relevant information is output as is. +However, with the aid of format modifiers it is possible to change the minimum field width, the maximum field width and justification. -The optional format modifier is placed between the percent sign and the -conversion character. +The optional format modifier is placed between the percent sign and the conversion character. The first optional format modifier is the _left justification flag_ -which is just the minus (-) character. Then comes the optional _minimum -field width_ modifier. This is a decimal constant that represents the -minimum number of characters to output. If the data item requires fewer -characters, it is padded on either the left or the right until the -minimum width is reached. The default is to pad on the left (right -justify) but you can specify right padding with the left justification -flag. The padding character is space. If the data item is larger than -the minimum field width, the field is expanded to accommodate the data. -The value is never truncated. To use zeros as the padding character prepend -the _minimum field width_ with a zero. - -This behavior can be changed using the _maximum field width_ modifier -which is designated by a period followed by a decimal constant. If the -data item is longer than the maximum field, then the extra characters -are removed from the _beginning_ of the data item and not from the end. -For example, if the maximum field width is eight and the data item is -ten characters long, then the first two characters of the data item are -dropped. This behavior deviates from the `printf()` function in C where -truncation is done from the end. - -Truncation from the end is possible by appending a minus character right -after the period. In that case, if the maximum field width is eight and -the data item is ten characters long, then the last two characters of -the data item are dropped. - -Below are various format modifier examples for the category conversion -specifier. +which is just the minus (-) character. +Then comes the optional _minimum field width_ modifier. +This is a decimal constant that represents the minimum number of characters to output. +If the data item requires fewer characters, it is padded on either the left or the right until the minimum width is reached. +The default is to pad on the left (right justify) but you can specify right padding with the left justification flag. +The padding character is space. +If the data item is larger than the minimum field width, the field is expanded to accommodate the data. +The value is never truncated. +To use zeros as the padding character prepend the _minimum field width_ with a zero. + +This behavior can be changed using the _maximum field width_ modifier which is designated by a period followed by a decimal constant. +If the data item is longer than the maximum field, then the extra characters are removed from the _beginning_ of the data item and not from the end. +For example, if the maximum field width is eight and the data item is ten characters long, then the first two characters of the data item are dropped. +This behavior deviates from the `printf()` function in C where truncation is done from the end. + +Truncation from the end is possible by appending a minus character right after the period. +In that case, if the maximum field width is eight and the data item is ten characters long, then the last two characters of the data item are dropped. + +Below are various format modifier examples for the category conversion specifier. .Pattern Converters |=== @@ -1650,25 +1643,21 @@ characters, then truncate from the end. [#enable-jansi] === ANSI Styling on Windows -ANSI escape sequences are supported natively on many platforms but are -not by default on Windows. To enable ANSI support add the -http://jansi.fusesource.org/[Jansi] jar to your application and set -property `log4j.skipJansi` to `false`. This allows Log4j to use Jansi to -add ANSI escape codes when writing to the console. +ANSI escape sequences are supported natively on many platforms but are not by default on Windows. +To enable ANSI support add the +http://jansi.fusesource.org/[Jansi] jar to your application and set property `log4j.skipJansi` to `false`. +This allows Log4j to use Jansi to add ANSI escape codes when writing to the console. -NOTE: Before Log4j 2.10, Jansi was enabled by default. The fact that -Jansi requires native code means that Jansi can only be loaded by a -single class loader. For web applications, this means the Jansi jar has -to be in the web container's classpath. To avoid causing problems for -web applications, Log4j will no longer automatically try to load Jansi -without explicit configuration from Log4j 2.10 onward. +NOTE: Before Log4j 2.10, Jansi was enabled by default. +The fact that Jansi requires native code means that Jansi can only be loaded by a single class loader. +For web applications, this means the Jansi jar has to be in the web container's classpath. +To avoid causing problems for web applications, Log4j will no longer automatically try to load Jansi without explicit configuration from Log4j 2.10 onward. === Example Patterns ==== Filtered Throwables -This example shows how to filter out classes from unimportant packages -in stack traces. +This example shows how to filter out classes from unimportant packages in stack traces. [source,xml] ---- @@ -1709,20 +1698,14 @@ All the content that follows the level will be bright green. [#PatternSelectors] === Pattern Selectors -The PatternLayout can be configured with a PatternSelector to allow it -to choose a pattern to use based on attributes of the log event or other -factors. A PatternSelector will normally be configured with a -defaultPattern attribute, which is used when other criteria don't match, -and a set of PatternMatch elements that identify the various patterns -that can be selected. +The PatternLayout can be configured with a PatternSelector to allow it to choose a pattern to use based on attributes of the log event or other factors. +A PatternSelector will normally be configured with a defaultPattern attribute, which is used when other criteria don't match, and a set of PatternMatch elements that identify the various patterns that can be selected. [#LevelPatternSelector] ==== LevelPatternSelector -The LevelPatternSelector selects patterns based on the log level of -the log event. If the Level in the log event is equal to (ignoring case) -the name specified on the PatternMatch key attribute, then -the pattern specified on that PatternMatch element will be used. +The LevelPatternSelector selects patterns based on the log level of the log event. +If the Level in the log event is equal to (ignoring case) the name specified on the PatternMatch key attribute, then the pattern specified on that PatternMatch element will be used. [source,xml] ---- @@ -1736,10 +1719,8 @@ the pattern specified on that PatternMatch element will be used. [#MarkerPatternSelector] ==== MarkerPatternSelector -The MarkerPatternSelector selects patterns based on the Marker included -in the log event. If the Marker in the log event is equal to or is an -ancestor of the name specified on the PatternMatch key attribute, then -the pattern specified on that PatternMatch element will be used. +The MarkerPatternSelector selects patterns based on the Marker included in the log event. +If the Marker in the log event is equal to or is an ancestor of the name specified on the PatternMatch key attribute, then the pattern specified on that PatternMatch element will be used. [source,xml] ---- @@ -1754,13 +1735,8 @@ the pattern specified on that PatternMatch element will be used. ==== ScriptPatternSelector The ScriptPatternSelector executes a script as described in the -xref:manual/configuration.adoc#Scripts[Scripts] section of the Configuration -chapter. The script is passed all the properties configured in the -Properties section of the configuration, the StrSubstitutor used by the -Configuration in the "substitutor" variables, and the log event in the -"logEvent" variable, and is expected to return the value of the -PatternMatch key that should be used, or null if the default pattern -should be used. +xref:manual/configuration.adoc#Scripts[Scripts] section of the Configuration chapter. +The script is passed all the properties configured in the Properties section of the configuration, the StrSubstitutor used by the Configuration in the "substitutor" variables, and the log event in the "logEvent" variable, and is expected to return the value of the PatternMatch key that should be used, or null if the default pattern should be used. [source,xml] ---- @@ -1784,11 +1760,8 @@ should be used. [#RFC5424Layout] == RFC5424 Layout -As the name implies, the Rfc5424Layout formats LogEvents by http://tools.ietf.org/html/rfc5424[RFC 5424], the enhanced Syslog specification. -Although the specification is primarily directed at -sending messages via Syslog, this format is quite useful for other -purposes since items are passed in the message as self-describing -key/value pairs. +As the name implies, the Rfc5424Layout formats LogEvents by http://tools.ietf.org/html/rfc5424[RFC 5424], the enhanced Syslog specification. +Although the specification is primarily directed at sending messages via Syslog, this format is quite useful for other purposes since items are passed in the message as self-describing key/value pairs. .Rfc5424Layout Parameters [cols="1m,1,4"] @@ -1831,7 +1804,7 @@ specified as upper or lowercase characters. |format |String -|If set to "RFC5424" the data will be formatted by RFC 5424. +|If set to "RFC5424" the data will be formatted by RFC 5424. Otherwise, it will be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be 1024 bytes or shorter the SyslogLayout does not truncate them. The @@ -1881,7 +1854,7 @@ thrown. This attribute only applies to RFC 5424 syslog records. |mdcPrefix |String -|A string that should be prepended to each MDC key to distinguish it from event attributes. +|A string that should be prepended to each MDC key to distinguish it from event attributes. The default string is "mdc:". This attribute only applies to RFC 5424 syslog records. |mdcId @@ -1904,18 +1877,15 @@ The default string is "mdc:". This attribute only applies to RFC 5424 syslog rec [#SerializedLayout] == Serialized Layout -The SerializedLayout simply serializes the LogEvent into a byte array -using Java Serialization. The SerializedLayout accepts no parameters. +The SerializedLayout simply serializes the LogEvent into a byte array using Java Serialization. +The SerializedLayout accepts no parameters. -This layout has been deprecated since version 2.9. Java Serialization has -inherent security weaknesses, using this layout is no longer -recommended. +This layout has been deprecated since version 2.9. Java Serialization has inherent security weaknesses, using this layout is no longer recommended. [#SyslogLayout] == Syslog Layout -The SyslogLayout formats the LogEvent as BSD Syslog records matching the -the same format used by Log4j 1.2. +The SyslogLayout formats the LogEvent as BSD Syslog records matching the the same format used by Log4j 1.2. .SyslogLayout Parameters [cols="1m,1,4"] @@ -1954,7 +1924,8 @@ within the message text. === Complete well-formed XML vs. fragment XML -If you configure `complete="true"`, the appender outputs a well-formed XML document where the default namespace is the Log4j namespace `https://logging.apache.org/log4j/2.0/events`. By default, with `complete="false"`, you should include the output as an _external entity_ in a separate file to form a well-formed XML document, in which case the appender uses `namespacePrefix` with a default of `log4j`. +If you configure `complete="true"`, the appender outputs a well-formed XML document where the default namespace is the Log4j namespace `https://logging.apache.org/log4j/2.0/events`. +By default, with `complete="false"`, you should include the output as an _external entity_ in a separate file to form a well-formed XML document, in which case the appender uses `namespacePrefix` with a default of `log4j`. A well-formed XML document follows this pattern: @@ -2011,11 +1982,15 @@ If `complete="false"`, the appender does not write the XML processing instructio === Marker -Markers are represented by a `Marker` element within the `Event` element. The `Marker` element appears only when a marker is used in the log message. The name of the marker's parent will be provided in the `parent` attribute of the `Marker` element. +Markers are represented by a `Marker` element within the `Event` element. +The `Marker` element appears only when a marker is used in the log message. +The name of the marker's parent will be provided in the `parent` attribute of the `Marker` element. === Pretty vs. compact XML -By default, the XML layout is not compact (a.k.a. not "pretty") with `compact="false"`, which means the appender uses end-of-line characters and indent lines to format the XML. If `compact="true"`, then no end-of-line or indentation is used. Message content may contain, of course, end-of-lines. +By default, the XML layout is not compact (a.k.a. not "pretty") with `compact="false"`, which means the appender uses end-of-line characters and indent lines to format the XML. +If `compact="true"`, then no end-of-line or indentation is used. +Message content may contain, of course, end-of-lines. [options="header"] |=== @@ -2040,7 +2015,8 @@ To include any custom field in the output, use the following syntax: ---- -Custom fields are always last, in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are always last, in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. NOTE: Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using XmlLayout. @@ -2116,34 +2092,27 @@ To include any custom field in the output, use the following syntax: ---- -Custom fields are always last, in the order they are declared. The values support xref:manual/lookups.adoc[lookups]. +Custom fields are always last, in the order they are declared. +The values support xref:manual/lookups.adoc[lookups]. NOTE: Additional xref:runtime-dependencies.adoc[runtime dependencies] are required for using YamlLayout. - [#LocationInformation] == Location Information -If one of the layouts is configured with a location-related attribute -like HTML link:#HtmlLocationInfo[locationInfo], or one of the patterns +If one of the layouts is configured with a location-related attribute like HTML link:#HtmlLocationInfo[locationInfo], or one of the patterns link:#PatternClass[%C or %class], link:#PatternFile[%F or %file], link:#PatternLocation[%l or %location], link:#PatternLine[%L or %line], -link:#PatternMethod[%M or %method], Log4j will take a snapshot of the -stack, and walk the stack trace to find the location information. - -This is an expensive operation: 1.3 - 5 times slower for synchronous -loggers. Synchronous loggers wait as long as possible before they take -this stack snapshot. If no location is required, the snapshot will never -be taken. - -However, asynchronous loggers need to make this decision before passing -the log message to another thread; the location information will be lost -after that point. The -xref:manual/performance.adoc#asyncLoggingWithLocation[performance impact] of -taking a stack trace snapshot is even higher for asynchronous loggers: -logging with location is 30-100 times slower than without location. For -this reason, asynchronous loggers and asynchronous appenders do not -include location information by default. - -You can override the default behavior in your logger or asynchronous -appender configuration by specifying `includeLocation="true"`. +link:#PatternMethod[%M or %method], Log4j will take a snapshot of the stack, and walk the stack trace to find the location information. + +This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. +Synchronous loggers wait as long as possible before they take this stack snapshot. +If no location is required, the snapshot will never be taken. + +However, asynchronous loggers need to make this decision before passing the log message to another thread; the location information will be lost after that point. +The +xref:manual/performance.adoc#asyncLoggingWithLocation[performance impact] of taking a stack trace snapshot is even higher for asynchronous loggers: +logging with location is 30-100 times slower than without location. +For this reason, asynchronous loggers and asynchronous appenders do not include location information by default. + +You can override the default behavior in your logger or asynchronous appender configuration by specifying `includeLocation="true"`. diff --git a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc index 3b132b4f6b3..75f071708c1 100644 --- a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc @@ -63,7 +63,7 @@ and that all the properties names that start with `log4j` use the normalized for In order to rapidly optimize Log4j Core for a particular usage, you can use the following properties: -include::partial$properties-meta.adoc[leveloffset=+1] +include::partial$manual/systemproperties/properties-meta.adoc[leveloffset=+1] [id=properties-log4j-api] == Log4j API properties @@ -78,7 +78,7 @@ Therefore, its configuration influences all other services. It has only one configuration property: -include::partial$properties-loader-util.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-loader-util.adoc[leveloffset=+2] [id=properties-provider] === Provider @@ -86,7 +86,7 @@ include::partial$properties-loader-util.adoc[leveloffset=+2] The runtime classpath of an application **should** contain only a single implementation of the Log4j API. In the particular case, when multiple implementations are present, you can select a specific implementation using these properties: -include::partial$properties-provider.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-provider.adoc[leveloffset=+2] [id=properties-status-logger] === Status Logger @@ -96,7 +96,7 @@ NOTE: To configure status logger you can also place its configuration in a file Log4j contains an internal logging mechanism called `StatusLogger` that is used by all Log4j components. By default, the status logger only reports errors on the standard error stream, but you can configure it using the following properties. -include::partial$properties-status-logger.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-status-logger.adoc[leveloffset=+2] [id=properties-simple-logger] === Simple logger @@ -105,7 +105,7 @@ NOTE: To configure simple logger you can also place its configuration in a file The simple logger implementation contained in `log4j-api` can be configured using these properties: -include::partial$properties-simple-logger.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-simple-logger.adoc[leveloffset=+2] [id=properties-simple-logger-thread-context] === Thread context (Simple Logger) @@ -121,7 +121,7 @@ The `log4j-to-slf4j` logging bridge delegates `ThreadContext` calls to the SLF4J The `log4j-to-jul` logging bridge ignores all `ThreadContext` method calls. ==== -include::partial$properties-thread-context.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-thread-context.adoc[leveloffset=+2] [id=properties-log4j-core] == Log4j Core properties @@ -133,26 +133,26 @@ While the only required configuration of the `log4j-core` library is provided by The behavior of all three async components (`AsyncLogger`, `AsyncLoggerConfig` and `AsyncAppender`) can be tuned using these properties: -include::partial$properties-async.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-async.adoc[leveloffset=+2] [id=properties-async-logger] === Full asynchronous logger The `AsyncLogger` component supports the following additional properties: -include::partial$properties-async-logger.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-async-logger.adoc[leveloffset=+2] [id=properties-async-logger-config] === Mixed asynchronous logger The `AsyncLoggerConfig` component supports the following additional properties: -include::partial$properties-async-logger-config.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-async-logger-config.adoc[leveloffset=+2] [id=properties-properties-context-selector] === Context selector -The link:javadoc/log4j-core/org/apache/logging/log4j/core/selector/ContextSelector[ContextSelector] component specifies the strategy used by Log4j to create new logger contexts. +The link:../javadoc/log4j-core/org/apache/logging/log4j/core/selector/ContextSelector[ContextSelector] component specifies the strategy used by Log4j to create new logger contexts. The choice of `ContextSelector` determines in particular: * how loggers are divided among logger contexts. @@ -161,7 +161,7 @@ See xref:manual/logsep.adoc[Log Separation] for details. * the `Logger` implementation used by Log4j Core. See xref:manual/async.adoc[Async Logging] as an example of this usage. -include::partial$properties-context-selector.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-context-selector.adoc[leveloffset=+2] [id=properties-configuration-factory] === Configuration factory @@ -175,24 +175,24 @@ If a remote configuration file is used, its transport must be secured. See <> for details. ==== -include::partial$properties-configuration-factory.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-configuration-factory.adoc[leveloffset=+2] [id=properties-garbage-collection] === Garbage Collection -include::partial$properties-garbage-collection.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-garbage-collection.adoc[leveloffset=+2] [id=properties-jansi] === JANSI If the https://fusesource.github.io/jansi/[JANSI] library is on the runtime classpath of the application, the following property can be used to control its usage: -include::partial$properties-jansi.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-jansi.adoc[leveloffset=+2] [id=properties-jmx] === JMX -include::partial$properties-jmx.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-jmx.adoc[leveloffset=+2] [id=properties-jndi] === JNDI @@ -201,7 +201,7 @@ Due to the inherent security problems of https://docs.oracle.com/javase/tutorial Moreover, each JNDI usage must be **explicitly** enabled by the user through the following configuration properties. -include::partial$properties-jndi.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-jndi.adoc[leveloffset=+2] [id=properties-log4j-core-thread-context] === Thread context (Log4j Core) @@ -216,12 +216,12 @@ Since configuration files can be used to load arbitrary classes into a Log4j Cor In order to protect the user Log4j disables the `http` URI scheme by default and provides several configuration options to ensure secure transport of configuration files: -include::partial$properties-transport-security.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-transport-security.adoc[leveloffset=+2] [id=properties-log4j-core-misc] === Miscellaneous properties -include::partial$properties-log4j-core-misc.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-log4j-core-misc.adoc[leveloffset=+2] [id=properties-other-components] == Other components @@ -231,19 +231,19 @@ include::partial$properties-log4j-core-misc.adoc[leveloffset=+2] The JUL-to-Log4j API bridge provides the following configuration properties: -include::partial$properties-log4j-jul.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-log4j-jul.adoc[leveloffset=+2] [id=properties-log4j-spring-boot] === Log4j Spring Boot properties The Log4j Spring Boot module supports the following configuration properties: -include::partial$properties-log4j-spring-boot.adoc[leveloffset=+2] +include::partial$manual/systemproperties/properties-log4j-spring-boot.adoc[leveloffset=+2] [id=property-sources] == Property sources -The Log4j configuration properties sub-system merges the content of multiple property sources that implement the Java interface link:javadoc/log4j-api/org/apache/logging/log4j/util/PropertySource[PropertySource]. +The Log4j configuration properties sub-system merges the content of multiple property sources that implement the Java interface link:../javadoc/log4j-api/org/apache/logging/log4j/util/PropertySource[PropertySource]. Additional property source classes can be added through: diff --git a/src/site/antora/modules/ROOT/pages/plugin-reference.adoc b/src/site/antora/modules/ROOT/pages/plugin-reference.adoc index 628d310c922..ebcc9b60ba1 100644 --- a/src/site/antora/modules/ROOT/pages/plugin-reference.adoc +++ b/src/site/antora/modules/ROOT/pages/plugin-reference.adoc @@ -19,6 +19,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more This file is a stub. Its content will be auto-generated during build. +The purpose of the sections below is to remove IDE errors while editing configuration files. + [#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-AbstractBuilder] == `AbstractBuilder` [#org-apache-logging-log4j_log4j-1-2-api_org-apache-log4j-builders-appender-AppenderBuilder] diff --git a/src/site/antora/modules/ROOT/partials/properties-async-logger-config.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-async-logger-config.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-async-logger-config.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-async-logger-config.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-async-logger.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-async-logger.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-async-logger.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-async-logger.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-async.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-async.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-async.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-async.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-configuration-factory.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-configuration-factory.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-configuration-factory.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-configuration-factory.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-context-selector.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-context-selector.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-context-selector.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-context-selector.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-garbage-collection.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-garbage-collection.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-garbage-collection.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-garbage-collection.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-jansi.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jansi.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-jansi.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jansi.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-jmx.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jmx.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-jmx.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jmx.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-jndi.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jndi.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-jndi.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jndi.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-loader-util.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-loader-util.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-loader-util.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-loader-util.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-log4j-core-misc.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-core-misc.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-log4j-core-misc.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-core-misc.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-log4j-jul.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-jul.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-log4j-jul.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-jul.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-log4j-spring-boot.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-spring-boot.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-log4j-spring-boot.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-log4j-spring-boot.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-meta.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-meta.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-meta.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-meta.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-provider.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-provider.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-provider.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-provider.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-simple-logger.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-simple-logger.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-simple-logger.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-simple-logger.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-status-logger.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-status-logger.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-status-logger.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-status-logger.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-thread-context.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-thread-context.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-thread-context.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-thread-context.adoc diff --git a/src/site/antora/modules/ROOT/partials/properties-transport-security.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-transport-security.adoc similarity index 100% rename from src/site/antora/modules/ROOT/partials/properties-transport-security.adoc rename to src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-transport-security.adoc From 5f8a7dc05d64b5ced2954357b94f7076ef25efc4 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Wed, 15 May 2024 12:09:10 +0200 Subject: [PATCH 22/24] Add logger configuration example --- .../manual/configuration/loggers.json | 37 ++++++++ .../manual/configuration/loggers.properties | 14 +++ .../examples/manual/configuration/loggers.xml | 24 +++++ .../manual/configuration/loggers.yaml | 21 +++++ .../ROOT/pages/manual/architecture.adoc | 1 + .../ROOT/pages/manual/configuration.adoc | 93 ++++++++++++++++++- 6 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json new file mode 100644 index 00000000000..e381ea3642e --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.json @@ -0,0 +1,37 @@ +{ + "Configuration": { + // tag::loggers[] + "Loggers": { + "Root": { // <1> + "level": "INFO", + "AppenderRef": { + "ref": "APPENDER1" + } + }, + "Logger": [ + { // <2> + "name": "org.example.no_additivity", + "additivity": false, + "AppenderRef": { + "ref": "APPENDER2" + } + }, + { // <3> + "name": "org.example.no_location", + "includeLocation": false, + "AppenderRef": { + "ref": "APPENDER3" + } + }, + { // <4> + "name": "org.example.level", + "level": "DEBUG", + "AppenderRef": { + "ref": "APPENDER4" + } + } + ] + } + // end::loggers[] + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties new file mode 100644 index 00000000000..66b56dc41db --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties @@ -0,0 +1,14 @@ +rootLogger.level = INFO # <1> +rootLogger.appenderRef.0.ref = APPENDER1 + +logger.0.name = org.example.no_additivity # <2> +logger.0.additivity = false +logger.0.appenderRef.0.ref = APPENDER2 + +logger.1.name = org.example.no_location # <3> +logger.1.includeLocation = false +logger.1.appenderRef.0.ref = APPENDER3 + +logger.2.name = org.example.level # <4> +logger.2.level = DEBUG +logger.2.appenderRef.0.ref = APPENDER4 \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml new file mode 100644 index 00000000000..a73e629171c --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml new file mode 100644 index 00000000000..2fdf62e4775 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.yaml @@ -0,0 +1,21 @@ +Configuration: + # tag::loggers[] + Loggers: + Root: # <1> + level: "INFO" + AppenderRef: + ref: "APPENDER1" + Logger: + - name: "org.example.no_additivity" # <2> + additivity: false + AppenderRef: + ref: "APPENDER2" + - name: "org.example.no_location" # <3> + includeLocation: false + AppenderRef: + ref: "APPENDER3" + - name: "org.example.level" # <4> + level: "DEBUG" + AppenderRef: + ref: "APPENDER4" + # end::loggers[] \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc index f188ffcc3d8..622b193943c 100644 --- a/src/site/antora/modules/ROOT/pages/manual/architecture.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/architecture.adoc @@ -152,6 +152,7 @@ Logger name. Nevertheless, naming loggers after the class where they are located seems to be the best strategy known so far. +[#loggerconfig] === LoggerConfig link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/LoggerConfig.html[`LoggerConfig`] diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index b7038547b7e..eb65b508ee1 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -434,7 +434,7 @@ See xref:manual/filters.adoc#filters[Filters] for additional filtering capabilit [id=configuring-loggers] === [[Loggers]] Loggers -Log4j 2 contains multiple types of logger components that can be added to the `Loggers` element of the configuration: +Log4j 2 contains multiple types of logger configurations that can be added to the `Loggers` element of the configuration: `Root`:: is the logger that receives all events that do not have a more specific logger defined. + @@ -452,10 +452,97 @@ See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apac + See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig[Plugin Reference]. -Every configuration **must** have at least a `Root` or `AsyncRoot` element. +There **must** be at least a `Root` or `AsyncRoot` element in every configuration file. The presence of other logger configurations is optional. -The logger components can have the following configuration attributes and elements: +Every +link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html[Logger] +in your application is assigned to one of these logger configurations (see +xref:manual/architecture.adoc#loggerconfig[architecture]), which determines the events that will be logged and those which won't. + +Let's start with an example of loggers configuration: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/configuration/loggers.xml[tag=loggers] +---- + +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/loggers.json[tag=loggers] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/loggers.yaml[tag=loggers] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/loggers.properties[] +---- +==== + +In the example above we have 4 logger configurations. +They differ between each other regarding the level of log messages that they allow, whether +xref:manual/layouts.adoc#location-information[location information] +will be printed and which appenders will be used. +The effects of each logger configuration are summarized in the table below: + +.Logger configurations +[cols="1,2,2,2,2,5"] +|=== +| +| <> +| <> +| <> +| <> +h| Appenders used + +| 1 +| _empty_ +| `INFO` +| N/A +| _default_ +| `APPENDER1` + +| 2 +| `org.example.no_additivity` +| `INFO` + +(inherited) +| `false` +| _default_ +| `APPENDER2` + +| 3 +| `org.example.no_location` +| `INFO` + +(inherited) +| `true` +| `false` +| `APPENDER1` and `APPENDER3` + +| 4 +| `org.example.level` +| `DEBUG` +| `true` +| _default_ +| `APPENDER1` and `APPENDER4` +|=== + +In the following part of this section we explain in detail all the available option for logger configurations: [id=logger-attributes-name] ==== `name` From cd69a989ee2855011c747665dd07c0dfe427b5ca Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Wed, 15 May 2024 13:09:43 +0200 Subject: [PATCH 23/24] Add property expansion example --- .../manual/configuration/loggers.properties | 21 +++- .../examples/manual/configuration/loggers.xml | 20 +++- .../manual/configuration/loggers.yaml | 18 ++- .../configuration/properties-example.json | 14 +++ .../properties-example.properties | 18 +++ .../configuration/properties-example.xml | 21 ++++ .../configuration/properties-example.yaml | 22 ++++ .../configuration/properties-recursion.json | 18 +++ .../properties-recursion.properties | 19 ++++ .../configuration/properties-recursion.xml | 22 ++++ .../configuration/properties-recursion.yaml | 24 ++++ .../ROOT/pages/manual/configuration.adoc | 103 +++++++++++++++++- 12 files changed, 315 insertions(+), 5 deletions(-) create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.json create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.properties create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.xml create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml create mode 100644 src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties index 66b56dc41db..01b945ebace 100644 --- a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.properties @@ -1,3 +1,21 @@ +# +# 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. +# +## +# tag::loggers[] rootLogger.level = INFO # <1> rootLogger.appenderRef.0.ref = APPENDER1 @@ -11,4 +29,5 @@ logger.1.appenderRef.0.ref = APPENDER3 logger.2.name = org.example.level # <4> logger.2.level = DEBUG -logger.2.appenderRef.0.ref = APPENDER4 \ No newline at end of file +logger.2.appenderRef.0.ref = APPENDER4 +# end::loggers[] diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml index a73e629171c..4549b534f25 100644 --- a/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/loggers.xml @@ -1,4 +1,20 @@ - + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml new file mode 100644 index 00000000000..35ef189004b --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-example.yaml @@ -0,0 +1,22 @@ +# +# 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. +# +Properties: + Property: + - name: "FOO" + value: "foo" + - name: "BAR" + value: "bar" diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json new file mode 100644 index 00000000000..6cfdc627990 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.json @@ -0,0 +1,18 @@ +{ + "Properties": { + "Property": [ + { + "name": "logging.file", + "value": "${logging.path}/app.log" + }, + { + "name": "logging.dir", + "value": "${env:APP_BASE}/logs" + }, + { + "name": "APP_BASE", + "value": "." + } + ] + } +} \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties new file mode 100644 index 00000000000..0c54dd40cb4 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.properties @@ -0,0 +1,19 @@ +# +# 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. +# +property.logging.file = ${logging.dir}/app.log +property.logging.dir = ${env:APP_BASE}/logs +property.APP_BASE = . diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml new file mode 100644 index 00000000000..98ac38dd07f --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml new file mode 100644 index 00000000000..2fa6ecc24c5 --- /dev/null +++ b/src/site/antora/modules/ROOT/examples/manual/configuration/properties-recursion.yaml @@ -0,0 +1,24 @@ +# +# 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. +# +Properties: + Property: + - name: "logging.file" + value: "${logging.dir}/app.log" + - name: "logging.dir" + value: "${env:APP_BASE}/logs" + - name: "APP_BASE" + value: "." diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index eb65b508ee1..10cc4b4af4d 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -489,7 +489,7 @@ Java properties:: + [source,properties] ---- -include::example$manual/configuration/loggers.properties[] +include::example$manual/configuration/loggers.properties[tags=loggers] ---- ==== @@ -818,6 +818,107 @@ To prevent the expansion of one of the expressions above, the initial `$` must b The same rule applies to the `name` parameter: if it contains a `${` sequence, the sequence must be escaped as `$${`. ==== +.Property substitution example +===== + +If your configuration file contains the following definitions: +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/configuration/properties-example.xml[lines=18..-1] +---- + +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/properties-example.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/properties-example.yaml[lines=17..-1] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/properties-example.properties[lines=17..-1] +---- +==== + +and the OS environment variable `FOO` has a value of `environment`, Log4j will evaluate expression as follows + +[cols="1m,1m"] +|=== +| Expression | Value + +| $\{FOO} | foo +| $\{BAZ} | $\{BAZ} +| ${BAR:-$\{FOO}} | bar +| ${BAZ:-$\{FOO}} | foo +| ${env:FOO} | environment +| ${env:BAR} | bar +| ${env:BAZ} | $\{BAZ} +| ${env:BAR:-$\{FOO}} | bar +| ${env:BAZ:-$\{FOO}} | foo +|=== +===== + +[CAUTION] +===== +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. +If your configuration contains, for example: + +[tabs] +==== +XML:: ++ +[source,xml] +---- +include::example$manual/configuration/properties-recursion.xml[lines=18..-1] +---- + +JSON:: ++ +[source,json] +---- +include::example$manual/configuration/properties-recursion.json[] +---- + +YAML:: ++ +[source,yaml] +---- +include::example$manual/configuration/properties-recursion.yaml[lines=17..-1] +---- + +Java properties:: ++ +[source,properties] +---- +include::example$manual/configuration/properties-recursion.properties[lines=17..-1] +---- +==== + +the `logging.dir` property will be expanded **before** the `logging.file` property and the expanded value will be substituted in `${logging.dir}/app.log`. +Therefore, the value of the `logging.file` property will be: + +* `./logs/app.log` if the environment variable `APP_BASE` is not defined, +* `/var/lib/app/logs/app.log` if the environment variable `APP_BASE` has a value of `/var/lib/app`. + + +===== + [id=lazy-property-substitution] ==== Lazy property substitution From 7e873f32a9ce69d67ada8355411b60c012b7414c Mon Sep 17 00:00:00 2001 From: Christian Grobmeier Date: Wed, 15 May 2024 23:00:40 +0200 Subject: [PATCH 24/24] some active/passive changes, wording and general style. No content changes --- .../ROOT/pages/manual/configuration.adoc | 181 +++++++++--------- 1 file changed, 91 insertions(+), 90 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc index 10cc4b4af4d..63dc17b9b13 100644 --- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc @@ -17,28 +17,28 @@ [id=configuration] = Configuration -Since logging is a common way to monitor the health of an application and diagnose problems that occur in it, even moderately sized applications can contain thousands of logging statements. -To decide which of these statements will be logged and where users need to configure Log4j Core. +Logging is a standard method for monitoring the health of an application and diagnosing problems that may arise within it. +Even moderately sized applications can contain thousands of logging statements. -Log4j Core can be configured in two ways: +To decide which of these statements will be logged and where, users need to configure Log4j Core in one of two ways: * through a <>. -Since version 2.0 the configuration file format is considered as part of the public API, and it remains stable even across major version upgrades. +Since version 2.0, the configuration file format has been considered part of the public API and has remained stable across significant version upgrades. -* through xref:manual/customconfig.adoc[Programmatic Configuration], which provides a larger spectrum of possible customizations, but might require code changes during version upgrades. +* through xref:manual/customconfig.adoc[Programmatic Configuration], which provides a larger spectrum of possible customizations but might require code changes during version upgrades. [NOTE] ==== -To prevent a chicken-and-egg problem some configuration options (e.g., the configuration file location) can only be supplied through xref:manual/systemproperties.adoc[configuration properties]. +To prevent a chicken-and-egg problem, users can only supply some configuration options (e.g., the configuration file location) through xref:manual/systemproperties.adoc[configuration properties]. ==== [#configuration-file] == Configuration file -Log4j Core can be configured using multiple configuration file formats. -Configuration factories for the XML, JSON, YAML and Java properties formats are included in the `log4j-core` artifact. +Users can configure Log4j Core using different file formats. +The `log4j-core` artifact includes XML, JSON, YAML, and Java properties formats factories. -Some configuration formats require additional dependencies to be present on the classpath, according to the table below. +As detailed in the table below, some configuration formats require additional dependencies on the classpath. include::partial$configuration-file-format-deps.adoc[] @@ -47,7 +47,7 @@ include::partial$configuration-file-format-deps.adoc[] The format of the configuration file changed between Log4j{nbsp}1 and Log4j{nbsp}2. Files in the Log4j{nbsp}1 format are ignored by default. -To enable partial support for old configuration formats see xref:manual/migration.adoc#enabling-the-log4j-1-x-bridge[Enabling the Log4j{nbsp}1 bridge]. +To enable partial support for old configuration formats, see xref:manual/migration.adoc#enabling-the-log4j-1-x-bridge[Enabling the Log4j{nbsp}1 bridge]. ==== [id=automatic-configuration] @@ -59,7 +59,7 @@ Upon initialization of a new logger context, Log4j assigns it a context name and . Files named `log4j2-test.`, . Files named `log4j2.` . Files named `log4j2.`, -. If no configuration file can be located a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration] is used and a warning is printed by the status logger. +. If no configuration file is found, Log4j uses the link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/DefaultConfiguration[DefaultConfiguration], and the status logger prints a warning. The default configuration prints all messages less specific than xref:manual/systemproperties.adoc#log4j2.level[log4j2.level] to the console. @@ -69,19 +69,19 @@ to the console. The configuration files prefixed by `log4j2-test` should only be used on the test classpath. If multiple configuration files in the same category are found, Log4j uses a deterministic order to choose one of them (see link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Order[@Order]). -Nevertheless: -* if you are developing an application you should not use configuration files that only differ by the extension, -* if you are developing a library you should only add configuration files to your test classpath. +Nevertheless: +* If you're developing an app, don't use config files with different extensions. +* If you're developing a library, only add config files to your test classpath. ==== The `` and `` placeholders above have the following meaning :: depends on the runtime environment in which Log4j runs: -* for standalone Java SE applications it is a random identifier, -* for web applications it is derived from the application descriptor. +* for standalone Java SE applications, it is a random identifier, +* for web applications, it is derived from the application descriptor. See xref:manual/webapp.adoc#configuration[Log4j Web application configuration] for more details. @@ -109,7 +109,7 @@ See xref:manual/webapp.adoc#configuration[Log4j It is also possible to override the location of the configuration file using the xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] configuration property. -In this case, Log4j will guess the configuration file format from the extension of the provided configuration file or will use the default configuration factory if the extension is unknown. +In this case, Log4j will guess the configuration file format from the provided configuration file extension or use the default configuration factory if the extension is unknown. See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurationFile] for details. ==== @@ -117,23 +117,24 @@ See xref:manual/systemproperties.adoc#log4j2.configurationFile[log4j2.configurat [id=configuration-syntax] === [[ConfigurationSyntax]] Syntax -The Log4j runtime is composed of xref:manual/plugins.adoc[plugins], which are analogous to beans in Spring Framework and Java EE. -Appenders, layouts, filters, configuration loaders, etc. are all accessed as plugins. +The Log4j runtime is composed of xref:manual/plugins.adoc[plugins], which are like beans in the Spring Framework and Java EE. +Appenders, layouts, filters, configuration loaders, and similar components are all accessed as plugins. All configuration files are represented internally as a tree of link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node[Node]s, which is translated into a tree of Log4j plugins. -The root of the tree creates a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration[Configuration] object. +The tree's root creates a link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Configuration[Configuration] object. + +A node is a relatively simple structure representing a single Log4j plugin (see xref:plugin-reference.adoc[] for a complete list), such as an appender, layout, or logger configuration. -A node is a fairly simple structure that represents a single Log4j plugin (see xref:plugin-reference.adoc[] for a complete list) such as an appender, layout or logger configuration. Each node has: * a set of simple string key-value pairs called **attributes**. Attributes are **matched by name** against the list of available configuration options of a Log4j plugin. -* one distinguished attribute called **plugin type** specifies the kind of Log4j plugin we want to instantiate. +* The **plugin type** attribute specifies the kind of Log4j plugin we want to instantiate. -* a set of child nodes called **nested elements**. -They are **matched by type** against the list of nested components that a Log4j plugin accepts. +* A set of child nodes called **nested elements**. +They are **matched by type** against the list of nested components a plugin accepts. Log4j maps the concepts above to the specifics of the configuration format as follows: @@ -150,11 +151,11 @@ Since XML was the original configuration format developed, the mapping from conf + [NOTE] ==== -There is an alternative XML configuration format called "XML strict format" that is activated by setting the `strict` -attribute of the main `` element to `true`. -It allows users to use arbitrary tag names as long as they provide the plugin type using a `type` property. +There is an alternative XML configuration format called "XML strict format" that is activated +by setting the `strict` attribute of the main `` element to `true`. +It allows users to use any tag names as long as they provide the plugin type using a `type` property. -The _XML strict format_ was conceived as a simplified XML format that can be validated by an XML schema, but has fallen into disuse: nowadays, the automatically generated schemas published at https://logging.apache.org/xml/ns/ +The _XML strict format_ was conceived as a simplified XML format that can be validated by an XML schema but has fallen into disuse: nowadays, the automatically generated schemas published at https://logging.apache.org/xml/ns/ offer a better alternative and allow users to use a more concise syntax. ==== @@ -165,8 +166,8 @@ In the JSON configuration format: [id=configuration-with-json] ==== * Each configuration node is represented by a JSON object, -* JSON properties of type string, number or boolean are mapped to node attributes. -* JSON properties of type object or array are used to represent nested configuration elements. +* JSON properties of type string, number, or boolean are mapped to node attributes. +* JSON properties of type object or array represent nested configuration elements. * The **plugin type** of a JSON object is given by: ** the value of the `type` key, if present, ** or the key associated with the JSON object otherwise. @@ -199,7 +200,7 @@ In the YAML configuration format: + [id=configuration-with-yaml] ==== -* Each configuration node is represented by a YAML mapping, +* A YAML mapping represents each configuration node, * YAML properties of scalar type are mapped to node attributes. * YAML properties of collection type are used to represent nested configuration elements. * The **plugin type** of a YAML mapping is given by: @@ -227,18 +228,18 @@ In the Java properties configuration format: + [id=configuration-with-properties] ==== -* Properties that share a common prefix (e.g. `appender.foo`) are mapped to a subtree of the configuration node tree. -* Configuration attributes are specified by appending the name of the property (e.g. `name`) to the prefix of the node, separated by a dot (e.g. `appender.foo.name`). -* The **plugin type** must necessarily be specified as an attribute named `type`. +* Properties that share a common prefix (e.g., `appender.foo`) are mapped to a subtree of the configuration node tree. +* Configuration attributes are specified by appending the property's name (e.g., `name`) to the prefix of the node, separated by a dot (e.g., `appender.foo.name`). +* The **plugin type** must be specified as an attribute named `type`. * Nested elements are created by: -** Choosing an arbitrary id for the nested component (e.g. `<0>`) -** Appending the id to the prefix of the parent component (e.g. `appender.foo.<0>`) -** Specifying the type of the nested plugin by assigning a `type` attribute (e.g. `appender.foo.<0>.type`) +** Choosing an arbitrary id for the nested component (e.g., `<0>`) +** Appending the id to the prefix of the parent component (e.g., `appender.foo.<0>`) +** Specifying the type of the nested plugin by assigning a `type` attribute (e.g., `appender.foo.<0>.type`) ==== + [NOTE] ==== -The ID assigned to nested components is only used for sorting purposes. +Nested components use the assigned ID for sorting purposes only. ==== ===== @@ -251,7 +252,7 @@ Log4j Core's logging pipeline is quite complex (see xref:manual/architecture.ado Loggers:: + -Loggers are the entry point of the logging pipeline, directly used in code. +Loggers are the entry point of the logging pipeline, which is directly used in the code. Their configuration must specify which level of messages they log and to which appenders they send the messages. + See <> for details. @@ -260,14 +261,14 @@ See <> for details. [[Appenders]] Appenders:: + Appenders are the exit point of the logging pipeline. -They decide to which resource (console, file, database, etc.) the log event is sent. +They decide which resource (console, file, database, or similar) the log event is sent to. In the examples of this chapter, we will only use the xref:manual/appenders.adoc#consoleappender[console appender] and the xref:manual/appenders.adoc#fileappender[file appender]. + See xref:manual/appenders.adoc[Appender configuration] for details. Layouts:: + -Layouts tell appenders how they should format the log event: text, JSON, XML, etc. +Layouts tell appenders how to format the log event: text, JSON, XML, or similar. In the examples of this chapter, we will only use the xref:manual/layouts.adoc#pattern-layout[textual pattern layout] and xref:manual/json-template-layout.adoc[JSON template layout]. @@ -360,26 +361,26 @@ See xref:manual/customloglevels.adoc[Custom log level configuration] for details Filters:: + -Components that can be added to loggers, appender references, appenders or the global configuration object to provide additional filtering of log events. +Users can add Components to loggers, appender references, appenders, or the global configuration object to provide additional filtering of log events. + See xref:manual/filters.adoc[Filter configuration] for details. Properties:: + -A set of reusable configuration values for property substitution. +Represent a set of reusable configuration values for property substitution. + See <> for details. Scripts:: + -A container for JSR 223 scripts that can be used in other Log4j components. +Scripts are a container for JSR 223 scripts that users can use in other Log4j components. + -See xref:manual/scripts.adoc[Scripts configuration] for details. +For details, see xref:manual/scripts.adoc[Scripts configuration]. [id=global-configuration-attributes] === Global configuration attributes -The main `Configuration` element has a set of attributes that can be used to tune the way the configuration file itself is used. +The main `Configuration` element has a set of attributes that can be used to tune how the configuration file is used. The principal attributes are listed below. See xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Configuration[Plugin reference] for a complete list. @@ -398,15 +399,16 @@ If set to `0`, polling is disabled. [CAUTION] ==== -Unlike other logging backends, Log4j Core is designed with reliability in mind. +Log4j Core is designed with reliability in mind, unlike other logging backends. During a reconfiguration process, no messages are lost. -Unless the new configuration file removes an appender, the old one continues to work without interruption. +Unless the new configuration file removes an appender, the old ones work without interruption. -Since some appender options (like the append mode used to open a file) can not be changed without closing the resource used by an appender, some attribute changes will be **ignored** during a reconfiguration. +Some changed appender options will be **ignored** during reconfiguration. +For example, appenders that need to close resources, like the append mode used to open a file, will ignore such options. -To modify these options during a reconfiguration you also need to change the resource used by the appender (e.g. the file name used by a file appender). +To modify these options during a reconfiguration, you also need to change the resource used by the appender (e.g., the file name used by a file appender). ==== [id=configuration-attribute-status] @@ -453,14 +455,14 @@ See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apac See also xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncLoggerConfig[Plugin Reference]. There **must** be at least a `Root` or `AsyncRoot` element in every configuration file. -The presence of other logger configurations is optional. +Other logger configurations are optional. Every link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html[Logger] in your application is assigned to one of these logger configurations (see -xref:manual/architecture.adoc#loggerconfig[architecture]), which determines the events that will be logged and those which won't. +xref:manual/architecture.adoc#loggerconfig[architecture]), which determines the events that will be logged and those that won't. -Let's start with an example of loggers configuration: +Let's start with an example of logger configuration: [tabs] ==== @@ -493,11 +495,11 @@ include::example$manual/configuration/loggers.properties[tags=loggers] ---- ==== -In the example above we have 4 logger configurations. -They differ between each other regarding the level of log messages that they allow, whether +In the example above, we have four logger configurations. +They differ from each other regarding the level of log messages that they allow, whether xref:manual/layouts.adoc#location-information[location information] -will be printed and which appenders will be used. -The effects of each logger configuration are summarized in the table below: +will be printed, and which appenders will be used. +The table below summarizes the effects of each logger configuration: .Logger configurations [cols="1,2,2,2,2,5"] @@ -542,7 +544,7 @@ h| Appenders used | `APPENDER1` and `APPENDER4` |=== -In the following part of this section we explain in detail all the available option for logger configurations: +In the following part of this section, we explain in detail all the available options for logger configurations: [id=logger-attributes-name] ==== `name` @@ -570,7 +572,7 @@ Since loggers are usually named using fully qualified class names, this value us | Applies to | `Logger` and `AsyncLogger` |=== -If `true` (default), all the messages received by this logger will also be transmitted to its +If `true` (default), all the messages this logger receives will also be transmitted to its xref:manual/architecture.adoc#logger-hierarchy[parent logger]). [id=logger-attributes-level] @@ -591,7 +593,7 @@ for `Logger` and `AsyncLogger`. |=== Specifies the level threshold that a log event must have to be logged. -Log events more specific than this setting will be filtered out. +Log events that are more specific than this setting will be filtered out. See also xref:manual/filters.adoc#filters[Filters] if you require additional filtering. @@ -616,7 +618,7 @@ for more details. |=== Specifies whether Log4j is allowed to compute location information. -If set to `false`, Log4j will make no attempt to infer the location of the logging call, unless said location was provided explicitly using one of the available +If set to `false`, Log4j will not attempt to infer the location of the logging call unless said location was provided explicitly using one of the available https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/LogBuilder.html[LogBuilder .withLocation()] methods. @@ -626,7 +628,7 @@ See xref:manual/layouts.adoc#location-information[Location information] for more [id=logger-elements-appenderrefs] ==== Appender references -Loggers use appender references to list the appenders to use to deliver log events. +Loggers use appender references to list the appenders to deliver log events. See <> below for more details. @@ -642,7 +644,7 @@ The `value` of each property is subject to <> are all aggregated. -Logger attributes are individually merged with duplicates being replaced by those in later configurations. -Appender references on a logger are aggregated with duplicates being replaced by those in later configurations. +Logger attributes are individually merged, and those in later configurations replace duplicates. +Appender references on a logger are aggregated, and those in later configurations replace duplicates. The strategy merges filters on loggers using the rule above. [id=format-specific-notes] @@ -1138,10 +1140,10 @@ Specifies the path to a classpath resource containing an XML schema. | Default value | `false` |=== -If set to `true` all configuration files will be checked against the XML schema provided by the +If set to `true,` all configuration files will be checked against the XML schema provided by the <>. -This setting also enables "XML strict mode" and allows one to specify the **plugin type** of an element through a `type` attribute instead of the tag name. +This setting also enables "XML strict mode" and allows one to specify an element's **plugin type** through a `type` attribute instead of the tag name. [id=xinclude] ===== [[XInlcude]] XInclude @@ -1179,14 +1181,13 @@ include::example$manual/configuration/xinclude-loggers.xml[lines=1;18..-1] ==== The Java properties format is not well suited to represent hierarchical structures. -Consider switching to XML, if you don't want additional dependencies, or YAML, if you are looking for a format similar to Java properties, but less verbose. +Switch to XML to avoid additional dependencies, or choose YAML for a format similar to Java properties but less verbose. ==== -The Java properties configuration format is by far the most verbose of the available formats. -To make it more usable a series of exceptions to the rules in <> have been introduced over time: +The Java properties configuration format is the most verbose of the available formats. +To make it more usable, a series of exceptions to the rules in <> have been introduced over time: -. The following direct children of `Configuration` have predefined prefixes and do not require to specify a `type` -attribute: +. The following direct children of `Configuration` have predefined prefixes and do not require to specify a `type` attribute: * The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-AppendersPlugin[Appender container] has a predefined `appender` prefix. * The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevels[Custom levels container] has a predefined `customLevel` prefix. * The xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-LoggersPlugin[Loggers container] has a predefined `logger` prefix. @@ -1201,7 +1202,7 @@ Their syntax is: property. = ---- -. Properties that start with `customLevel` are used to define custom levels Their syntax is: +. Properties that start with `customLevel` are used to define custom levels. Their syntax is: + [source,properties] ----