[
https://issues.apache.org/jira/browse/LOG4J2-710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Remko Popma updated LOG4J2-710:
-------------------------------
Description:
_Documentation preview. Feedback welcome._
_Side-nav menu:_
* [Custom Log Levels|#Custom]
** [Adding or Replacing Levels|#Customizing]
** [Generating Logger Wrappers|#wrapper]
** [Example Usage|#GeneratedWrapperUsage]
** [Tool Usage|#GenerateExtended]
_Custom Loggers page:_
{anchor:CustomLevels}
*[#Custom] Log Levels*
Log4J 2 supports custom log levels. It is possible to log messages at any
self-defined custom level by passing this level to the {{Logger.log()}} method:
{code}
final Logger logger = LogManager.getLogger();
final Level VERBOSE = Level.forName("VERBOSE", 550);
logger.log(VERBOSE, "a verbose message");
logger.log(VERBOSE, "another message");
{code}
When defining a custom log level, the {{intLevel}} parameter (550 in the
example above) determines where the custom level exists in relation to the
standard levels built in to Log4J 2. For reference, the table below shows the
{{intLevel}} of the built-in log levels.
||Standard Level||intLevel||
|OFF|0|
|FATAL|100|
|ERROR|200|
|WARN|300|
|INFO|400|
|DEBUG|500|
|TRACE|600|
|ALL|Integer.MAX_VALUE|
{anchor:Extending}
*The Standard Logger Interface*
The built-in levels have a set of convenience methods on the Logger interface
that makes them easier to use. For example, the Logger interface has 14 debug
methods that support the DEBUG level:
{code}
// convenience methods for the built-in DEBUG level
debug(Marker, Message)
debug(Marker, Message, Throwable)
debug(Marker, Object)
debug(Marker, Object, Throwable)
debug(Marker, String)
debug(Marker, String, Object...)
debug(Marker, String, Throwable)
debug(Message)
debug(Message, Throwable)
debug(Object)
debug(Object, Throwable)
debug(String)
debug(String, Object...)
debug(String, Throwable)
{code}
Similar method sets exist for the other built-in levels.
{anchor:Customizing}
*Adding or Replacing Levels*
It would be nice to have the same ease of use with custom levels, so that after
declaring a custom VERBOSE level, we would be able to use code like this:
{code}
logger.verbose("a verbose message"); // no need to pass the VERBOSE level as a
parameter
logger.verbose("another message");
{code}
In the above example, a convenience method was _added_ to the Logger interface,
in addition to the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods
for the built-in log levels.
There is another use case, Domain Specific Language loggers, where we want to
_replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with
all-custom methods.
For example, for medical devices we could have only {{critical()}},
{{warning()}}, and {{advisory()}} methods. Another example could be a game that
has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels.
If it were possible to hide existing log levels, users could customize the
Logger interface to match their requirements. Some people may not want to have
a {{FATAL}} or a {{TRACE}} level, for example. They would like to be able to
create a custom Logger that only has {{debug()}}, {{info()}}, {{warn()}} and
{{error()}} methods.
{anchor:wrapper}
*Generating source code for a Logger [#wrapper]*
Common Log4J usage is to get an instance of the {{Logger}} interface from the
{{LogManager}} and call the methods on this interface. However, the custom log
Levels are not known in advance, so Log4J cannot provide an interface with
convenience methods for these custom log Levels.
To solve this, Log4J ships with a tool that generates source code for a Logger
wrapper. The generated wrapper class has convenience methods for each custom
log level, making custom levels just as easy to use as the built-in levels.
There are two flavors of wrappers: ones that _extend_ the {{Logger}} API
(_adding_ methods to the built-in levels) and ones that _customize_ the
{{Logger}} API (_replacing_ the built-in methods).
When generating the source code for a wrapper class, you need to specify:
* the fully qualified name of the class to generate
* the list of custom levels to support and their {{intLevel}} relative strength
* whether to extend {{Logger}} (and keep the existing built-in methods) or have
only methods for the custom log levels
You would then include the generated source code in the project where you want
to use custom log levels.
{anchor:GeneratedWrapperUsage}
*Example Usage of a Generated Logger Wrapper*
Here is an example of how one would use a generated logger wrapper for custom
levels DIAG, NOTICE and VERBOSE:
{code}
// ExtLogger is a generated logger wrapper
import com.mycompany.myproject.ExtLogger;
public class MyService {
// instead of Logger logger = LogManager.getLogger(MyService.class):
private static final ExtLogger logger = ExtLogger.create(MyService.class);
public void someMethod() {
// ...
logger.trace("the built-in TRACE level");
logger.verbose("a custom level: a VERBOSE message");
logger.debug("the built-in DEBUG level");
logger.notice("a custom level: a NOTICE message");
logger.info("the built-in INFO level");
logger.diag("a custom level: a DIAG message");
logger.warn("the built-in WARN level");
logger.error("the built-in ERROR level");
logger.fatal("the built-in FATAL level");
// ...
}
...
}
{code}
{anchor:GenerateExtended}
*Generating Extended Loggers*
Use the following command to generate a wrapper that adds methods to the
built-in ones:
{code}
java -cp log4j-core-2.0.jar
org.apache.logging.log4j.core.tools.Generate$ExtendedLogger
com.mycomp.ExtLogger DIAG=350 NOTICE=450 VERBOSE=550 > com/mycomp/ExtLogger.java
{code}
This will generate source code for a logger wrapper that has the convenience
methods for the built-in levels _as well as_ the specified custom levels. The
tool sends the generated source code to the console, so we redirected the
output to a file.
{anchor:GenerateCustom}
*Generating Custom Loggers*
Use the following command to generate a wrapper that hides the built-in levels
and has only custom levels:
{code}
java -cp log4j-core-2.0.jar
org.apache.logging.log4j.core.tools.Generate$CustomLogger com.mycomp.MyLogger
DEFCON1=350 DEFCON2=450 DEFCON3=550 > com/mycomp/MyLogger.java
{code}
This will generate source code for a logger wrapper that has _only_ convenience
methods for the specified custom levels, _not for the built-in levels_. The
tool sends the generated source code to the console, so we redirected the
output to a file.
was:
_Documentation preview. Feedback welcome._
_Side-nav menu:_
* [Custom Log Levels|#Custom]
** [Adding or Replacing Levels|#Customizing]
** [Generating Logger Wrappers|#wrapper]
** [Example Usage|#GeneratedWrapperUsage]
** [Tool Usage|#GenerateExtended]
_Custom Loggers page:_
{anchor:CustomLevels}
*[#Custom] Log Levels*
Log4J 2 supports custom log levels. It is possible to log messages at any
self-defined custom level by passing this level to the {{Logger.log()}} method:
{code}
final Logger logger = LogManager.getLogger();
final Level VERBOSE = Level.forName("VERBOSE", 550);
logger.log(VERBOSE, "a verbose message");
logger.log(VERBOSE, "another message");
{code}
When defining a custom log level, the {{intLevel}} parameter (550 in the
example above) determines where the custom level exists in relation to the
standard levels built in to Log4J 2. For reference, the table below shows the
{{intLevel}} of the built-in log levels.
||Standard Level||intLevel||
|OFF|0|
|FATAL|100|
|ERROR|200|
|WARN|300|
|INFO|400|
|DEBUG|500|
|TRACE|600|
|ALL|Integer.MAX_VALUE|
{anchor:Extending}
*The Standard Logger Interface*
The built-in levels have a set of convenience methods on the Logger interface
that makes them easier to use. For example, the Logger interface has 14 debug
methods that support the DEBUG level:
{code}
// convenience methods for the built-in DEBUG level
debug(Marker, Message)
debug(Marker, Message, Throwable)
debug(Marker, Object)
debug(Marker, Object, Throwable)
debug(Marker, String)
debug(Marker, String, Object...)
debug(Marker, String, Throwable)
debug(Message)
debug(Message, Throwable)
debug(Object)
debug(Object, Throwable)
debug(String)
debug(String, Object...)
debug(String, Throwable)
{code}
Similar method sets exist for the other built-in levels.
{anchor:Customizing}
*Adding or Replacing Levels*
It would be nice to have the same ease of use with custom levels, so that after
declaring a custom VERBOSE level, we would be able to use code like this:
{code}
logger.verbose("a verbose message"); // no need to pass the VERBOSE level as a
parameter
logger.verbose("another message");
{code}
In the above example, a convenience method was _added_ to the Logger interface,
in addition to the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods
for the built-in log levels.
There is another use case, Domain Specific Language loggers, where we want to
_replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with
all-custom methods.
For example, for medical devices we could have only {{critical()}},
{{warning()}}, and {{advisory()}} methods. Another example could be a game that
has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels.
If it were possible to hide existing log levels, users could customize the
Logger interface to match their requirements. Some people may not want to have
a {{FATAL}} or a {{TRACE}} level, for example. They would like to be able to
create a custom Logger that only has {{debug()}}, {{info()}}, {{warn()}} and
{{error()}} methods.
{anchor:wrapper}
*Generating source code for a Logger [#wrapper]*
Common Log4J usage is to get an instance of the {{Logger}} interface from the
{{LogManager}} and call the methods on this interface. However, the custom log
Levels are not known in advance, so Log4J cannot provide an interface with
convenience methods for these custom log Levels.
To solve this, Log4J ships with a tool that generates source code for a Logger
wrapper. The generated wrapper class has convenience methods for each custom
log level, making custom levels just as easy to use as the built-in levels.
There are two flavors of wrappers: ones that _extend_ the {{Logger}} API
(_adding_ methods to the built-in levels) and ones that _customize_ the
{{Logger}} API (_replacing_ the built-in methods).
When generating the source code for a wrapper class, you need to specify:
* the fully qualified name of the class to generate
* the list of custom levels to support and their {{intLevel}} relative strength
* whether to extend {{Logger}} (and keep the existing built-in methods) or have
only methods for the custom log levels
You would then include the generated source code in the project where you want
to use custom log levels.
{anchor:GeneratedWrapperUsage}
*Example Usage of a Generated Logger Wrapper*
Here is an example of how one would use a generated logger wrapper for custom
levels DIAG, NOTICE and VERBOSE:
{code}
// ExtLogger is a generated logger wrapper
import com.mycompany.myproject.ExtLogger;
public class MyService {
// instead of Logger logger = LogManager.getLogger(MyService.class):
private static final ExtLogger logger = ExtLogger.create(MyService.class);
public void someMethod() {
// ...
logger.trace("the built-in TRACE level");
logger.verbose("a custom level: a VERBOSE message");
logger.debug("the built-in DEBUG level");
logger.notice("a custom level: a NOTICE message");
logger.info("the built-in INFO level");
logger.diag("a custom level: a DIAG message");
logger.warn("the built-in WARN level");
logger.error("the built-in ERROR level");
logger.fatal("the built-in FATAL level");
// ...
}
...
}
{code}
{anchor:GenerateExtended}
*Generating Extended Loggers*
Use the following command to generate a wrapper that adds methods to the
built-in ones:
{code}
java org.apache.logging.log4j.core.tools.Generate$ExtendedLogger
com.mycomp.ExtLogger DIAG=350 NOTICE=450 VERBOSE=550 > com/mycomp/ExtLogger.java
{code}
This will generate source code for a logger wrapper that has the convenience
methods for the built-in levels _as well as_ the specified custom levels. The
tool sends the generated source code to the console, so we redirected the
output to a file.
{anchor:GenerateCustom}
*Generating Custom Loggers*
Use the following command to generate a wrapper that hides the built-in levels
and has only custom levels:
{code}
java org.apache.logging.log4j.core.tools.Generate$CustomLogger
com.mycomp.MyLogger DEFCON1=350 DEFCON2=450 DEFCON3=550 >
com/mycomp/MyLogger.java
{code}
This will generate source code for a logger wrapper that has _only_ convenience
methods for the specified custom levels, _not for the built-in levels_. The
tool sends the generated source code to the console, so we redirected the
output to a file.
> Documentation for Custom Levels and Custom Loggers
> --------------------------------------------------
>
> Key: LOG4J2-710
> URL: https://issues.apache.org/jira/browse/LOG4J2-710
> Project: Log4j 2
> Issue Type: Bug
> Components: Documentation
> Affects Versions: 2.0
> Reporter: Remko Popma
> Assignee: Remko Popma
> Fix For: 2.0.1
>
>
> _Documentation preview. Feedback welcome._
> _Side-nav menu:_
> * [Custom Log Levels|#Custom]
> ** [Adding or Replacing Levels|#Customizing]
> ** [Generating Logger Wrappers|#wrapper]
> ** [Example Usage|#GeneratedWrapperUsage]
> ** [Tool Usage|#GenerateExtended]
> _Custom Loggers page:_
> {anchor:CustomLevels}
> *[#Custom] Log Levels*
> Log4J 2 supports custom log levels. It is possible to log messages at any
> self-defined custom level by passing this level to the {{Logger.log()}}
> method:
> {code}
> final Logger logger = LogManager.getLogger();
> final Level VERBOSE = Level.forName("VERBOSE", 550);
> logger.log(VERBOSE, "a verbose message");
> logger.log(VERBOSE, "another message");
> {code}
> When defining a custom log level, the {{intLevel}} parameter (550 in the
> example above) determines where the custom level exists in relation to the
> standard levels built in to Log4J 2. For reference, the table below shows the
> {{intLevel}} of the built-in log levels.
> ||Standard Level||intLevel||
> |OFF|0|
> |FATAL|100|
> |ERROR|200|
> |WARN|300|
> |INFO|400|
> |DEBUG|500|
> |TRACE|600|
> |ALL|Integer.MAX_VALUE|
> {anchor:Extending}
> *The Standard Logger Interface*
> The built-in levels have a set of convenience methods on the Logger interface
> that makes them easier to use. For example, the Logger interface has 14 debug
> methods that support the DEBUG level:
> {code}
> // convenience methods for the built-in DEBUG level
> debug(Marker, Message)
> debug(Marker, Message, Throwable)
> debug(Marker, Object)
> debug(Marker, Object, Throwable)
> debug(Marker, String)
> debug(Marker, String, Object...)
> debug(Marker, String, Throwable)
> debug(Message)
> debug(Message, Throwable)
> debug(Object)
> debug(Object, Throwable)
> debug(String)
> debug(String, Object...)
> debug(String, Throwable)
> {code}
> Similar method sets exist for the other built-in levels.
> {anchor:Customizing}
> *Adding or Replacing Levels*
> It would be nice to have the same ease of use with custom levels, so that
> after declaring a custom VERBOSE level, we would be able to use code like
> this:
> {code}
> logger.verbose("a verbose message"); // no need to pass the VERBOSE level as
> a parameter
> logger.verbose("another message");
> {code}
> In the above example, a convenience method was _added_ to the Logger
> interface, in addition to the existing {{trace()}}, {{debug()}}, {{info()}},
> ... methods for the built-in log levels.
> There is another use case, Domain Specific Language loggers, where we want to
> _replace_ the existing {{trace()}}, {{debug()}}, {{info()}}, ... methods with
> all-custom methods.
> For example, for medical devices we could have only {{critical()}},
> {{warning()}}, and {{advisory()}} methods. Another example could be a game
> that has only {{defcon1()}}, {{defcon2()}}, and {{defcon3()}} levels.
> If it were possible to hide existing log levels, users could customize the
> Logger interface to match their requirements. Some people may not want to
> have a {{FATAL}} or a {{TRACE}} level, for example. They would like to be
> able to create a custom Logger that only has {{debug()}}, {{info()}},
> {{warn()}} and {{error()}} methods.
> {anchor:wrapper}
> *Generating source code for a Logger [#wrapper]*
> Common Log4J usage is to get an instance of the {{Logger}} interface from the
> {{LogManager}} and call the methods on this interface. However, the custom
> log Levels are not known in advance, so Log4J cannot provide an interface
> with convenience methods for these custom log Levels.
> To solve this, Log4J ships with a tool that generates source code for a
> Logger wrapper. The generated wrapper class has convenience methods for each
> custom log level, making custom levels just as easy to use as the built-in
> levels.
> There are two flavors of wrappers: ones that _extend_ the {{Logger}} API
> (_adding_ methods to the built-in levels) and ones that _customize_ the
> {{Logger}} API (_replacing_ the built-in methods).
> When generating the source code for a wrapper class, you need to specify:
> * the fully qualified name of the class to generate
> * the list of custom levels to support and their {{intLevel}} relative
> strength
> * whether to extend {{Logger}} (and keep the existing built-in methods) or
> have only methods for the custom log levels
> You would then include the generated source code in the project where you
> want to use custom log levels.
> {anchor:GeneratedWrapperUsage}
> *Example Usage of a Generated Logger Wrapper*
> Here is an example of how one would use a generated logger wrapper for custom
> levels DIAG, NOTICE and VERBOSE:
> {code}
> // ExtLogger is a generated logger wrapper
> import com.mycompany.myproject.ExtLogger;
> public class MyService {
> // instead of Logger logger = LogManager.getLogger(MyService.class):
> private static final ExtLogger logger = ExtLogger.create(MyService.class);
>
> public void someMethod() {
> // ...
> logger.trace("the built-in TRACE level");
> logger.verbose("a custom level: a VERBOSE message");
> logger.debug("the built-in DEBUG level");
> logger.notice("a custom level: a NOTICE message");
> logger.info("the built-in INFO level");
> logger.diag("a custom level: a DIAG message");
> logger.warn("the built-in WARN level");
> logger.error("the built-in ERROR level");
> logger.fatal("the built-in FATAL level");
> // ...
> }
> ...
> }
> {code}
> {anchor:GenerateExtended}
> *Generating Extended Loggers*
> Use the following command to generate a wrapper that adds methods to the
> built-in ones:
> {code}
> java -cp log4j-core-2.0.jar
> org.apache.logging.log4j.core.tools.Generate$ExtendedLogger
> com.mycomp.ExtLogger DIAG=350 NOTICE=450 VERBOSE=550 >
> com/mycomp/ExtLogger.java
> {code}
> This will generate source code for a logger wrapper that has the convenience
> methods for the built-in levels _as well as_ the specified custom levels. The
> tool sends the generated source code to the console, so we redirected the
> output to a file.
> {anchor:GenerateCustom}
> *Generating Custom Loggers*
> Use the following command to generate a wrapper that hides the built-in
> levels and has only custom levels:
> {code}
> java -cp log4j-core-2.0.jar
> org.apache.logging.log4j.core.tools.Generate$CustomLogger com.mycomp.MyLogger
> DEFCON1=350 DEFCON2=450 DEFCON3=550 > com/mycomp/MyLogger.java
> {code}
> This will generate source code for a logger wrapper that has _only_
> convenience methods for the specified custom levels, _not for the built-in
> levels_. The tool sends the generated source code to the console, so we
> redirected the output to a file.
--
This message was sent by Atlassian JIRA
(v6.2#6252)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]