Log4j Levels Example – Order, Priority, Custom Filters

Filed Under: Java

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 Levels

Log4j provides many logging levels. Below is the complete list.

  1. TRACE: The TRACE Level designates finer-grained informational events than the DEBUG.
  2. DEBUG: The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
  3. INFO: The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
  4. WARN: The WARN level designates potentially harmful situations.
  5. ERROR: The ERROR level designates error events that might still allow the application to continue running.
  6. FATAL: The FATAL level designates very severe error events that will presumably lead the application to abort.
  7. ALL: The ALL has the lowest possible rank and is intended to turn on all logging.
  8. OFF: The OFF has the highest possible rank and is intended to turn off logging.

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.

Log4j Level Order/Priority

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.

Log4j Filters

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="http://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:

Comments

  1. Guilherme says:

    Thanks for explanation. It was helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages