1. Overview
In this tutorial, we’ll learn how to set the log level when running tests for a Spring Boot application.
Although we can mostly ignore the logs while our tests are passing, choosing the right log level can be critical if we need to diagnose failed tests.
2. The Importance of the Log Level
Configuring the log level correctly can save us a lot of time.
For example, if tests are failing on a CI server, but passing on our development machine, we won’t be able to diagnose the failing tests unless we have enough log output. Conversely, if we log too much detail, it might be more difficult to find useful information.
To achieve the right amount of detail, we can fine-tune the logging levels of our application’s packages. If we find that a Java package is more critical for our tests, we can give it a lower level, like DEBUG. Similarly, to avoid having too much noise in our logs, we can configure a higher level, say INFO or ERROR, for packages that are less important.
Let’s explore various ways of setting the logging level.
3. Logging Settings in application.properties
If we want to modify the log level in our tests, there’s a property we can set in *src/test/resources/*application.properties:
logging.level.com.baeldung.testloglevel=DEBUG
This property will set the log level specifically for the com.baeldung.testloglevel package.
Similarly, we can change the logging level for all packages by setting the root log level:
logging.level.root=INFO
Now let’s try out our logging settings by adding a REST endpoint that writes some logs:
@RestController
public class TestLogLevelController {
private static final Logger LOG = LoggerFactory.getLogger(TestLogLevelController.class);
@Autowired
private OtherComponent otherComponent;
@GetMapping("/testLogLevel")
public String testLogLevel() {
LOG.trace("This is a TRACE log");
LOG.debug("This is a DEBUG log");
LOG.info("This is an INFO log");
LOG.error("This is an ERROR log");
otherComponent.processData();
return "Added some log output to console...";
}
}
As expected, if we call this endpoint in our tests*,* we’ll be able to see the DEBUG logs from TestLogLevelController:
2019-04-01 14:08:27.545 DEBUG 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is a DEBUG log
2019-04-01 14:08:27.545 INFO 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an INFO log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an ERROR log
2019-04-01 14:08:27.546 INFO 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an INFO log from another package
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an ERROR log from another package
Setting the log level like this is quite easy, and we should definitely do it this way if our tests are annotated with @SpringBootTest. However, if we don’t use that annotation, we’ll have to configure the log level in a different way.
3.1. Profile-based Logging Settings
Although putting the settings into src/test/application.properties would work in most situations, there might be cases where we would like to have different settings for one test or a group of tests.
In that case, we can add a Spring profile to our test by using the ActiveProfiles annotation:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class)
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
@ActiveProfiles("logging-test")
public class TestLogLevelWithProfileIntegrationTest {
// ...
}
Our logging settings will then be in a special application-logging-test.properties file within src/test/resources:
logging.level.com.baeldung.testloglevel=TRACE
logging.level.root=ERROR
If we call TestLogLevelController from our tests with the described settings, we’ll now see the TRACE logs from our controller, and there will be no more INFO logs from other packages:
2019-04-01 14:08:27.545 DEBUG 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is a DEBUG log
2019-04-01 14:08:27.545 INFO 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an INFO log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an ERROR log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an ERROR log from another package
4. Configuring Logback
If we use Logback, which is used by default in Spring Boot, we can set the log level in the logback-test.xml file within src/test/resources:
<configuration>
<include resource="/org/springframework/boot/logging/logback/base.xml"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="error">
<appender-ref ref="STDOUT"/>
</root>
<logger name="com.baeldung.testloglevel" level="debug"/>
</configuration>
The above example shows how to set the log level in our Logback configuration for tests. The root log level is set to INFO and the log level for our com.baeldung.testloglevel package is set to DEBUG.
Again, let’s check the output after applying the settings from above:
2019-04-01 14:08:27.545 DEBUG 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is a DEBUG log
2019-04-01 14:08:27.545 INFO 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an INFO log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an ERROR log
2019-04-01 14:08:27.546 INFO 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an INFO log from another package
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an ERROR log from another package
4.1. Profile-based Logback Configuration
Another way to set up a profile-specific configuration for our tests is to set the logging.config property in application.properties for our profile:
logging.config=classpath:logback-testloglevel.xml
Or, if we want to have a single Logback configuration on our classpath, we can use the springProfile element in logback.xml:
<configuration>
<include resource="/org/springframework/boot/logging/logback/base.xml"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="error">
<appender-ref ref="STDOUT"/>
</root>
<springProfile name="logback-test1">
<logger name="com.baeldung.testloglevel" level="info"/>
</springProfile>
<springProfile name="logback-test2">
<logger name="com.baeldung.testloglevel" level="trace"/>
</springProfile>
</configuration>
Now if we call the TestLogLevelController in our tests with the profile logback-test1, we’ll get the following output:
2019-04-01 14:08:27.545 INFO 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an INFO log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an ERROR log
2019-04-01 14:08:27.546 INFO 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an INFO log from another package
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an ERROR log from another package
Conversely, if we change the profile to logback-test2, the output will be:
2019-04-01 14:08:27.545 DEBUG 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is a DEBUG log
2019-04-01 14:08:27.545 INFO 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an INFO log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an ERROR log
2019-04-01 14:08:27.546 INFO 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an INFO log from another package
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an ERROR log from another package
5. A Log4J Alternative
Alternatively, if we use Log4J2, we can set the log level in the log4j2-spring.xml file within src/test/resources:
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.baeldung.testloglevel" level="debug" />
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
We can set the path of our Log4J configuration by setting the logging.config property in application.properties:
logging.config=classpath:log4j-testloglevel.xml
Finally, let’s check the output after applying the above settings:
2019-04-01 14:08:27.545 DEBUG 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is a DEBUG log
2019-04-01 14:08:27.545 INFO 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an INFO log
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.testloglevel.TestLogLevelController : This is an ERROR log
2019-04-01 14:08:27.546 INFO 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an INFO log from another package
2019-04-01 14:08:27.546 ERROR 56585 --- [nio-8080-exec-1] c.b.component.OtherComponent : This is an ERROR log from another package
6. Conclusion
In this article, we learned how to set the log level when testing a Spring Boot application. Then we explored a number of different ways of configuring it.
Setting the log level in Spring Boot’s application.properties is the easiest option, especially when we’re using the @SpringBootTest annotation.
As always, the source code for these examples is over on GitHub.