Skip to content
Spring Boot sb config 4 min read

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 profilesDEBUG in application-dev.yml, WARN in application-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.

PropertyEffect
logging.file.nameWrite to this exact file
logging.file.pathWrite spring.log into this directory
logging.logback.rollingpolicy.max-file-sizeRoll over at this size
logging.logback.rollingpolicy.max-historyDays of archives to keep
logging.logback.rollingpolicy.total-size-capTotal archive size limit

Note: logging.file.name and logging.file.path are 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-logging first. 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.name plus a rolling policy in production; cap total archive size.
  • Reach for logback-spring.xml only when properties cannot express what you need; prefer the -spring variant.
  • Consider structured JSON logging when shipping logs to an aggregator.
  • When switching to Log4j2, always exclude the default logging starter to avoid conflicts.
Last updated June 13, 2026
Was this helpful?