How do you configure logging in Spring Boot (Logback, log levels per package, structured/JSON logging)?

8 minintermediatelogginglogbackstructured-logging

Quick Answer

Spring Boot uses Logback as its default logging implementation (via the common SLF4J facade), configurable through simple application.yml/properties keys for basic needs (logging.level.<package>=DEBUG) or a full logback-spring.xml for advanced configuration (custom appenders, rolling file policies, conditional configuration based on active Spring profiles). For log aggregation systems, structured/JSON logging (via a Logback encoder like logstash-logback-encoder, or Spring Boot 3.4+'s built-in structured logging support) outputs each log line as a parseable JSON object instead of a plain text line, making fields like log level, logger name, and custom key-value context directly queryable rather than requiring text parsing.

Detailed Answer

Spring Boot uses SLF4J as the logging facade (the API application code actually calls) with Logback as the default underlying implementation — giving both a simple, quick-configuration path and a full-power path for advanced needs.

Simple configuration via application.yml — sufficient for most day-to-day needs:

logging:
  level:
    root: INFO
    com.example.myapp: DEBUG          # more verbose for your own code
    org.springframework.web: WARN     # quieter for a noisy framework package
  file:
    name: /var/log/myapp/app.log

Full Logback configuration (logback-spring.xml, the -spring suffix enabling Spring-specific extensions like profile-conditional sections) for anything beyond basic level tuning — custom appenders, rolling file policies, multiple output destinations:

<configuration>
    <springProfile name="prod">
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>app.%d{yyyy-MM-dd}.log</fileNamePattern>
                <maxHistory>30</maxHistory>
            </rollingPolicy>
        </appender>
    </springProfile>
</configuration>

Structured/JSON logging matters significantly once logs are shipped to a centralized aggregation system (ELK/OpenSearch, Splunk, a cloud logging service) — a plain text log line requires the aggregator to parse an often-fragile, ad-hoc text format to extract fields, whereas emitting each log entry as a JSON object makes every field (timestamp, level, logger, message, and any custom key-value context) directly and reliably queryable:

{"timestamp":"2026-07-04T10:15:30Z","level":"INFO","logger":"OrderService","message":"Order placed","orderId":"12345","customerId":"cust-1"}

This can be achieved via a dedicated Logback encoder library (e.g., logstash-logback-encoder), or — since Spring Boot 3.4 — via Spring Boot's own built-in structured logging support, configurable with a simple property:

logging.structured.format.console=ecs

supporting common structured formats (Elastic Common Schema, Logstash's format, GELF) without needing an extra third-party encoder dependency.

Adding contextual key-value fields to individual log statements (rather than just the message text) via SLF4J's fluent API or MDC (Mapped Diagnostic Context) makes those fields available as their own structured, filterable attributes in the aggregation system — e.g., attaching a orderId or the current distributed-tracing traceId to every log line emitted while handling a specific request, which is invaluable for correlating logs with the specific request/trace they belong to (see the distributed-tracing question) during a production investigation.