1 year ago
#73882
CHANist
Logging each JUnit test on different log file in multi-thread environment
I would like to create a log for each JUnit Test I have run, each having its own file.
Actually, I have done that yesterday, with the help of Logback's SiftingAppender.
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
public class CustomJUnitTestRule implements AfterEachCallback, BeforeEachCallback {
@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {
Class<?> testClass = extensionContext.getTestClass().get();
AnnotatedElement annotatedElement = extensionContext.getElement().get();
Method method = extensionContext.getTestMethod().get();
String methodName = method.getName();
DisplayName displayName = testClass.getAnnotation(DisplayName.class);
String topic = displayName.value();
boolean annotationPresent = annotatedElement.isAnnotationPresent(Order.class);
int order = -1;
if (annotationPresent) {
Order orderAnnotation = annotatedElement.getAnnotation(Order.class);
order = orderAnnotation.value();
}
String fileName = String.format("%s-%02d-%s", topic, order, methodName);
MDC.put("testId", fileName);
}
@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
MDC.remove("testId");
}
}
with a sample logback.xml
<configuration>
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<!-- in the absence of the class attribute, it is assumed that the
desired discriminator type is
ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
<discriminator>
<key>testId</key>
<defaultValue>unknown</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
<file>${testId}.log</file>
<append>false</append>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
</layout>
</appender>
</sift>
</appender>
<root level="DEBUG">
<appender-ref ref="SIFT" />
</root>
</configuration>
and a simple test
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@DisplayName("abc")
public class ABCTest {
@Test
@Order(1)
public void xxxTest() {
// ...
}
}
It is working as intended at the first sight.
However as it uses MDC to work in the background, which essentially is thread bounded, which makes some of my unit test, which creates multiple thread, not working as intended.
Can I create a logback's appender, which is not MDC bound, but globally, so that all logs in different threads (other than thread running jUnit test case), can be found in the log file as well?
java
multithreading
junit
sifting-appender
0 Answers
Your Answer