This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch doc/2.x/extending in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit f9deaaf961726256099e0449af8d33544a2b0a77 Author: Volkan Yazıcı <[email protected]> AuthorDate: Tue Jun 11 10:30:06 2024 +0200 Move extending appenders/filters/lookups to their own pages --- .../modules/ROOT/pages/manual/appenders.adoc | 166 +++++++++++++------- .../modules/ROOT/pages/manual/extending.adoc | 170 --------------------- .../antora/modules/ROOT/pages/manual/filters.adoc | 66 ++++++-- .../antora/modules/ROOT/pages/manual/lookups.adoc | 83 +++++++--- src/site/resources/.htaccess | 3 + 5 files changed, 225 insertions(+), 263 deletions(-) diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc index aad5a661a3..be44a32d4d 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. //// + = Appenders -Ralph Goers; Gary Gregory; Nick Williams; Matt Sicker Appenders are responsible for delivering LogEvents to their destination. Every Appender must implement the @@ -70,8 +70,14 @@ This setting only guarantees that a byte representation of the log event is pass It does not ensure that the operating system writes the event to the underlying storage. ==== +[#collection] +== Collection + +Log4j bundles several predefined appenders to assist in several common deployment use cases. +Following sections explain all these in detail. + [id=AsyncAppender] -== [[asyncappender]] AsyncAppender +=== [[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. @@ -232,7 +238,7 @@ maximum capacity. |======================================================================= [#CassandraAppender] -== CassandraAppender +=== CassandraAppender The CassandraAppender writes its output to an https://cassandra.apache.org/[Apache Cassandra] database. @@ -371,7 +377,7 @@ CREATE TABLE logs ( ---- [id=consoleappender] -== [[ConsoleAppender]] 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. @@ -434,7 +440,7 @@ A typical Console configuration might look like: ---- [#FailoverAppender] -== 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. @@ -497,7 +503,7 @@ A Failover configuration might look like: ---- [id=fileappender] -== [[FileAppender]] 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. @@ -625,7 +631,7 @@ Here is a sample File configuration: ---- [#FlumeAppender] -== FlumeAppender +=== FlumeAppender _This is an optional component supplied in a separate jar._ @@ -857,7 +863,7 @@ A sample FlumeAppender configuration that is configured with a primary and a sec ---- [#JDBCAppender] -== JDBCAppender +=== JDBCAppender As of Log4j 2.11.0, JDBC support has moved from the existing module `log4j-core` to the new module `log4j-jdbc`. @@ -1251,7 +1257,7 @@ table based on a Log4j `MapMessage` instead of values from `LogEvent`. </Configuration> ---- -== JMS Appender +=== JMS Appender The JMS Appender sends the formatted log event to a JMS Destination. @@ -1384,7 +1390,7 @@ To map your Log4j `MapMessage` to JMS `javax.jms.MapMessage`, set the layout of ---- [[JPAAppender]] -== JPAAppender +=== JPAAppender As of Log4j 2.11.0, JPA support has moved from the existing module `log4j-core` to the new module `log4j-jpa`. @@ -1562,7 +1568,7 @@ public class JpaLogEntity extends AbstractLogEventWrapperEntity { ---- [#HttpAppender] -== HttpAppender +=== HttpAppender The HttpAppender sends log events over HTTP. A Layout must be provided to format the LogEvent. @@ -1636,7 +1642,7 @@ Here is a sample HttpAppender configuration snippet: ---- [[KafkaAppender]] -== KafkaAppender +=== KafkaAppender The KafkaAppender logs events to an https://kafka.apache.org/[Apache Kafka] topic. Each log event is sent as a Kafka record. @@ -1721,7 +1727,7 @@ _Note:_ Make sure to not let `org.apache.kafka` log to a Kafka appender on DEBUG ---- [#MemoryMappedFileAppender] -== 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._ @@ -1816,7 +1822,7 @@ Here is a sample MemoryMappedFile configuration: ---- [#NoSQLAppender] -== 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. @@ -1907,10 +1913,10 @@ The following example demonstrates how log events are persisted in NoSQL databas ---- [#NoSQLAppenderMongoDB] -=== NoSQL providers for MongoDB +==== NoSQL providers for MongoDB [#mongo-installation] -==== Installation +===== Installation Starting with version 2.11.0, Log4j supplies providers for the https://www.mongodb.com/[MongoDB] @@ -1980,7 +1986,7 @@ If you are note sure, which implementation to choose, `log4j-mongodb` is the rec ==== [#log4j-mongodb] -==== NoSQL provider for MongoDB (current) +===== NoSQL provider for MongoDB (current) This section details specializations of the link:#NoSQLAppender[NoSQLAppender] provider for MongoDB using the current MongoDB driver (version 5). @@ -2069,7 +2075,7 @@ You can define additional fields to log using KeyValuePair elements, for example ---- [#log4j-mongodb4] -==== [[NoSQLAppenderMongoDB4]] NoSQL provider for MongoDB 4 (deprecated) +===== [[NoSQLAppenderMongoDB4]] NoSQL provider for MongoDB 4 (deprecated) The `log4j-mongodb4` module is deprecated in favor of link:#log4j-mongodb[NoSQL provider for MongoDB]. @@ -2159,7 +2165,7 @@ You can define additional fields to log using KeyValuePair elements, for example ---- [[NoSQLAppenderApacheCouchDB]] -== NoSQLAppender for Apache CouchDB +=== 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. @@ -2222,7 +2228,7 @@ Here are a few sample configurations for the NoSQLAppender and CouchDB provider: ---- [#OutputStreamAppender] -== 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. @@ -2230,7 +2236,7 @@ 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 +=== 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 @@ -2310,7 +2316,7 @@ Here is a sample RandomAccessFile configuration: ---- [#RewriteAppender] -== 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. @@ -2342,13 +2348,13 @@ Appender in a link:#FailoverAppender[FailoverAppender]. |======================================================================= [#RewritePolicy] -=== 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. -==== MapRewritePolicy +===== MapRewritePolicy MapRewritePolicy will evaluate LogEvents that contain a MapMessage and will add or update elements of the Map. @@ -2384,7 +2390,7 @@ The following configuration shows a RewriteAppender configured to add a product </Configuration> ---- -==== PropertiesRewritePolicy +===== 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. @@ -2423,7 +2429,7 @@ The following configuration shows a RewriteAppender configured to add a product </Configuration> ---- -==== LoggerNameLevelRewritePolicy +===== 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. @@ -2466,7 +2472,7 @@ The following configuration shows a RewriteAppender configured to map level INFO ---- [id=rollingfileappender] -== [[RollingFileAppender]] 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` @@ -2602,9 +2608,9 @@ file attribute view. |======================================================================= [#TriggeringPolicies] -== TriggeringPolicies +=== TriggeringPolicies -=== Composite Triggering Policy +==== Composite Triggering Policy The `CompositeTriggeringPolicy` combines multiple triggering policies and returns true if any of the configured policies return true. The @@ -2621,7 +2627,7 @@ For example, the following XML fragment defines policies that rollover the log w </Policies> ---- -=== Cron Triggering Policy +==== 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. @@ -2642,7 +2648,7 @@ expression indicates a rollover should have occurred between that time and the current time the file will be immediately rolled over. |======================================================================= -=== OnStartup Triggering Policy +==== 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. @@ -2661,7 +2667,7 @@ When running in Google App Engine, the OnStartup policy causes a rollover if the `java.lang.management.ManagementFactory.getRuntimeMXBean().getStartTime()` and falls back to Log4J initialization time instead.) -=== SizeBased Triggering Policy +==== 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`. @@ -2672,7 +2678,7 @@ When combined with a time-based triggering policy the file pattern must contain 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 +==== TimeBased Triggering Policy The `TimeBasedTriggeringPolicy` causes a rollover once the date/time pattern no longer applies to the active file. This policy accepts an @@ -2701,10 +2707,10 @@ load of doing so across time. |======================================================================= [#RolloverStrategies] -== RolloverStrategies +=== RolloverStrategies [#DefaultRolloverStrategy] -=== DefaultRolloverStrategy +==== DefaultRolloverStrategy Default Rollover Strategy @@ -2798,7 +2804,7 @@ archived log file during compression. |======================================================================= [#DirectWriteRolloverStrategy] -=== DirectWriteRolloverStrategy +==== DirectWriteRolloverStrategy DirectWrite Rollover Strategy @@ -2959,7 +2965,7 @@ This sample configuration is the same as the previous one but limits the number ---- [#CustomDeleteOnRollover] -=== CustomDeleteOnRollover +==== CustomDeleteOnRollover Log Archive Retention Policy: Delete on Rollover @@ -3046,7 +3052,7 @@ and must return a list with the paths to delete. |======================================================================= [#DeleteIfFileName] -== DeleteIfFileName +=== DeleteIfFileName .IfFileName Condition Parameters [cols="20%,20%,60%",options="header",] @@ -3072,7 +3078,7 @@ the path name matches). |======================================================================= [#DeleteIfLastModified] -== DeleteIfLastModified +=== DeleteIfLastModified .IfLastModified Condition Parameters [cols="20%,20%,60%",options="header",] @@ -3091,7 +3097,7 @@ the file is old enough). |======================================================================= [#DeleteIfAccumulatedFileCount] -== DeleteIfAccumulatedFileCount +=== DeleteIfAccumulatedFileCount .IfAccumulatedFileCount Condition Parameters [cols="20%,20%,60%",options="header",] @@ -3108,7 +3114,7 @@ the threshold count has been exceeded). |======================================================================= [#DeleteIfAccumulatedFileSize] -== DeleteIfAccumulatedFileSize +=== DeleteIfAccumulatedFileSize .IfAccumulatedFileSize Condition Parameters [cols="20%,20%,60%",options="header",] @@ -3202,7 +3208,7 @@ During every rollover, this configuration will delete files that match "*/app-*. ---- [#ScriptCondition] -== ScriptCondition +=== ScriptCondition .ScriptCondition Parameters [cols="20%,20%,60%",options="header",] @@ -3217,7 +3223,7 @@ how ScriptFiles and ScriptRefs can be configured. |======================================================================= [#ScriptParameters] -== ScriptParameters +=== ScriptParameters .Script Parameters [cols="20%,20%,60%",options="header",] @@ -3307,7 +3313,7 @@ The Delete action will delete all files returned by the script. ---- [#CustomPosixViewAttributeOnRollover] -== CustomPosixViewAttributeOnRollover +=== CustomPosixViewAttributeOnRollover Log Archive File Attribute View Policy: Custom file attribute on Rollover @@ -3399,7 +3405,7 @@ Below is a sample configuration that uses a RollingFileAppender and defines diff ---- [#RollingRandomAccessFileAppender] -== RollingRandomAccessFileAppender +=== 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 @@ -3511,11 +3517,11 @@ file attribute view. |======================================================================= -=== Triggering Policies +==== Triggering Policies See xref:#TriggeringPolicies[RollingFileAppender Triggering Policies]. -=== Rollover Strategies +==== Rollover Strategies See link:#RolloverStrategies[RollingFileAppender Rollover Strategies]. @@ -3599,7 +3605,7 @@ Below is a sample configuration that uses a RollingRandomAccessFileAppender with ---- [#RoutingAppender] -== 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. @@ -3678,7 +3684,7 @@ Note that the List Appender is one of our test appenders, any appender can be us ---- [#Routes] -=== 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`. @@ -3763,7 +3769,7 @@ In this example, the script runs for each log event and picks a route based on t ---- [#Purge] -=== Purge Policy +==== 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. @@ -3807,7 +3813,7 @@ Note that the AuditAppender was predefined while the RollingFileAppenders are cr ---- [[SMTPAppender]] -== SMTPAppender +=== SMTPAppender Sends an e-mail when a specific logging event occurs, typically on errors or fatal errors. @@ -3916,7 +3922,7 @@ As with other Appenders, the formatting can be controlled by specifying a Layout ---- [#ScriptAppenderSelector] -== 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 @@ -3952,7 +3958,7 @@ The appender name is recorded under the name of the ---- [#SocketAppender] -== 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. @@ -4062,7 +4068,7 @@ This is a secured link:#SSL[SSL] configuration: ---- [#SSL] -== 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. @@ -4085,7 +4091,7 @@ counterparty. Determines whether the remote authentication credentials |======================================================================= [#KeyStore] -=== KeyStore +==== KeyStore The Keystore is meant to contain your private keys and certificates, and determines which authentication credentials to send to the remote host. @@ -4118,7 +4124,7 @@ algorithms]. |======================================================================= [#TrustStore] -=== 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. @@ -4154,7 +4160,7 @@ algorithms]. |======================================================================= [#Example] -=== Example +==== Example [source,xml] ---- @@ -4165,7 +4171,7 @@ algorithms]. ---- [#SyslogAppender] -== 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. @@ -4331,7 +4337,7 @@ For link:#SSL[SSL] this appender writes its output to a remote destination speci ---- [[JeroMQAppender]] -== ZeroMQ/JeroMQ Appender +=== ZeroMQ/JeroMQ Appender The ZeroMQ appender uses the https://github.com/zeromq/jeromq[JeroMQ] library to send log events to one or more ZeroMQ endpoints. @@ -4462,3 +4468,45 @@ Please consult the JeroMQ and ZeroMQ documentation for details. |boolean |The ZMQ_XPUB_VERBOSE option. Defaults to false. |=== + +[#extending] +== Extending + +Appenders are xref:manual/plugins.adoc[plugins] implementing link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[the `Appender` interface]. +This section will guide you on how to create custom ones. + +[WARNING] +==== +*Implementing a reliable and efficient appender is a difficult task!* +We strongly advise you to + +. Use existing appenders and/or managers whenever appropriate +. Share your use case and ask for feedback in a {logging-services-url}/support.html[user support channel] +==== + +[#extending-plugins] +=== Plugin preliminaries + +include::partial$manual/plugin-preliminaries.adoc[] + +[#extending-appenders] +=== Extending appenders + +Appenders are xref:manual/plugins.adoc[plugins] implementing link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html[the `Appender` interface]. +We recommend users to extend from link:../javadoc/log4j-core/org/apache/logging/log4j/core/appender/AbstractAppender.html[`AbstractAppender`], which provides implementation convenience. +While annotating your appender with `@Plugin`, you need to make sure that + +* It has a unique `name` attribute across all available `Appender` plugins +* The `category` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`] +* The `elementType` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/Appender.html#ELEMENT_TYPE[`Appender.ELEMENT_TYPE`] + +Most appender implementation use *managers*, which model an abstraction owning the resources, such as an `OutputStream` or a socket. +When a reconfiguration occurs a new appender will be created. +However, if nothing significant in the previous manager has changed, the new appender will simply reference it instead of creating a new one. +This ensures that events are not lost while a reconfiguration is taking place without requiring that logging pause while the reconfiguration takes place. +You are strongly advised to study the manager concept in xref:#collection[the predefined appenders], and either use an existing manager, or create your own. + +You can check out following files for examples: + +* {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java[`HttpAppender.java`] – xref:#HttpAppender[] sends log events over HTTP using `HttpURLConnectionManager` +* {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java[`ConsoleAppender.java`] – xref:#ConsoleAppender[Console Appender] writes log events to either `System.out` or `System.err` using `OutputStreamManager` diff --git a/src/site/antora/modules/ROOT/pages/manual/extending.adoc b/src/site/antora/modules/ROOT/pages/manual/extending.adoc index b8d6395681..6b3e67233e 100644 --- a/src/site/antora/modules/ROOT/pages/manual/extending.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/extending.adoc @@ -208,176 +208,6 @@ a separate `FlowMessageFactory`. Applications may replace the `log4j2.flowMessageFactory` to the name of the custom `FlowMessageFactory` class. -[#Lookups] -== Lookups - -Lookups are the means in which parameter substitution is performed. -During Configuration initialization an "Interpolator" is created that -locates all the Lookups and registers them for use when a variable needs -to be resolved. The interpolator matches the "prefix" portion of the -variable name to a registered Lookup and passes control to it to resolve -the variable. - -A Lookup must be declared using a `@Plugin @Lookup` annotation. The `value` specified on the `@Plugin` annotation will be used to -match the prefix. The example below shows a Lookup that will return -the value of a System Property. - -The provided Lookups are documented here: xref:manual/lookups.adoc[Lookups] - -[source,java] ----- -@Lookup -@Plugin("sys") -public class SystemPropertiesLookup implements StrLookup { - - /** - * Lookup the value for the key. - * @param key the key to be looked up, may be null - * @return The value for the key. - */ - public String lookup(String key) { - return System.getProperty(key); - } - - /** - * Lookup the value for the key using the data in the LogEvent. - * @param event The current LogEvent. - * @param key the key to be looked up, may be null - * @return The value associated with the key. - */ - public String lookup(LogEvent event, String key) { - return System.getProperty(key); - } -} ----- - -[#Filters] -== Filters - -As might be expected, Filters are used to reject or accept log -events as they pass through the logging system. A Filter is declared -using a `@Configurable` annotation with an `elementType` of "filter". -The `value` attribute on the `@Plugin` annotation is used to specify the name -of the element users should use to enable the Filter. Specifying the -`printObject` attribute with a value of "true" indicates that a call to -`toString` will format the arguments to the filter as the configuration is -being processed. The Filter must also specify a `@PluginFactory` method -or `@PluginFactoryBuilder` builder class and method -that will be called to create the Filter. - -The example below shows a Filter used to reject LogEvents based upon -their logging level. Notice the typical pattern where all the filter -methods resolve to a single filter method. - -[source,java] ----- -@Plugin(name = "ThresholdFilter", category = "Core", elementType = "filter", printObject = true) -public final class ThresholdFilter extends AbstractFilter { - - private final Level level; - - private ThresholdFilter(Level level, Result onMatch, Result onMismatch) { - super(onMatch, onMismatch); - this.level = level; - } - - public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) { - return filter(level); - } - - public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { - return filter(level); - } - - public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { - return filter(level); - } - - @Override - public Result filter(LogEvent event) { - return filter(event.getLevel()); - } - - private Result filter(Level level) { - return level.isAtLeastAsSpecificAs(this.level) ? onMatch : onMismatch; - } - - @Override - public String toString() { - return level.toString(); - } - - /** - * Create a ThresholdFilter. - * @param level The log Level. - * @param onMatch The action to take on a match. - * @param onMismatch The action to take on a mismatch. - * @return The created ThresholdFilter. - */ - @PluginFactory - public static ThresholdFilter createFilter(@PluginAttribute(defaultStringValue = "ERROR") Level level, - @PluginAttribute(defaultStringValue = "NEUTRAL") Result onMatch, - @PluginAttribute(defaultStringValue = "DENY") Result onMismatch) { - return new ThresholdFilter(level, onMatch, onMismatch); - } -} ----- - -[#Appenders] -== Appenders - -Appenders are passed an event, (usually) invoke a Layout to format the -event, and then "publish" the event in whatever manner is desired. -Appenders are declared as `@Configurable` with an -`elementType` of "appender". The `value` attribute on the `@Plugin` annotation -specifies the name of the element users must provide in their -configuration to use the Appender. Appenders should specify `printObject` -as "true" if the toString method renders the values of the attributes -passed to the Appender. - -Appenders must also declare a `@PluginFactory` method that returns an instance -of the appender or a builder class used to create the appender. The example below shows -an Appender named "Stub" that can be used as an initial template. - -Most Appenders use Managers. A manager actually "owns" the resources, -such as an `OutputStream` or socket. When a reconfiguration occurs a new -Appender will be created. However, if nothing significant in the -previous Manager has changed, the new Appender will simply reference it -instead of creating a new one. This insures that events are not lost -while a reconfiguration is taking place without requiring that logging -pause while the reconfiguration takes place. - -[source,java] ----- -@Plugin(name = "Stub", category = "Core", elementType = "appender", printObject = true) -public final class StubAppender extends AbstractOutputStreamAppender<StubManager> { - - private StubAppender(String name, - Layout<?> layout, - Filter filter, - boolean ignoreExceptions, - StubManager manager) { - super(name, layout, filter, ignoreExceptions, true, manager); - } - - @PluginFactory - public static StubAppender createAppender(@PluginAttribute @Required(message = "No name provided for StubAppender") String name, - @PluginAttribute boolean ignoreExceptions, - @PluginElement Layout layout, - @PluginElement Filter filter) { - - StubManager manager = StubManager.getStubManager(name); - if (manager == null) { - return null; - } - if (layout == null) { - layout = PatternLayout.createDefaultLayout(); - } - return new StubAppender(name, layout, filter, ignoreExceptions, manager); - } -} ----- - [#Plugin_Builders] == Plugin Builders diff --git a/src/site/antora/modules/ROOT/pages/manual/filters.adoc b/src/site/antora/modules/ROOT/pages/manual/filters.adoc index baea1d507b..88e10b79ac 100644 --- a/src/site/antora/modules/ROOT/pages/manual/filters.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/filters.adoc @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. //// + [id=filters] = Filters @@ -85,8 +86,14 @@ Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 1 Using the `level` property of appender references will give a better performance. ==== +[#collection] +== Collection + +Log4j bundles several predefined filters to assist in several common deployment use cases. +Following sections explain all these in detail. + [#BurstFilter] -== 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. @@ -148,7 +155,7 @@ A configuration containing the BurstFilter might look like: ---- [#CompositeFilter] -== 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. @@ -194,7 +201,7 @@ A configuration containing the CompositeFilter might look like: ---- [#DynamicThresholdFilter] -== 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. @@ -262,7 +269,7 @@ Here is a sample configuration containing the DynamicThresholdFilter: ---- [#LevelRangeFilter] -== LevelRangeFilter +=== LevelRangeFilter `LevelRangeFilter` allows filtering against a level range, where levels get compared by their associated integral values; `OFF` has an integral value of 0, `FATAL` 100, `ERROR` 200, and so on. @@ -311,7 +318,7 @@ The filter will return `onMismatch` result (i.e., `DENY`, the default) for log e ---- [#MapFilter] -== MapFilter +=== MapFilter The MapFilter allows filtering against data elements that are in a MapMessage. @@ -431,7 +438,7 @@ This third sample configuration will exhibit the same behavior as the preceding ---- [#MarkerFilter] -== 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. @@ -481,7 +488,7 @@ A sample configuration that only allows the event to be written by the appender ---- [#MutableThreadContextMapFilter] -== MutableThreadContextMapFilter +=== MutableThreadContextMapFilter The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering against data elements that are in the current context. By default, this is the ThreadContext Map. @@ -555,7 +562,7 @@ The configuration file supplied to the filter should look similar to: ---- [#NoMarkerFilter] -== 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. @@ -601,7 +608,7 @@ A sample configuration that only allows the event to be written by the appender ---- [#RegexFilter] -== RegexFilter +=== RegexFilter The RegexFilter allows the formatted or unformatted message to be compared against a regular expression. @@ -771,7 +778,7 @@ xref:manual/appenders.adoc#ScriptCondition[ScriptCondition] for an example of ho ---- [#StructuredDataFilter] -== StructuredDataFilter +=== StructuredDataFilter The StructuredDataFilter is a MapFilter that also allows filtering on the event id, type and message. @@ -836,7 +843,7 @@ As in this configuration, the StructuredDataFilter can be used to log particular ---- [#ThreadContextMapFilter] -== ThreadContextMapFilter +=== ThreadContextMapFilter The ThreadContextMapFilter or ContextMapFilter allows filtering against data elements that are in the current context. By default, this is the ThreadContext Map. @@ -928,7 +935,7 @@ The ContextMapFilter can also be applied to a logger for filtering: ---- [#ThresholdFilter] -== 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. @@ -980,7 +987,7 @@ A sample configuration that only allows the event to be written by the appender ---- [#TimeFilter] -== TimeFilter +=== TimeFilter The time filter can be used to restrict the filter to only a certain portion of the day. @@ -1037,3 +1044,36 @@ A sample configuration that only allows the event to be written by the appender </Loggers> </Configuration> ---- + +[#extending] +== Extending + +Filters are xref:manual/plugins.adoc[plugins] implementing link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.html[the `Filter` interface]. +This section will guide you on how to create custom ones. + +[NOTE] +==== +While xref:#collection[the predefined filter collection] should address most common use cases, you might find yourself needing to implement a custom one. +If this is the case, we really appreciate it if you can *share your use case in a {logging-services-url}/support.html[user support channel]*. +==== + +[#extending-plugins] +=== Plugin preliminaries + +include::partial$manual/plugin-preliminaries.adoc[] + +[#extending-filters] +=== Extending filters + +Filter are xref:manual/plugins.adoc[plugins] implementing link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.html[the `Filter` interface]. +We recommend users to extend from link:../javadoc/log4j-core/org/apache/logging/log4j/core/filter/AbstractFilter.html[`AbstractFilter`], which provides implementation convenience. +While annotating your filter with `@Plugin`, you need to make sure that + +* It has a unique `name` attribute across all available `Filter` plugins +* The `category` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/config/Node.html#CATEGORY[`Node.CATEGORY`] +* The `elementType` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.html#ELEMENT_TYPE[`Filter.ELEMENT_TYPE`] + +You can check out following files for examples: + +* {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MarkerFilter.java[`MarkerFilter.java`] – xref:#MarkerFilter[] matching on markers associated with the effective `LogEvent` in the context +* {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java[`RegexFilter.java`] – xref:#RegexFilter[] matching on the message associated with the effective `LogEvent` in the context diff --git a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc index 6eea0d2afe..33e9749801 100644 --- a/src/site/antora/modules/ROOT/pages/manual/lookups.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/lookups.adoc @@ -25,8 +25,14 @@ be found in the xref:manual/configuration.adoc#PropertySubstitution[Property Substitution] section of the xref:manual/configuration.adoc[Configuration] page. +[#collection] +== Collection + +Log4j bundles several predefined lookups to assist in several common deployment use cases. +Following sections explain all these in detail. + [#ContextMapLookup] -== Context Map Lookup +=== Context Map Lookup The ContextMapLookup allows applications to store data in the Log4j ThreadContext Map and then retrieve the values in the Log4j @@ -47,7 +53,7 @@ resolve the variable for each event. Note that the pattern ---- [#DateLookup] -== Date Lookup +=== Date Lookup The DateLookup is somewhat unusual from the other lookups as it doesn't use the key to locate an item. Instead, the key can be used to specify a @@ -67,7 +73,7 @@ be formatted as specified. ---- [#DockerLookup] -== Docker Lookup +=== Docker Lookup The DockerLookup can be used to lookup attributes from the Docker container the application is running in. @@ -107,7 +113,7 @@ 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] [id=environment-lookup] -== [[EnvironmentLookup]] 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 @@ -136,8 +142,9 @@ when the `USER` environment variable is undefined, the default value </PatternLayout> </File> ---- + [#EventLookup] -== Event Lookup +=== Event Lookup The EventLookup provides access to fields within the log event from the configuration. @@ -212,7 +219,7 @@ present in the log event. ---- [#JavaLookup] -== Java Lookup +=== Java Lookup The JavaLookup allows Java environment information to be retrieved in convenient preformatted strings using the `java:` prefix. @@ -265,7 +272,7 @@ For example: ---- [#JndiLookup] -== JNDI Lookup +=== JNDI Lookup As of Log4j 2.15.1 JNDI operations require that `log4j2.enableJndi=true` be set as a system property or the corresponding environment variable for this lookup to function. See the @@ -295,7 +302,7 @@ or ip address are supported along with any hosts or ip addresses listed in the *Java's JNDI module is not available on Android.* [#JmxRuntimeInputArgumentsLookup] -== JVM Input Arguments Lookup (JMX) +=== JVM Input Arguments Lookup (JMX) Maps JVM input arguments -- but not _main_ arguments -- using JMX to acquire the JVM arguments. @@ -308,7 +315,7 @@ https://docs.oracle.com/javase/8/docs/api/java/lang/management/RuntimeMXBean.htm *Java's JMX module is not available on Android or on Google App Engine.* [#KubernetesLookup] -== Kubernetes Lookup +=== Kubernetes Lookup For retrieving attributes using Fabric8's Kubernetes Client, see their https://github.com/fabric8io/kubernetes-client/blob/main/doc/KubernetesLog4j.md[Kubernetes Log4j Lookup]. @@ -333,7 +340,7 @@ relative to the log4j configuration file. ---- [#LowerLookup] -== Lower Lookup +=== Lower Lookup The LowerLookup converts the passed in argument to lower case. Presumably the value will be the result of a nested lookup. @@ -348,7 +355,7 @@ result of a nested lookup. ---- [#AppMainArgsLookup] -== Main Arguments Lookup (Application) +=== Main Arguments Lookup (Application) This lookup requires that you manually provide the main arguments of the application to Log4j: @@ -378,9 +385,10 @@ key must be followed by a backslash as an escape character as in `${main:\--file For example, suppose the static void main String[] arguments are: -.... +[source,text] +---- --file foo.txt --verbose -x bar -.... +---- Then the following substitutions are possible: @@ -428,7 +436,7 @@ Example usage: ---- [#MapLookup] -== Map Lookup +=== Map Lookup The MapLookup serves several purposes. @@ -469,7 +477,7 @@ page for information on how to set the default values. </Routing> ---- -== Marker Lookup +=== Marker Lookup The marker lookup allows you to use markers in interesting configurations like a routing appender. Consider the following YAML @@ -538,7 +546,8 @@ You can use the notation `"${marker:name}"` and `"$${marker:name}"` to check for the existence of a marker where `name` is the marker name. If the marker exists, the expression returns the name, otherwise `null`. -== Resource Bundle Lookup +=== Resource Bundle Lookup + The resource bundle lookup retrieves values from Resource Bundles (see Java documentation). The format is `${bundle:BundleName:BundleKey}`. The bundle name follows package naming conventions, for example: `${bundle:com.domain.Messages:MyKey}`. [source, xml] @@ -550,7 +559,8 @@ The resource bundle lookup retrieves values from Resource Bundles (see Java docu </File> ---- -== Spring Boot Lookup +=== Spring Boot Lookup + The Spring Boot Lookup retrieves the values of Spring properties from the Spring configuration as well as values of the active and default profiles. Specifying a key of "profiles.active" will return the active profiles while a key of "profiles.default" will return the default profiles. The default and active profiles can be an array. If more than one profile is present they will be returned as a comma separated list. To retrieve a single item from the array append "[\{index}]" to the key [...] This Lookup will return null values until Spring Boot initializes application logging. The Spring Boot Lookup requires the log4j-spring-boot jar be included as a dependency. @@ -567,7 +577,7 @@ This Lookup will return null values until Spring Boot initializes application lo This Lookup requires log4j-spring-cloud-config-client be included in the application. [#StructuredDataLookup] -== Structured Data Lookup +=== Structured Data Lookup The StructuredDataLookup is very similar to the MapLookup in that it will retrieve values from StructuredDataMessages. In addition to the Map @@ -596,7 +606,7 @@ while "type" would have to be an item in the Map in a MapMessage. ---- [id=system-properties-lookup] -== [[SystemPropertiesLookup]] 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 @@ -623,7 +633,7 @@ when the `logPath` system property is undefined, the default value ---- [#UpperLookup] -== Upper Lookup +=== Upper Lookup The LowerLookup converts the passed in argument to upper case. Presumably the value will be the result of a nested lookup. @@ -638,7 +648,7 @@ result of a nested lookup. ---- [#WebLookup] -== Web Lookup +=== Web Lookup The WebLookup allows applications to retrieve variables that are associated with the ServletContext. In addition to being able to @@ -698,3 +708,34 @@ located then the corresponding value will be returned. <File name="ApplicationLog" fileName="${web:rootDir}/app.log"/> </Appenders> ---- + +[#extending] +== Extending + +Lookups are xref:manual/plugins.adoc[plugins] implementing link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[the `StrLookup` interface]. +This section will guide you on how to create custom ones. + +[NOTE] +==== +While xref:#collection[the predefined lookup collection] should address most common use cases, you might find yourself needing to implement a custom one. +If this is the case, we really appreciate it if you can *share your use case in a {logging-services-url}/support.html[user support channel]*. +==== + +[#extending-plugins] +=== Plugin preliminaries + +include::partial$manual/plugin-preliminaries.adoc[] + +[#extending-lookups] +=== Extending lookups + +Lookups are xref:manual/plugins.adoc[plugins] implementing link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html[the `StrLookup` interface]. +While annotating your lookup with `@Plugin`, you need to make sure that + +* It has a unique `name` attribute across all available `StrLookup` plugins +* The `category` attribute is set to link:../javadoc/log4j-core/org/apache/logging/log4j/core/lookup/StrLookup.html#CATEGORY[`StrLookup.CATEGORY`] + +You can check out following files for examples: + +* {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/DateLookup.java[`LowerLookup.java`] – xref:#LowerLookup[] lower-cases its input +* {project-github-url}/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/EventLookup.java[`EventLookup.java`] – xref:#EventLookup[] extracts specified fields from the effective `LogEvent` in the context diff --git a/src/site/resources/.htaccess b/src/site/resources/.htaccess index 708c2c5df7..6bef5ba191 100644 --- a/src/site/resources/.htaccess +++ b/src/site/resources/.htaccess @@ -54,7 +54,10 @@ RewriteRule "^log4j-slf4j-impl\.html$" "manual/installation.html#impl-core-bridg RewriteRule "^log4j-slf4j2-impl/index\.html$" "manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE] RewriteRule "^log4j-slf4j2-impl\.html$" "manual/installation.html#impl-core-bridge-slf4j" [R=permanent,NE] RewriteRule "^manual/api-separation\.html$" "manual/api.html" [R=permanent] +RewriteRule "^manual/extending\.html#Appenders$" "manual/appenders.html#extending" [R=permanent] +RewriteRule "^manual/extending\.html#Filters$" "manual/filters.html#extending" [R=permanent] RewriteRule "^manual/extending\.html#Layouts$" "manual/layouts.html#extending" [R=permanent] +RewriteRule "^manual/extending\.html#Lookups$" "manual/lookups.html#extending" [R=permanent] RewriteRule "^manual/extending\.html#PatternConverters$" "manual/pattern-layout.html#extending-converters" [R=permanent] RewriteRule "^manual/layouts\.html#enable-jansi$" "manual/pattern-layout.html#jansi" [R=permanent] RewriteRule "^manual/layouts\.html#EndOfBatch$" "manual/pattern-layout.html#converter-end-of-batch" [R=permanent]
