I think this code explains well enough what I'm trying to do
package us.benanderson;
public class MyClass {
private static final Logger LOG = LogManager.getLogger(MyClass.class);
...
// within a method
LOG.debug("only output to appFile");
LOG.error("output to both appFile and errorFile");
This is what I'd guess should be my config
<Loggers>
<Logger name="us.benanderson" level="debug" additivity="true">
<AppenderRef ref="appFile" />
</Logger>
<Root level="error">
<AppenderRef ref="errorFile" />
</Root>
</Loggers>
However, I'm finding that when additivity="true", debug messages are also output to errorFile. When additivity="false" nothing is output to errorFile. Is there any way to do what I'm trying to do?
Additivity is set to true by default, that is children inherit the appenders of their ancestors by default. If this variable is set to false then the appenders found in the ancestors of this logger are not used.
Configuration: the root element of a log4j2 configuration file; the status attribute represents the level at which internal log4j events should be logged. Appenders: this element contains a list of appenders; in our example, an appender corresponding to the System console is defined.
This concept is known as Logger Hierarchy. Logger Hierarchy is made up of set of LoggerConfig objects with a parent-child relationship. The topmost element in every Logger Hierarchy is the Root Logger. If Log4j2 doesn't find the configuration file, only Root Logger will be used for logging with logging level as ERROR.
I think the simplest way to achieve what you want is to put a level directly on the appender-ref. This eliminates the need to have a named logger in your config, simplifying the configuration a little.
Named loggers are still useful if you want to redirect log events for a certain package to a separate appender.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="appFile" fileName="logs/appFile.log" append="true">
<PatternLayout pattern="%-5p %d{ABSOLUTE} [%t] %c - %m%n" />
</File>
<File name="errorFile" fileName="logs/errorFile.log" append="true">
<PatternLayout pattern="%-5p %d{ABSOLUTE} [%t] %c - %m%n" />
</File>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="appFile" level="debug" />
<AppenderRef ref="errorFile" level="error" />
</Root>
</Loggers>
</Configuration>
Threshold filters and filter combinations can be especially useful if you want to do more unusual filtering. For example, if you want to send only INFO and WARN level events to a certain appender, excluding TRACE/DEBUG, and also excluding ERROR and FATAL level events(!), you could do this:
<Console name="only-info-warn">
<PatternLayout pattern="%-5p %c %message %n" />
<Filters>
<!-- First deny error and fatal messages -->
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL"/>
<!-- Then accept info, warn, error, fatal and deny debug/trace -->
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</Console>
Use a filter.
Here's a configuration that outputs everything to C:/Logs/Log.log
, and additionally outputs debug only to C:/Logs/Debug.log
:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="general-out" class="org.apache.log4j.FileAppender">
<param name="File" value="C:/Logs/Log.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1} : %m%n"/>
</layout>
</appender>
<appender name="debug-out" class="org.apache.log4j.FileAppender">
<param name="File" value="C:/Logs/Debug.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1} : %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="debug"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>
<root>
<appender-ref ref="debug-out" />
<appender-ref ref="general-out" />
</root>
</log4j:configuration>
The key part here is this:
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="debug"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
This allows things logged with debug
, and then denies anything else.
Source: http://wiki.apache.org/logging-log4j/LogByLevel
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With