In my log4j2 configuration, I have an AsyncRoot set to INFO because I want to log this level and upper in a file.
But I would like also to log the ERROR level into a specific file AND in the appender configured in the AsyncRoot
Here is my configuration:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<Appenders>
<RollingFile name="file" fileName="${LOG_PATH}/${APP_NAME}.log" filePattern="${LOG_PATH}/${APP_NAME}-${FILE_PATTERN_TRAILER}.log">
<PatternLayout pattern="${PATTERN_LAYOUT}"/>
<Policies>
<SizeBasedTriggeringPolicy size="50 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
<RollingFile name="errorFile" fileName="${LOG_PATH}/${APP_NAME}-errors.log" filePattern="${LOG_PATH}/${APP_NAME}-errors-${FILE_PATTERN_TRAILER}.log">
<PatternLayout pattern="${PATTERN_LAYOUT}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<AsyncRoot level="INFO">
<AppenderRef ref="file"/>
</AsyncRoot>
<AsyncLogger level="ERROR">
<AppenderRef ref="errorFile"/>
</AsyncLogger>
</Loggers>
</Configuration>
Here is the logging behaviour I'd like to achieve (no matter the package) :
Thank you
You can achieve what you want by setting the root logger's level to info since you don't want any trace or debug events to reach your appenders. Set the level on the error file appender to error so that only events of that level or more specific are written to the file.
Here's a simple example that you can adapt to your needs:
Example Java class to generate some log events:
package example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
log.debug("This is some debug!");
log.info("Here's some info!");
log.error("Some error happened!");
}
}
log4j2.xml config file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="ErrorFile"
fileName="logs/error.log"
immediateFlush="false"
append="false">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<File name="InfoFile"
fileName="logs/info.log"
immediateFlush="false"
append="false">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="InfoFile"/>
<AppenderRef ref="ErrorFile"
level="error"/>
</Root>
</Loggers>
</Configuration>
This generates 2 files: error.log and info.log
error.log contains only the ERROR:
2019-12-04 10:05:34.672 [main] ERROR example.SomeClass - Some error happened!
info.log contains both the ERROR and the INFO events:
2019-12-04 10:05:34.670 [main] INFO example.SomeClass - Here's some info!
2019-12-04 10:05:34.672 [main] ERROR example.SomeClass - Some error happened!
To do similar thing in the properties config file you can set config file as below
status = error
name = PropertiesConfig
filters = threshold
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appenders = rolling, rollingErrorFile
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = logs.log
appender.rolling.filePattern = logs.log.%i
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d{ISO8601} %-5p %30.30c{2} : %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 20 MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 20
appender.rollingErrorFile.type = RollingFile
appender.rollingErrorFile.name = RollingErrorFile
appender.rollingErrorFile.fileName = logsErrors.log
appender.rollingErrorFile.filePattern = logsErrors.log.%i
appender.rollingErrorFile.layout.type = PatternLayout
appender.rollingErrorFile.layout.pattern = %d{ISO8601} %-5p %30.30c{2} : %m%n
appender.rollingErrorFile.policies.type = Policies
appender.rollingErrorFile.policies.size.type = SizeBasedTriggeringPolicy
appender.rollingErrorFile.policies.size.size = 20 MB
appender.rollingErrorFile.strategy.type = DefaultRolloverStrategy
appender.rollingErrorFile.strategy.max = 20
loggers = rolling
#Make sure to change the package structure as per your application
logger.rolling.name = example
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
logger.rolling.appenderRef.rollingErrorFile.ref = RollingErrorFile
logger.rolling.appenderRef.rollingErrorFile.level = error
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