Let's get started with a Microservice Architecture with Spring Cloud:
Different Log Level for File and Console Appender in Spring Boot
Last updated: October 2, 2025
1. Overview
When we build Spring Boot apps, we know good logging is key; it helps us observe, troubleshoot, and truly understand our application’s flow.
In this article, we’ll explore how we can achieve this separation of log levels for FILE and CONSOLE appenders using Logback, the default logging framework in Spring Boot.
2. Project Setup
Before we dive into the logging configuration itself, we need a working Spring Boot application to serve as our demonstration. Let’s walk through setting up our project.
2.1. Adding Dependency
Logback and SLF4J are Spring Boot’s default logging implementations. This holds true if we’re already using spring-boot-starter-web or any other Spring Boot starter that bundles spring-boot-starter-logging:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.2. Creating Controller
Next, we create a simple controller to generate some log messages for testing:
@RestController
public class LogController {
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@GetMapping("/log")
public String generateLogs() {
logger.trace("This is a TRACE message from controller.");
logger.debug("This is a DEBUG message from controller.");
logger.info("This is an INFO message from controller.");
logger.warn("This is a WARN message from controller.");
logger.error("This is an ERROR message from controller.");
return "Logs generated!";
}
}
Log levels follow a strict hierarchy: TRACE is the lowest, then DEBUG, INFO, WARN, ERROR, and FATAL. When we define a log level for an appender or a logger, we ensure only messages at that specific level and more severe ones are processed.
3. Creating a logback-spring.xml File
The core of our solution lies in the logback-spring.xml file. We just place this file in our src/main/resources directory, and Spring Boot automatically picks it up. This allows us to precisely define what we log, where those logs are stored, and with what level of detail.
3.1. Properties Tags
Let’s look into the property tags first:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS_HOME" value="./logs"/>
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<property name="FILE_NAME" value="my-spring-app"/>
<configuration>
These variables define common values like where our logs will go (LOGS_HOME), the format for console output (CONSOLE_LOG_PATTERN), the format for file output (FILE_LOG_PATTERN), and the base name for our log files (FILE_NAME). Using properties makes the configuration cleaner and easier to update.
3.2. Console Appender Tags
This section defines how logs are handled for our console:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
For our console output, we define an appender named “CONSOLE“. It tells Logback to use its built-in ConsoleAppender for sending output directly to our standard console. Within this appender, we use an <encoder> to convert our raw log messages into a readable format. The <Pattern> tag inside this encoder applies our predefined CONSOLE_LOG_PATTERN, which ensures a consistent and easy-to-read look for all our console logs.
Critically, we then introduce a filter: <filter class=”ch.qos.logback.classic.filter.ThresholdFilter”>. This is a crucial component for controlling our log levels; when our console’s ThresholdFilter is set to INFO, we display only log messages at the INFO level or higher-meaning INFO, WARN, ERROR, and FATAL messages.
3.3. File Appender
Let’s break down each part of our file appender:
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOGS_HOME}/${FILE_NAME}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${FILE_LOG_PATTERN}</Pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
For our file output, we define an appender named “FILE“, choosing ch.qos.logback.core.FileAppender as its class. This tells Logback we simply want an appender that writes all our logs to a single, continuously growing file. We specify the active log file’s exact path: <file>${LOGS_HOME}/${FILE_NAME}.log</file>. This resolves to ./logs/my-spring-app.log. Like with our console, we use an <encoder> here. It formats each log entry using our FILE_LOG_PATTERN for consistent readability.
Finally, we add a crucial <filter class=”ch.qos.logback.classic.filter.ThresholdFilter”>, which is specific to this file appender. We’ve set the threshold to DEBUG, meaning any log message at the DEBUG level or higher in severity (i.e. DEBUG, INFO, WARN, ERROR, FATAL) will be captured and written to our log files.
3.4. Root Logger
This section defines how our log messages are routed and processed within our application:
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
Our <root level=”DEBUG”> serves as the default, catch-all logger for our entire application; any log message generated by our Spring Boot application will eventually pass through this root logger. We’ve set its primary level to DEBUG, meaning it considers messages at DEBUG level or higher. From here, we’re telling this root logger to send all the log messages it processes to our CONSOLE and FILE appender.
It’s important to remember that our CONSOLE appender itself has its own filter set to INFO, so it will ultimately only display the logs that meet its INFO level or higher criteria. Similarly, we also send the root logger’s processed messages to our FILE appender, which we’ve set to DEBUG.
Now we can run our application and hit the localhost:8080/log endpoint to see the logs generated.
4. Conclusion
In this tutorial, we demonstrated how to configure distinct logging levels for the FILE and CONSOLE appenders within a Spring Boot application by employing Logback’s ThresholdFilter. This provides us with the flexibility to tailor our logging output to specific needs – keeping the console clean and concise for daily monitoring while retaining detailed DEBUG level information in log files for comprehensive analysis.
The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.















