If you have used log4j, you will notice that there are many methods to log messages. For example:
logger.trace("My Log message");
logger.debug("My Log message");
logger.info("My Log message");
Actually they corresponds to log4j levels.
Log4j provides many logging levels. Below is the complete list.
ALL and OFF are special logging levels and should be used in extreme situations. I have never used these personally at any point of time.
Trace is of the lowest priority and Fatal is having highest priority. Below is the log4j logging level order. Trace < Debug < Info < Warn < Error < Fatal. When we define logger level, anything having higher priority logs are also getting printed. For example, if logger level is INFO then debug logs will not be printed but Warn logs will be printed because of higher priority.
Let’s say we want to log only INFO and FATAL events but not WARN and ERROR events. In these scenarios, we can take help of log4j Filters. We can extend org.apache.log4j.spi.Filter
class and implements it’s decide(LoggingEvent event)
method to provide custom filtering capabilities.
package com.journaldev.log4j.filters;
import org.apache.log4j.Level;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
public class MyLog4jFilter extends Filter {
/**
* My custom filter to only log INFO and FATAL events
*/
@Override
public int decide(LoggingEvent event) {
if(event.getLevel() == Level.INFO || event.getLevel() == Level.FATAL)
return ACCEPT;
else return DENY;
}
}
Above custom Filter will log only INFO and FATAL events, below is the XML log4j configuration for this.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/"
debug="false">
<!-- console appender -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
</layout>
<filter class="com.journaldev.log4j.filters.MyLog4jFilter" />
</appender>
<logger name="com.journaldev.log4j" additivity="false">
<level value="TRACE" />
<appender-ref ref="console" />
</logger>
<root>
<priority value="DEBUG" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Notice the usage of Filter class in the console appender. Below is a simple class doing basic logging.
package com.journaldev.log4j.main;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
public class Log4jExample {
static {
init();
}
private final static Logger logger = Logger.getLogger(Log4jExample.class);
public static void main(String[] args) {
logger.trace("My Trace Log");
logger.debug("My Debug Log");
logger.info("My Info Log");
logger.warn("My Warn Log");
logger.error("My error log");
logger.fatal("My fatal log");
}
/**
* method to init log4j configurations
*/
private static void init() {
DOMConfigurator.configure("log4j.xml");
}
}
On running this program, it generates below logs into console.
INFO Log4jExample - My Info Log
FATAL Log4jExample - My fatal log
We can do even more complex filtering by creating our own custom filter classes. Notice that for this particular case, we can use org.apache.log4j.varia.LevelMatchFilter
and org.apache.log4j.varia.DenyAllFilter
classes as shown in below appender.
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="INFO" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="FATAL" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>
We also have org.apache.log4j.varia.LevelRangeFilter
class that can be used to reject messages with priorities outside a certain range. That’s all for a quick understanding of log4j levels and filters. References:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Very helpful. Thanks for sharing!
- Alberto
Thanks for explanation. It was helpful!
- Guilherme