1. Overview
In this tutorial, we’ll show 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 there is a 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. On the other side, 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 is 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 it 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-testloglevel.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 will 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, yet another, say if we want to have a single Logback configuration on our classpath, is to 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 will 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
On the other hand, 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’ve learned how to set the log level when testing a Spring Boot application. We explored a number of different ways of configuring it.
Setting the log level in Spring Boot’s application.properties showed itself as the easiest, especially when we are using the @SpringBootTest annotation.
As always, the source code for these examples is over on GitHub.