skip to content

Why use logback-spring.xml instead of logback.xml, and what do <springProfile> and <springProperty> do?

level: middleimportance: must knowfreq 65%

answer

  1. -spring suffix = Spring loads it, sees profiles
  2. plain logback.xml parsed too early
  3. springProfile name = expression (| and !)
  4. springProperty source->name, scope=context, defaultValue
  5. both files present -> logback.xml wins

basics

~10 s

logback-spring.xml is loaded by Spring Boot (not raw Logback), so it supports Spring's extensions: <springProfile> includes config only for certain active profiles, and <springProperty> pulls values from Spring's Environment (application.yml) into the Logback config.

solid answer

~40 s

Plain logback.xml is read directly by Logback very early, before the Spring ApplicationContext exists, so it can't see profiles or Spring properties. Naming the file logback-spring.xml tells Spring Boot to initialize logging through its own LoggingSystem, which registers two custom Logback tags. <springProfile name="prod"> conditionally includes a block only when that profile is active (supports expressions like "prod | staging" and "!dev"). <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="app"/> binds a value from the Spring Environment into a Logback property you can reference as ${appName}. This lets one config file adapt appenders, levels, and patterns per environment and reuse application.yml values instead of duplicating them.

code

java · 22 lines
java
// src/main/resources/logback-spring.xml
// <configuration>
//     <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
//
//     <!-- Bind a value from application.yml into a Logback variable -->
//     <springProperty scope="context" name="appName"
//                     source="spring.application.name" defaultValue="katajob"/>
//
//     <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
//         <encoder>
//             <pattern>%d %-5level [${appName}] %logger{36} - %msg%n</pattern>
//         </encoder>
//     </appender>
//
//     <!-- Different levels per environment -->
//     <springProfile name="dev | test">
//         <root level="DEBUG"><appender-ref ref="CONSOLE"/></root>
//     </springProfile>
//     <springProfile name="prod">
//         <root level="INFO"><appender-ref ref="CONSOLE"/></root>
//     </springProfile>
// </configuration>

go deeper

for a junior

Know that -spring lets the config see Spring profiles and properties.

for a middle

Explain the load-order reason (raw Logback runs before the context) and both tags' attributes.

for a senior

Discuss precedence when both files exist and the limits of what the environment exposes at logging-init time.

for a principal

Reason about environment-driven logging as config-as-code, single-source-of-truth with application.yml, and startup ordering constraints.

## The naming rule and why it matters Logback natively looks for `logback.xml` (or `logback-test.xml`) on the classpath and parses it **immediately** at startup. That happens *before* Spring Boot has created the `ApplicationContext` or resolved the active profiles — so a plain `logback.xml` has no access to Spring's `Environment`, profiles, or `application.yml` values. Spring Boot solves this with a naming convention: if you name the file **`logback-spring.xml`**, Logback ignores it (wrong name), and Spring Boot's `LogbackLoggingSystem` loads it *itself* after bootstrapping the environment. During that load Spring registers two extension tags via its `SpringBootJoranConfigurator`: ### `<springProfile>` Conditionally includes the enclosed configuration based on active Spring profiles. ```xml <springProfile name="prod"> <root level="WARN"><appender-ref ref="FILE"/></root> </springProfile> <springProfile name="dev | test"> <root level="DEBUG"><appender-ref ref="CONSOLE"/></root> </springProfile> <springProfile name="!prod"> <!-- everything except prod --> </springProfile> ``` The `name` attribute accepts a profile expression: a single name, an OR list with `|`, and negation with `!`. It can wrap almost any element (appenders, `<root>`, `<logger>`, `<property>`). ### `<springProperty>` Pulls a value from the Spring `Environment` into a Logback variable. ```xml <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="unknown"/> <property name="LOG_DIR" value="/var/log/${appName}"/> ``` - `source` is the property key as it appears in `application.yml` / environment (e.g., `spring.application.name`). - `name` is the Logback variable you then reference as `${appName}`. - `scope="context"` makes it available to the whole Logback context (recommended); `defaultValue` guards against the property being absent. This avoids hard-coding — you keep the single source of truth in `application.yml` and reference it from logging config. ## Precedence and coexistence - If **both** `logback.xml` and `logback-spring.xml` exist, `logback.xml` wins because Logback loads it first; Spring's file is then skipped. Keep only the `-spring` variant. - The same convention exists for Log4j2 (`log4j2-spring.xml`) and even properties/YAML logging config. ## Common gotchas - Putting `<springProfile>` in `logback.xml` (without `-spring`) silently does nothing — the tag is unknown to raw Logback and Logback will error or ignore it. - `source` uses the *canonical* property name (`spring.application.name`), not a relaxed/uppercased form. - Logging initializes early; some later-bound properties (e.g., ones set by a `@Configuration` bean) are not available to `<springProperty>` because the environment, not the full context, is what's ready. - Very early log output (before Spring's logging system re-initializes) uses default config; you may see a brief default-pattern preamble.

  • What happens if you put <springProfile> in a file named logback.xml instead of logback-spring.xml?
    Logback loads logback.xml directly and doesn't understand the Spring extension tag, so the profile logic won't apply (Logback treats it as an unknown element). You must use the -spring name so Spring Boot loads and interprets it.
  • Can <springProfile> use expressions, and what syntax?
    Yes: a single profile name, OR combinations with | (e.g., "dev | test"), and negation with ! (e.g., "!prod"). These are standard Spring profile expressions.

saying these in an interview costs you the question

  • Thinking springProfile/springProperty work inside a plain logback.xml
  • Believing logback-spring.xml is a Logback feature rather than a Spring Boot one
  • Assuming logback-spring.xml wins when logback.xml is also present
  • Confusing springProperty 'source' (the yml key) with 'name' (the Logback variable)

context