Log4j2 ThreadContext – Fish Tagging

Log4j2 ThreadContext allows us to tag the log statements with multiple unique tags to analyze logs while diagnose a problem in runtime – mostly in multithreaded applications where applications generate plenty of logging in short duration.

For example, we may want to scan all logs for a particular user transaction or complete session. This process is also called fish tagging (i.e. add some extra context information in every log statement). The fish tagging can help using the automated tools for logs such as Splunk.

Let’s see how we can use ThreadContext class for fish tagging in log4j2.

1. Add and Remove Context Information

1.1. ThreadContext.put()

To uniquely stamp each request, ThreadContext provide put(String key, String value) method which accept a key and it’s value. We can add as many tags as we need to capture the whole context information. Note that all methods of the ThreadContext class are static.

package com.howtodoinjava.log4j2.examples;

import java.util.UUID;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;

public class Log4j2HelloWorldExample 
{
	private static final Logger LOGGER = LogManager.getLogger(Log4j2HelloWorldExample.class.getName());
	
	public static void main(String[] args) 
	{
		//Add context information
		ThreadContext.put("id", UUID.randomUUID().toString());
		ThreadContext.put("ipAddress", "192.168.21.9");
		
		LOGGER.debug("Debug Message Logged !!");
		LOGGER.info("Info Message Logged !!");
		LOGGER.debug("Another Debug Message !!");
		
		//Clear the map
		ThreadContext.clearMap();
		
		LOGGER.debug("Thread Context Cleaned up !!");
		LOGGER.debug("Log message with no context information !!");
	}
}

1.2. ThreadContext.push()

Or We can use ThreadContext’s Stack implemeration with ThreadContext.push(String value) as below:

//Add context information
ThreadContext.push(UUID.randomUUID().toString());
ThreadContext.push("192.168.21.9");

LOGGER.debug("Debug Message Logged !!");
LOGGER.info("Info Message Logged !!");
LOGGER.debug("Another Debug Message !!");

//Clear the map
ThreadContext.clearStack();

LOGGER.debug("Thread Context Cleaned up !!");
LOGGER.debug("Log message with no context information !!");

1.3. ThreadContext.clearMap()

After the transaction is over or context information is no more required, you can empty the information using ThreadContext.clearMap() method.

ThreadContext’s Stack and Map are managed per thread and are based on ThreadLocal by default. By setting system property isThreadContextMapInheritable to true, contents of context map will be passed to child threads.

2. Modify Conversion Pattern

Now to print the above tags in log statements, we need to modify the conversion pattern in the log4j2 configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
	<Appenders>
		<Console name="console" target="SYSTEM_OUT">
			<PatternLayout
				pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%X{id}] [%X{ipAddress}] %c{1} - %msg%n" />
		</Console>
	</Appenders>
	<Loggers>
		<Root level="debug" additivity="false">
			<AppenderRef ref="console" />
		</Root>
	</Loggers>
</Configuration>
  • Use %X by itself to include the full contents of the Map.
  • Use %X{key} to include the specified key.
  • Use %x to include the full contents of the Stack.

Now when you run the above code – we will get the below output:

 
[DEBUG] 2016-06-21 13:09:56.485 [main] [7cdd4cf0-2c26-4b81-b374-1adce3781499] [192.168.21.9] Log4j2HelloWorldExample - Debug Message Logged !!
[INFO ] 2016-06-21 13:09:56.487 [main] [7cdd4cf0-2c26-4b81-b374-1adce3781499] [192.168.21.9] Log4j2HelloWorldExample - Info Message Logged !!
[DEBUG] 2016-06-21 13:09:56.487 [main] [7cdd4cf0-2c26-4b81-b374-1adce3781499] [192.168.21.9] Log4j2HelloWorldExample - Another Debug Message !!
[DEBUG] 2016-06-21 13:09:56.487 [main] [] [] Log4j2HelloWorldExample - Thread Context Cleaned up !!
[DEBUG] 2016-06-21 13:09:56.487 [main] [] [] Log4j2HelloWorldExample - Log message with no context information !!

As you can see the first three log statements have context information added to them – and the other two statements do not have such information.

Happy Learning !!

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode