What are the Spring Boot log levels, how are they ordered, and how do you set the threshold for a specific logger?
answer
- TRACE<DEBUG<INFO<WARN<ERROR (+OFF)
- level = floor: that level and more severe
- logging.level.<logger>=LEVEL
- root default = INFO
- most specific prefix wins
basics
~10 sLevels from least to most severe: TRACE, DEBUG, INFO, WARN, ERROR. Setting a logger to a level shows that level and everything more severe. Configure with logging.level.<logger>, e.g. logging.level.org.springframework.web=DEBUG. Default root level is INFO.
solid answer
~40 sSpring Boot uses the severity order TRACE < DEBUG < INFO < WARN < ERROR (plus OFF to disable). A logger's configured level is a threshold: it emits messages at that level and every more-severe level, and suppresses less-severe ones. So INFO shows INFO/WARN/ERROR but hides DEBUG/TRACE. You set a level per logger name (usually a package) via the property logging.level.<logger-name>=LEVEL, e.g. logging.level.com.example.orders=DEBUG. The special name root sets the fallback for everything: logging.level.root=WARN. Boot's default root level is INFO. Level names are case-insensitive. Logger names are hierarchical by dotted path, so the most specific configured prefix wins. This works the same whether the backend is Logback (default) or Log4j2.
code
java · 19 linesimport org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
// Logger name = fully-qualified class name -> com.example.orders.OrderService
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
public void place(String id) {
log.trace("entering place() id={}", id); // hidden unless threshold <= TRACE
log.debug("validating order {}", id); // hidden unless threshold <= DEBUG
log.info("order {} placed", id); // shown at default INFO
log.warn("inventory low for {}", id); // shown
log.error("payment failed for {}", id); // shown
}
}
// With logging.level.com.example.orders=DEBUG the trace() line stays hidden
// but debug()/info()/warn()/error() are all emitted.go deeper
Must know the five levels, their order, that a level shows itself plus more-severe, and the logging.level.<logger> property.
Should explain root fallback, hierarchical name resolution, and OFF.
Should distinguish threshold vs statement level, and warn about noisy broad packages in prod.
Frames level policy as an operational concern: defaults per environment, avoiding TRACE/DEBUG on hot paths, and cost of logging.
## What a log level is A **log level** is a severity label attached to each log statement in code. Using SLF4J (the logging facade Spring Boot uses by default, typically via Logback as the implementation), you write statements like `logger.debug(...)`, `logger.info(...)`, `logger.warn(...)`. The level of the *statement* is fixed in code; what you configure at runtime is the **threshold** for each logger. ## The severity order (least to most severe) `TRACE` < `DEBUG` < `INFO` < `WARN` < `ERROR`. There is also the pseudo-level `OFF` which disables all output for that logger. (Some backends such as Log4j2 also define `FATAL`; Spring Boot's core set is the five above plus `OFF`.) ## Threshold semantics A logger's configured level acts as a **floor**. It emits every message at that level or **more severe**, and drops anything **less severe**: - `INFO` -> shows INFO, WARN, ERROR; hides DEBUG, TRACE. - `DEBUG` -> shows DEBUG, INFO, WARN, ERROR; hides TRACE. - `WARN` -> shows WARN, ERROR only. - `OFF` -> shows nothing. ## Setting a level In `application.properties`/`application.yml`, use the property namespace `logging.level.<logger-name>`: ```properties logging.level.root=INFO logging.level.org.springframework.web=DEBUG logging.level.com.example.orders=TRACE logging.level.org.hibernate=WARN ``` The `<logger-name>` is almost always a **package prefix** but can be any logger name (including a fully-qualified class name). Values are **case-insensitive** (`debug` == `DEBUG`). ## The root logger and defaults `logging.level.root` sets the fallback level applied to any logger that has no more-specific configuration. Spring Boot's **default root level is INFO**, which is why you see INFO/WARN/ERROR out of the box but not DEBUG. ## Hierarchical name resolution Logger names form a tree by dotted segments. `com.example.orders` is a child of `com.example`, which is a child of `com`, whose parent is `root`. When Spring resolves the effective level for a logger, the **most specific configured prefix wins**; if none matches it inherits from its nearest configured ancestor, ultimately `root`. ## Convenience shortcuts Spring Boot also honours two shortcuts on the command line / properties: `debug=true` and `trace=true`. These do **not** flip everything to DEBUG globally; they enable DEBUG/TRACE for a curated set of core loggers (embedded container, Hibernate, Spring Boot) while leaving your app at its configured level. ## Gotchas - Setting a level does not change *what the code logs* — a `logger.trace(...)` call still exists; you just make it visible by lowering the threshold to TRACE. - Lowering a broad package like `org.springframework` to DEBUG is extremely noisy in production. - `logging.level.<name>` controls filtering; it does not control formatting/pattern (that is `logging.pattern.*`) or destinations (that is `logging.file.*`).
- If root is INFO but logging.level.com.example=DEBUG, what does the logger com.example.orders.OrderService emit?It inherits from the most specific configured ancestor, com.example=DEBUG, so it emits DEBUG and everything more severe. root=INFO is only the fallback when no more-specific prefix matches.
- What does logging.level.org.hibernate=OFF do?OFF is a pseudo-level that disables all output for that logger subtree — no messages at any level from org.hibernate are emitted.
saying these in an interview costs you the question
- Thinking INFO shows DEBUG (it hides less-severe levels).
- Believing the level order is ERROR<WARN<INFO (severity is inverted from that).
- Claiming debug=true switches every logger in the app to DEBUG (it only targets a core set).
- Assuming logging.level also changes the output format or file destination.