I am developing an automation framework for which I am using slf4j (version 1.7.21).
I want to be able to write every test class's logs into its own file. I am new to log4j2 and this is what I have tried so far.
I read that to set the file name dynamically, we should set a system property in a static block in my class and then use this property to set the file name in my log4j2-test.xml.
This is how my class looks like :
public class TestClass {
Logger log;
static {
System.setProperty("logFilename", "TestClass");
log = LoggerFactory.getLogger(TestClass.class);
}
@Test
public static void testLogger() {
log.info("Testing logger");
}
}
My log4j2.xml looks like :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" name="Regressions">
<Properties>
<Property name="logs.dir">logs</Property>
<Property name="pattern">%d %-5p - [%logger] ~ %m (%c{1.}:%L)%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${pattern}"/>
</Console>
<File name="All" fileName="${sys:logs.dir}/${sys:logFilename}.log" append="false">
<PatternLayout pattern="${pattern}"/>
</File>
<File name="Debug" fileName="${sys:logs.dir}/${sys:logFilename}-DEBUG.log" append="false">
<PatternLayout pattern="${pattern}"/>
</File>
<File name="Error" fileName="${sys:logs.dir}/${sys:logFilename}-ERROR.log" append="false">
<PatternLayout pattern="${pattern}"/>
</File>
</Appenders>
<Loggers>
<Logger name="org.apache.http" level="DEBUG" additivity="false">
<AppenderRef ref="Debug"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="All"/>
</Root>
</Loggers>
This works well when I have the static block in each test class.
Now, I want to do this in a base test class. Here is where the issue lies. I tried the following things :
1) Get the class name in the base class :
public class BaseClass {
String testClass = this.getClass().getSimpleName();
}
But as it is a static block, I can't call this.
2) Another way is to have a separate method in the base class to create the logger :
public class TestClass {
Logger log = BaseClass.getLogger(TestClass.class);
}
public class BaseClass {
public static Logger getLogger (Class className) {
System.setProperty("logFilename", className.getSimpleName());
return LoggerFactory.getLogger(className);
}
}
which I find ugly. Is there a better way to do it?