In this tutorial, we will show you how to use Logback Mapped Diagnostic Context (MDC) and SiftingAppender to create a separate log file for each thread.

P.S Tested with Logback 1.1.2, should work in earlier version.

Note

More info, refer to this Logback MDC documentation

1. logback.xml example

logback.xml file to show you how to declare and configure SiftingAppender and MDC.

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

	<property name="USER_HOME" value="C:\\logs\\analyzer" />

	<appender name="FILE-THREAD" class="ch.qos.logback.classic.sift.SiftingAppender">

		<!-- This is MDC value -->
		<!-- We will assign a value to 'logFileName' via Java code -->
		<discriminator>
			<key>logFileName</key>
			<defaultValue>head0</defaultValue>
		</discriminator>

		<sift>

		  <!-- A standard RollingFileAppender, the log file is based on 'logFileName' at runtime  -->
		  <appender name="FILE-${logFileName}"
			class="ch.qos.logback.core.rolling.RollingFileAppender">
			<file>${USER_HOME}/${logFileName}.log</file>

			<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
				<Pattern>
					%d{yyyy-MM-dd HH:mm:ss} %mdc [%thread] %level %logger{35} - %msg%n
				</Pattern>
			</encoder>

			<rollingPolicy
				class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
				<FileNamePattern>${USER_HOME}/${logFileName}.%i.log.zip
				</FileNamePattern>
				<MinIndex>1</MinIndex>
				<MaxIndex>10</MaxIndex>
			</rollingPolicy>

			<triggeringPolicy
				class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
				<MaxFileSize>10MB</MaxFileSize>
			</triggeringPolicy>

		  </appender>

		</sift>
	</appender>

	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<layout class="ch.qos.logback.classic.PatternLayout">
			<Pattern>
				%-5level %logger{36} - %msg%n
			</Pattern>
		</layout>
	</appender>

	<logger name="com.favtuts.analyzer.core" level="debug"
		additivity="false">
		<appender-ref ref="FILE-THREAD" />
		<appender-ref ref="STDOUT" />
	</logger>

	<root level="error">
		<appender-ref ref="STDOUT" />
	</root>

</configuration>

2. Java Threads Example

A simple thread example, declared the ‘logFileName’ value via MDC.put

Head.java

package com.favtuts.analyzer.core;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class Head implements Runnable {

	static Logger logger = LoggerFactory.getLogger(Head.class);

	private String name;
	
	@Override
	public void run() {

		MDC.put('logFileName', getName());

		logger.debug("hello");

		//remember remove this
		MDC.remove('logFileName');

	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

Start 10 threads

	int count = 1;
	while(count<=10){
		Head head = new Head();
		head.setName("head-" + count);
		threadPools.execute(head);
		count++;
	}

Output : 10 separate log files for 10 threads.

Note

With this MDC feature, you can even log output to a separate log file for each login user, each URI request, each remote host and etc.

References

  1. Logback MDC documentation

Leave a Reply

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