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 df1813d2c1079a7bdbe436a90a6361b68b29b636
Merge: 34eb9f036e 204d825129
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Tue Jun 25 10:35:58 2024 +0200

    Merge remote-tracking branch 'origin/2.x' into doc/2.x/extending
    
    # Conflicts:
    #       src/site/antora/modules/ROOT/pages/manual/customloglevels.adoc

 .mvn/extensions.xml                                |   2 +-
 .mvn/wrapper/maven-wrapper.properties              |   4 +-
 .../manual/customloglevels/LevelExample.java       |  49 ++++
 .../manual/customloglevels/custom/log4j2.json      |  34 ---
 .../manual/customloglevels/custom/log4j2.xml       |  28 --
 .../manual/customloglevels/custom/log4j2.yaml      |  37 ---
 .../manual/customloglevels/filtering/log4j2.json   |  24 --
 .../customloglevels/filtering/log4j2.properties    |  24 --
 .../manual/customloglevels/filtering/log4j2.xml    |  21 --
 .../examples/manual/customloglevels/log4j2.json    |  41 +++
 .../customloglevels/{custom => }/log4j2.properties |  23 +-
 .../{filtering/logback.xml => log4j2.xml}          |  38 +--
 .../customloglevels/{filtering => }/log4j2.yaml    |  20 +-
 src/site/antora/modules/ROOT/nav.adoc              |   2 +
 src/site/antora/modules/ROOT/pages/log4j-jul.adoc  | 196 ++++++++++++++
 .../antora/modules/ROOT/pages/log4j-to-jul.adoc    |  38 +++
 .../modules/ROOT/pages/manual/customloglevels.adoc | 289 +++++++++++++--------
 .../modules/ROOT/pages/manual/installation.adoc    |   8 +-
 .../ROOT/partials/manual/levels-log4j-to-jul.adoc  |  43 +++
 .../systemproperties/properties-log4j-jul.adoc     |  20 +-
 src/site/resources/.htaccess                       |   3 +-
 21 files changed, 618 insertions(+), 326 deletions(-)

diff --cc 
src/site/antora/modules/ROOT/examples/manual/customloglevels/LevelExample.java
index 0000000000,ceb92caaea..ceb92caaea
mode 000000,100644..100644
--- 
a/src/site/antora/modules/ROOT/examples/manual/customloglevels/LevelExample.java
+++ 
b/src/site/antora/modules/ROOT/examples/manual/customloglevels/LevelExample.java
diff --cc 
src/site/antora/modules/ROOT/examples/manual/customloglevels/log4j2.json
index 0000000000,e29890d90c..e29890d90c
mode 000000,100644..100644
--- a/src/site/antora/modules/ROOT/examples/manual/customloglevels/log4j2.json
+++ b/src/site/antora/modules/ROOT/examples/manual/customloglevels/log4j2.json
diff --cc src/site/antora/modules/ROOT/pages/manual/customloglevels.adoc
index 42423e751a,b197e3dc63..3496c96b72
--- a/src/site/antora/modules/ROOT/pages/manual/customloglevels.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/customloglevels.adoc
@@@ -23,19 -22,43 +22,43 @@@ Using levels, you can filter out less i
  
  Log4j contains following predefined levels:
  
- [%header,cols="1m,1"]
+ .Standard log levels
+ [%header,cols="1,1m",id=standard-log-levels]
  |===
- |Name |Priority
- |OFF |0
- |FATAL |100
- |ERROR |200
- |WARN |300
- |INFO |400
- |DEBUG |500
- |TRACE |600
- |ALL |`Integer.MAX_VALUE`
+ | Name | Priority
+ 
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Level#OFF[`OFF`]<<dont-use-in-code,[see
 note]>>
+ | 0
+ 
+ | link:../javadoc/log4j-api/org/apache/logging/log4j/Level#FATAL[`FATAL`]
+ | 100
+ 
+ | link:../javadoc/log4j-api/org/apache/logging/log4j/Level#ERROR[`ERROR`]
+ | 200
+ 
+ | link:../javadoc/log4j-api/org/apache/logging/log4j/Level#WARN[`WARN`]
+ | 300
+ 
+ | link:../javadoc/log4j-api/org/apache/logging/log4j/Level#INFO[`INFO`]
+ | 400
+ 
+ | link:../javadoc/log4j-api/org/apache/logging/log4j/Level#DEBUG[`DEBUG`]
+ | 500
+ 
+ | link:../javadoc/log4j-api/org/apache/logging/log4j/Level#TRACE[`TRACE`]
+ | 600
+ 
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Level#ALL[`ALL`]<<dont-use-in-code,[see
 note]>>
+ | Integer.MAX_VALUE
  |===
  
+ [IMPORTANT,id=dont-use-in-code]
+ ====
+ The `OFF` and `ALL` levels are special: they should not be used to fish-tag 
log events.
+ 
 -Log4j implementations, such as Log4j Core, can use `OFF` in their 
configuration files to disable all log statements and `ALL` to enabled them all.
++Log4j API implementations, such as Log4j Core, can use `OFF` in their 
configuration files to disable all log statements and `ALL` to enabled them all.
+ ====
+ 
  A level is composed of a case-sensitive name and a *priority* (of type 
`int`), which is used to define an order while comparing two.
  Priority can be used in several contexts to express a filtering capability, 
for instance:
  
@@@ -48,165 -71,207 +71,207 @@@ Predefined levels are available for Log
  [#usage]
  == [[StandardLoggerInterface]] Usage
  
- You can specify the log level while using `Logger` in several ways:
+ To assign a level to a log event you can use one of the variants of the
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#log(org.apache.logging.log4j.Level,org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[`Logger.log(..)`]
+ and
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atLevel(org.apache.logging.log4j.Level)[`Logger.atLevel(Level)`]
+ methods:
  
- [source,java]
+ [source,java,indent=0]
  ----
- LOGGER.info("Hello, {}!", userName); // <1>
- LOGGER.log(Level.INFO, "Hello, {}!", userName); // <2>
 -include::example$manual/customlevels/LevelExample.java[tag=standard]
++include::example$manual/customloglevels/LevelExample.java[tag=standard]
  ----
- <1> Using `Logger#info()` to log a message at `INFO` level
- <2> Using `Logger#log()` to log a message and specifying the `INFO` level 
explicitly
  
- [#DefiningLevelsInCode]
- === Custom log levels
+ The `Logger` interface also contains shorthand methods that always log at a 
specified log level:
  
- Users can programmatically define custom levels using 
link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#forName(java.lang.String,int)[the
 `Level.forName()` method]:
+ .Shorthand `Logger` methods
+ [%header,cols="1m,3m"]
+ |===
+ | Effective level | Shorthand methods
  
- [source,java]
- ----
- public final class CustomLogLevel {
+ | FATAL
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#fatal(org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[Logger.fatal(..)],
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atFatal()[Logger.atFatal()]
  
-     public static final Level VERBOSE = Level.forName("VERBOSE", 550); // <1>
+ | ERROR
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#error(org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[Logger.error(..)],
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atError()[Logger.atError()]
  
- }
- ----
- <1> Creating a custom level with name `VERBOSE` and priority 550
+ | WARN
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#warn(org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[Logger.warn(..)],
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atWarn()[Logger.atWarn()]
  
- Once defined, you can log messages at this level by calling the 
`Logger#log()` method and passing the custom log level:
+ | INFO
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#info(org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[Logger.info(..)],
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atInfo()[Logger.atInfo()]
  
- [source,java]
- ----
- public class PurchaseOrder {
+ | DEBUG
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#debug(org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[Logger.debug(..)],
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atDebug()[Logger.atDebug()]
  
-     private static final Logger LOGGER = LogManager.getLogger();
+ | TRACE
+ | 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#trace(org.apache.logging.log4j.Marker,org.apache.logging.log4j.message.Message)[Logger.trace(..)],
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Logger.html#atTrace()[Logger.atTrace()]
  
-     public PurchaseOrder(String id) {
-         LOGGER.log(CustomLogLevel.VERBOSE, "Creating purchase order with ID 
`{}`", id); // <1>
-         // ...
-     }
+ |===
  
-     // ...
+ By using shorthand methods, you can rewrite the example above as:
  
- }
+ [source,java,indent=0]
+ ----
 -include::example$manual/customlevels/LevelExample.java[tag=shorthand]
++include::example$manual/customloglevels/LevelExample.java[tag=shorthand]
  ----
- <1> Logging with the created custom level
  
- [#config]
- == Configuration
+ [#level-selection]
+ === Which level to use?
  
- Levels can be used in various ways in a configuration file.
- We will explain some important ones from multiple logging implementations.
+ [CAUTION]
+ ====
+ While Log4j API defines a set of standard levels, it does not define the 
purpose of these levels.
+ Many different conventions on which log levels to use coexist in the industry.
+ When in doubt, you should ask your teammates about the convention used at 
your company.
+ ====
  
- [#config-core]
- === Log4j Core
+ Most log level usage conventions divide log levels into two categories:
  
- Log4j Core, the reference implementation of Log4j API, has extensive support 
for levels.
- It allows both <<config-core-filter,basic level-based filtering>> and 
<<DefiningLevelsInConfiguration,custom log levels>>.
+ * the most severe log levels (e.g. `FATAL`, `ERROR` and `WARN`) are used to 
inform the system administrator about a problem in the Java application that 
needs to be fixed.
+ The more severe the problem, the more severe the log level.
+ +
+ Log events with these levels should be used sparingly and should allow the 
system administrator to fix the problem.
  
- [#config-core-filter]
- ==== Basic filtering
+ * the less severe log levels (e.g. `INFO`, `DEBUG`, `TRACE`) provide context 
that allow a system administrator or developer to diagnose the reason of an 
application failure.
+ The most severe of them describe events that concern the whole application, 
while the less severe describe events that are interesting for a single 
sub-system.
  
- Filtering on levels for loggers is a pretty common example:
+ [#DefiningLevelsInCode]
+ === Custom log levels
  
- [tabs]
- ====
- XML::
- +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/filtering/log4j2.xml[`log4j2.xml`] 
configuring level-filtered loggers
- [source,xml]
- ----
- 
include::example$manual/customloglevels/filtering/log4j2.xml[lines=14..19,indent=0]
- ----
+ While most Java logging APIs adopt the same set of standard logging levels, 
some logging APIs, such as xref:log4j-jul.adoc#default-level-conversions[JUL]
+ and external logging systems, such as
+ https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1[Syslog]
+ and
+ 
https://opentelemetry.io/docs/specs/otel/logs/data-model/#displaying-severity[OpenTelemetry]
+ support additional logging levels that can not be mapped to the standard ones.
  
- JSON::
- +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/filtering/log4j2.json[`log4j2.json`]
 configuring level-filtered loggers
- [source,xml]
- ----
- 
include::example$manual/customloglevels/filtering/log4j2.json[lines=9..22,indent=0]
- ----
+ To improve interoperability between logging systems, Log4j API supports 
custom log levels that can be defined using the
+ 
link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#forName(java.lang.String,int)[`Level.forName()`]
+ method:
  
- YAML::
- +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/filtering/log4j2.yaml[`log4j2.yaml`]
 configuring level-filtered loggers
- [source,xml]
+ [source,java,indent=0]
  ----
- 
include::example$manual/customloglevels/filtering/log4j2.yaml[lines=24..31,indent=0]
 -include::example$manual/customlevels/LevelExample.java[tag=custom-definition]
++include::example$manual/customloglevels/LevelExample.java[tag=custom-definition]
  ----
  
- Properties::
- +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/filtering/log4j2.properties[`log4j2.properties`]
 configuring level-filtered loggers
- [source,xml]
+ Custom log levels can be used in your code with the usual `Logger.log(..)` 
and `Logger.atLevel(Level)` methods:
+ 
+ [source,java,indent=0]
  ----
- 
include::example$manual/customloglevels/filtering/log4j2.properties[lines=21..24]
 -include::example$manual/customlevels/LevelExample.java[tag=custom]
++include::example$manual/customloglevels/LevelExample.java[tag=custom]
  ----
+ 
+ [#implementation-support]
+ == Implementation support
+ 
+ All logging implementations support filtering of log events, based on their 
log level, but the number of available log levels varies between 
implementations.
+ 
+ [WARNING]
+ ====
+ While most logging implementations support <<standard-log-levels,standard log 
levels>>, custom log levels are only supported by Log4j Core (and the EOL Log4j 
1).
+ To ensure independence from a specific logging implementation you should 
restrict your log statements to **standard** log levels.
+ 
+ If you use custom log levels as a fish-tagging technique, you can use 
alternative
+ xref:manual/api.adoc#fish-tagging[fish-tagging features]
+ such as
+ xref:manual/markers.adoc[],
+ which are supported by multiple logging implementations.
  ====
- <1> Logs of level `INFO` or higher severity (i.e., `WARN`, `ERROR`, `FATAL`) 
are allowed for `com.mycompany` package
- <2> Logs of level `ERROR` or higher severity (i.e., `FATAL`) are allowed for 
the rest
  
  [#DefiningLevelsInConfiguration]
- ==== Custom log levels
- 
- Log4j Core, the reference implementation of Log4j API, requires a custom 
level to be defined first, before it can be used in a configuration file.
- To facilitate this, the `CustomLevel` configuration element is used to define 
a custom level.
- Internally it calls the same `Level.forName()` method discussed in 
<<DefiningLevelsInCode>>.
+ === Log4j Core
  
- The following example shows a configuration that defines the `VERBOSE` custom 
log level and uses it to filter log events sent to the console.
+ The Log4j Core implementation fully supports both standard and custom levels.
+ Similarly to the <<DefiningLevelsInCode,Log4j API usage>>, custom levels must 
be defined in a configuration file before they can be used.
+ You can do it using
+ 
xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-CustomLevelConfig[`CustomLevel`]
+ configuration elements:
  
  [tabs]
  ====
  XML::
  +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/custom/log4j2.xml[`log4j2.xml`] 
configuring custom log levels
  [source,xml]
  ----
- 
include::example$manual/customloglevels/custom/log4j2.xml[lines=17..26,indent=0]
 -include::example$manual/customlevels/log4j2.xml[lines=1;18..-1]
++include::example$manual/customloglevels/log4j2.xml[lines=1;18..-1]
  ----
  
  JSON::
  +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/custom/log4j2.json[`log4j2.json`] 
configuring custom log levels
  [source,xml]
  ----
- 
include::example$manual/customloglevels/custom/log4j2.json[lines=13..32,indent=0]
 -include::example$manual/customlevels/log4j2.json[]
++include::example$manual/customloglevels/log4j2.json[]
  ----
  
  YAML::
  +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/custom/log4j2.yaml[`log4j2.yaml`] 
configuring custom log levels
- [source,xml]
+ [source,yaml]
  ----
- 
include::example$manual/customloglevels/custom/log4j2.yaml[lines=27..37,indent=0]
 -include::example$manual/customlevels/log4j2.yaml[lines=17..-1]
++include::example$manual/customloglevels/log4j2.yaml[lines=17..-1]
  ----
  
  Properties::
  +
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/custom/log4j2.properties[`log4j2.properties`]
 configuring custom log levels
- [source,xml]
+ [source,properties]
  ----
- include::example$manual/customloglevels/custom/log4j2.properties[lines=24..30]
 -include::example$manual/customlevels/log4j2.properties[lines=17..-1]
++include::example$manual/customloglevels/log4j2.properties[lines=17..-1]
  ----
  ====
- <1> Defining the `VERBOSE` custom log level
- <2> Only events of `VERBOSE` level or higher severity are sent to the console
  
- [#config-logback]
- === Logback
+ <1> All the available xref:manual/layouts.adoc[] support printing levels.
+ In the case of
+ xref:manual/pattern-layout.adoc[]
+ you can use a xref:manual/pattern-layout.adoc#converter-level[`%p` or 
`%level`] pattern.
+ <2> Loggers support a 
xref:manual/configuration.adoc#logger-attributes-level[`level`] configuration 
attribute to filter log events.
+ <3> A xref:manual/configuration.adoc#appenderref-attributes-level[`level`] 
attribute is also available in appender references.
+ <4> Custom levels must be defined before they can be used.
+ <5> Custom levels can be used anywhere a standard level can be used.
  
- {logback-url}[Logback] can be configured as follows to define level-filtered 
loggers:
+ [#slf4j-implementations]
+ === SLF4J implementations (Logback)
  
- .Snippet from an example 
{antora-examples-url}/manual/customloglevels/filtering/logback.xml[`logback.xml`]
 configuring level-filtered loggers
- [source,xml]
- ----
- 
include::example$manual/customloglevels/filtering/logback.xml[lines=29..32,indent=0]
- ----
+ Since SLF4J only supports five log levels (`ERROR`, `WARN`, `INFO`, `DEBUG` 
and `TRACE`) and does not support custom log levels,
+ Log4j API levels are converted according to the following table:
+ 
+ .Log4j to SLF4J level conversion
+ [%header,cols="1m,1m,1m"]
+ |===
+ | Log4j level priority | Log4j standard levels | SLF4J Level
+ 
+ | 0 < priority < 300
+ | FATAL, ERROR
+ | https://www.slf4j.org/api/org/slf4j/event/Level.html#ERROR[ERROR]
+ 
+ | 300 &le; priority < 400
+ | WARN
+ | https://www.slf4j.org/api/org/slf4j/event/Level.html#WARN[WARN]
+ 
+ | 400 &le; priority < 500
+ | INFO
+ | https://www.slf4j.org/api/org/slf4j/event/Level.html#INFO[INFO]
+ 
+ | 500 &le; priority < 600
+ | DEBUG
+ | https://www.slf4j.org/api/org/slf4j/event/Level.html#DEBUG[DEBUG]
+ 
+ | 600 &le; priority
+ | TRACE
+ | https://www.slf4j.org/api/org/slf4j/event/Level.html#TRACE[TRACE]
+ 
+ |===
+ 
+ [#jul]
+ === JUL (`java.util.logging`)
+ 
+ Similarly to Log4j API, `java.util.logging` also supports custom log levels, 
but the current
+ xref:log4j-to-jul.adoc[] implementation does not take advantage of them.
+ The conversion of between Log4j log levels and JUL levels is performed 
accordingly to the following table:
+ 
+ include::partial$manual/levels-log4j-to-jul.adoc[]

Reply via email to