Logging Configuration
Spring Boot ships with a fully configured logging setup out of the box: SLF4J as the API and Logback as the implementation. You get sensible console output the moment you start an app, and you can tune levels, patterns, and file output entirely from application.yml — only dropping down to logback-spring.xml when you need full control.
Default logging
Every Spring Boot starter pulls in spring-boot-starter-logging transitively, so SLF4J and Logback are already on the classpath. Write logs against the SLF4J API — see SLF4J Logging for the logging facade itself.
@Service
public class OrderService {
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
public void place(Long id) {
log.info("Placing order {}", id);
log.debug("Order details loaded for {}", id);
}
}
Output:
2026-06-13T10:15:42.318 INFO 12044 --- [ main] c.d.shop.OrderService : Placing order 42
By default only INFO and above reach the console; debug is suppressed until you raise the level.
Setting log levels
Control verbosity per package or class with logging.level.<logger>. The value is the minimum level that gets emitted.
logging:
level:
root: INFO # default for everything
com.devcraftly.shop: DEBUG # your application packages
org.springframework.web: INFO
org.hibernate.SQL: DEBUG # log generated SQL
org.hibernate.orm.jdbc.bind: TRACE # log bound parameters
Levels, from most to least verbose: TRACE, DEBUG, INFO, WARN, ERROR, OFF. You can also flip broad switches with the convenience flags:
java -jar app.jar --debug # DEBUG for a curated set of core loggers
java -jar app.jar --trace # TRACE for the same set
Tip: Set levels per environment using profiles —
DEBUGinapplication-dev.yml,WARNinapplication-prod.yml— rather than editing one shared value.
Console and file patterns
Customize the layout with pattern properties. Logback pattern conversions like %d, %-5level, %logger, and %msg control each field.
logging:
pattern:
console: "%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n"
Spring Boot also exposes logging.pattern.dateformat and a logging.pattern.level placeholder, and enables ANSI colors automatically on capable terminals.
Logging to a file
Console-only is the default. Enable a log file with either logging.file.name (a specific path) or logging.file.path (a directory, file named spring.log).
logging:
file:
name: logs/shop.log # specific file
logback:
rollingpolicy:
max-file-size: 10MB
max-history: 7 # keep 7 days of rolled files
total-size-cap: 1GB
The default rolling policy rotates by size and date, archiving old files as shop.log.2026-06-12.0.gz.
| Property | Effect |
|---|---|
logging.file.name | Write to this exact file |
logging.file.path | Write spring.log into this directory |
logging.logback.rollingpolicy.max-file-size | Roll over at this size |
logging.logback.rollingpolicy.max-history | Days of archives to keep |
logging.logback.rollingpolicy.total-size-cap | Total archive size limit |
Note:
logging.file.nameandlogging.file.pathare mutually exclusive — set one, not both.
Full control with logback-spring.xml
When property-based config is not enough (custom appenders, async logging, conditional blocks), add a logback-spring.xml to src/main/resources. Prefer the -spring variant over plain logback.xml so Spring’s extensions — like <springProfile> and <springProperty> — are available.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!-- Read a Spring property into the Logback config -->
<springProperty name="appName" source="app.name" defaultValue="app"/>
<!-- Profile-specific configuration -->
<springProfile name="prod">
<root level="WARN">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="dev | test">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
</configuration>
Including Spring Boot’s defaults.xml keeps the familiar formatting and color conventions while you layer your own appenders on top.
Structured JSON logging
Spring Boot 3.4+ can emit structured logs (ECS, Logstash, or GELF) with no XML — ideal for log aggregators.
logging:
structured:
format:
console: ecs # Elastic Common Schema as JSON to the console
Switching to Log4j2
To replace Logback with Log4j2, exclude the default logging starter and add the Log4j2 starter. SLF4J still routes through it, so your logging code does not change.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Then provide a log4j2-spring.xml for advanced configuration. The logging.level.* properties continue to work as before.
Warning: You must exclude
spring-boot-starter-loggingfirst. Leaving both Logback and Log4j2 on the classpath causes binding conflicts and unpredictable logging behavior.
Best Practices
- Keep the default Logback setup unless you have a concrete reason to change it.
- Tune levels per environment with profiles, not by editing a shared value.
- Use
logging.file.nameplus a rolling policy in production; cap total archive size. - Reach for
logback-spring.xmlonly when properties cannot express what you need; prefer the-springvariant. - Consider structured JSON logging when shipping logs to an aggregator.
- When switching to Log4j2, always exclude the default logging starter to avoid conflicts.