Logging means recording what your application is doing while it runs.
For example, when a Spring Boot application starts, you may see:
2026-08-17T10:51:28.508Z INFO ... Starting MyApplication 2026-08-17T10:51:35.286Z INFO ... Started MyApplication
Logs help you answer questions such as:
Spring Boot uses Commons Logging internally while leaving the underlying logging implementation open. Spring Boot provides default configurations for Java Util Logging, Log4j2 and Logback.
When you use Spring Boot starters, Logback is the default logging implementation. Spring Boot also provides routing so libraries using JUL, Commons Logging, Log4J or SLF4J can work together.
| Term | Simple meaning |
|---|---|
| Commons Logging | Logging abstraction used by Spring Boot internally. |
| SLF4J | Common logging API frequently used by Java applications. |
| Logback | Default implementation when using Spring Boot starters. |
| Log4j2 | Another popular logging implementation. |
| JUL | Java Util Logging, provided by the JDK. |
A default log entry contains several useful pieces of information.
2026-08-17T10:51:28.508Z INFO 11390 --- [myapp] [main] com.example.MyApplication : Starting MyApplication
| Part | Meaning |
|---|---|
| Date and time | When the event happened. |
| Log level | ERROR, WARN, INFO, DEBUG or TRACE. |
| Process ID | ID of the running JVM process. |
| Application name | Included when spring.application.name is set. |
| Application group | Included when spring.application.group is set. |
| Thread | Thread that produced the message. |
| Logger name | Usually the source class/package, often abbreviated. |
| Message | The actual information being logged. |
Logback does not have a separate FATAL level; Spring Boot maps it to ERROR.
Think of log levels as a volume control for diagnostic information.
| Level | Meaning | Typical use |
|---|---|---|
| TRACE | Extremely detailed information. | Deep troubleshooting. |
| DEBUG | Detailed developer information. | Development and debugging. |
| INFO | Normal application events. | Startup, major business flow. |
| WARN | Something unexpected or potentially problematic. | Deprecated behavior, recoverable issue. |
| ERROR | An operation failed. | Exceptions and serious failures. |
| FATAL | Supported as a configurable level, but Logback maps it to ERROR. | Framework-specific semantics. |
| OFF | Disable logging for the selected logger. | Very targeted suppression. |
By default, Spring Boot writes logs to the console. ERROR, WARN and INFO messages are logged by default.
java -jar myapp.jar --debug
Or:
debug=true
Debug mode increases detail for a selection of core loggers such as the embedded container, Hibernate and Spring Boot. It does not mean that every application logger is automatically set to DEBUG.
java -jar myapp.jar --trace
Or:
trace=true
Trace mode enables trace logging for selected core areas, including the embedded container, Hibernate schema generation and the Spring portfolio.
logging.console.enabled=false
If the terminal supports ANSI output, Spring Boot can use colors to make logs easier to read.
spring.output.ansi.enabled=always
Spring Boot's %clr conversion word can color output based on the log level.
%clr(%5p)
| Level | Default color mapping |
|---|---|
| FATAL | Red |
| ERROR | Red |
| WARN | Yellow |
| INFO | Green |
| DEBUG | Green |
| TRACE | Green |
You can specify a color and style:
%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow,bold}
By default, Spring Boot logs to the console only. To create log files, use logging.file.name or logging.file.path.
| Configuration | Result |
|---|---|
| Neither property | Console only. |
logging.file.name=my.log | Writes to the specified file. |
logging.file.path=/var/log | Writes spring.log into that directory. |
| Both set | logging.file.name wins; path is ignored. |
logging.file.name=logs/application.log
or:
logging.file.path=logs
Log rotation prevents one log file from growing forever.
| Property | Purpose |
|---|---|
logging.logback.rollingpolicy.file-name-pattern | Archive filename pattern. |
logging.logback.rollingpolicy.clean-history-on-start | Clean archives when the application starts. |
logging.logback.rollingpolicy.max-file-size | Maximum size before archiving. |
logging.logback.rollingpolicy.total-size-cap | Total space allowed for archives. |
logging.logback.rollingpolicy.max-history | Maximum archive count; default is 7. |
logging.file.name=logs/app.log logging.logback.rollingpolicy.max-file-size=20MB logging.logback.rollingpolicy.max-history=14 logging.logback.rollingpolicy.total-size-cap=500MB
| Property | Purpose |
|---|---|
logging.log4j2.rollingpolicy.file-name-pattern | Archive filename pattern. |
logging.log4j2.rollingpolicy.max-file-size | Maximum file size; default 10MB. |
logging.log4j2.rollingpolicy.max-history | Maximum archives; default 7. |
logging.log4j2.rollingpolicy.strategy | Rolling strategy; default is size. |
logging.log4j2.rollingpolicy.cron | Cron expression when cron strategy is used. |
logging.log4j2.rollingpolicy.time-interval | Time-based triggering interval. |
logging.log4j2.rollingpolicy.time-modulate | Whether to align the next rollover with the interval. |
The most useful Spring Boot logging configuration is:
logging.level.<logger-name>=<level>
Example:
logging.level.root=warn logging.level.org.springframework.web=debug logging.level.org.hibernate=error
YAML:
logging:
level:
root: "warn"
org.springframework.web: "debug"
org.hibernate: "error"
org.springframework.web to DEBUG affects that logger/package while leaving unrelated loggers at their configured levels.LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG
SPRING_APPLICATION_JSON can be used.Sometimes you want to control several related loggers together. A logging group gives them one convenient name.
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat logging.level.tomcat=trace
YAML:
logging:
group:
tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"
level:
tomcat: "trace"
| Built-in group | Includes |
|---|---|
web | Spring core codec, HTTP, web, Actuator web endpoint and servlet initialization loggers. |
sql | Spring JDBC, Hibernate SQL and jOOQ LoggerListener. |
Spring Boot provides a shutdown hook to clean up logging resources when the JVM exits. It is registered automatically unless the application is deployed as a WAR.
Disable it when the application's context hierarchy or logging setup requires direct control:
logging.register-shutdown-hook=false
You can provide a logging configuration file or specify its location with:
logging.config=classpath:my-logback.xml
Spring Boot can use different logging systems depending on the libraries available on the classpath.
| Logging system | Configuration files |
|---|---|
| Logback | logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy |
| Log4j2 | log4j2-spring.xml, log4j2.xml |
| JUL | logging.properties |
-spring variants such as logback-spring.xml. They allow Spring Boot to have more control over initialization.ApplicationContext is created. Therefore, you cannot use @PropertySource inside configuration to control the logging system during initialization.The system property org.springframework.boot.logging.LoggingSystem can force a particular implementation.
-Dorg.springframework.boot.logging.LoggingSystem=com.example.MyLoggingSystem
It can also disable Spring Boot logging configuration:
-Dorg.springframework.boot.logging.LoggingSystem=none
Spring Boot transfers selected Environment properties into System properties so the underlying logging configuration can use them.
| Spring property | System property |
|---|---|
logging.file.name | LOG_FILE |
logging.file.path | LOG_PATH |
logging.pattern.console | CONSOLE_LOG_PATTERN |
logging.pattern.file | FILE_LOG_PATTERN |
logging.pattern.dateformat | LOG_DATEFORMAT_PATTERN |
logging.pattern.level | LOG_LEVEL_PATTERN |
logging.charset.console | CONSOLE_LOG_CHARSET |
logging.threshold.console | CONSOLE_LOG_THRESHOLD |
logging.structured.format.console | CONSOLE_LOG_STRUCTURED_FORMAT |
logging.structured.format.file | FILE_LOG_STRUCTURED_FORMAT |
For Logback, Spring Boot also transfers rolling-policy properties into corresponding LOGBACK_... system properties.
You can customize the level portion of the log output using logging.pattern.level.
logging.pattern.level=user:%X{user} %5p
This can include an MDC value such as a user identifier when that value exists.
Structured logging means writing logs in a predictable, machine-readable structure instead of relying only on human-oriented text.
Spring Boot provides structured logging support for:
Enable it for console:
logging.structured.format.console=ecs
Or file:
logging.structured.format.file=ecs
You can configure both:
logging.structured.format.console=ecs logging.structured.format.file=ecs
ECS is a JSON-based logging format.
logging.structured.format.console=ecs logging.structured.format.file=ecs
A typical ECS record contains fields for timestamp, level, logger, process, service and message.
ECS also includes key-value pairs stored in MDC. SLF4J's fluent logging API can add key-value pairs using addKeyValue.
logging.structured.ecs.service.name=MyService logging.structured.ecs.service.version=1 logging.structured.ecs.service.environment=Production logging.structured.ecs.service.node-name=Primary
If not specified, the ECS service name defaults to spring.application.name, and service version defaults to spring.application.version.
GELF is a JSON-based format intended for the Graylog log analytics platform.
logging.structured.format.console=gelf logging.structured.format.file=gelf
Some GELF fields can be customized:
logging.structured.gelf.host=MyService logging.structured.gelf.service.version=1
The GELF host defaults to spring.application.name when not specified, and service version defaults to spring.application.version.
Logstash JSON is another structured JSON format.
logging.structured.format.console=logstash logging.structured.format.file=logstash
Like the other structured formats, MDC key-value pairs are included. SLF4J markers can also appear as a tags string array.
Spring Boot provides properties for small changes to generated structured JSON.
| Property | Purpose |
|---|---|
logging.structured.json.include / exclude | Include or filter specific JSON paths. |
logging.structured.json.rename | Rename a JSON member. |
logging.structured.json.add | Add additional JSON members. |
Example:
logging.structured.json.exclude=log.level logging.structured.json.rename.process.id=procid logging.structured.json.add.corpname=mycorp
For more advanced customization, implement StructuredLoggingJsonMembersCustomizer.
Structured logs include complete exception stack traces by default. For large systems, this can increase ingestion and processing costs.
| Property | Purpose |
|---|---|
logging.structured.json.stacktrace.root | Use first or last for the root item. |
logging.structured.json.stacktrace.max-length | Maximum printed length. |
logging.structured.json.stacktrace.max-throwable-depth | Maximum number of frames. |
logging.structured.json.stacktrace.include-common-frames | Include or remove common frames. |
logging.structured.json.stacktrace.include-hashes | Include a stack-trace hash. |
logging.structured.json.stacktrace.root=first logging.structured.json.stacktrace.max-length=1024 logging.structured.json.stacktrace.include-common-frames=true logging.structured.json.stacktrace.include-hashes=true
For full control, configure logging.structured.json.stacktrace.printer with a StackTracePrinter implementation, or use logging-system for regular logging-system stack trace output.
Spring Boot's structured logging support is extensible. Implement StructuredLogFormatter.
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.springframework.boot.logging.structured.StructuredLogFormatter;
class MyCustomFormat implements StructuredLogFormatter<ILoggingEvent> {
@Override
public String format(ILoggingEvent event) {
return "time=" + event.getInstant()
+ " level=" + event.getLevel()
+ " message=" + event.getMessage() + "\n";
}
}
Then configure the console or file format with the fully qualified class name of your implementation.
logging.structured.format.console=com.example.MyCustomFormat
Spring Boot provides Logback extensions for advanced configuration. These are intended for logback-spring.xml.
logback.xml is loaded too early for these Spring Boot extensions. Use logback-spring.xml or specify a configuration through logging.config.<springProfile name="staging">
<!-- staging configuration -->
</springProfile>
<springProfile name="dev | staging">
<!-- dev OR staging -->
</springProfile>
<springProfile name="!production">
<!-- when production is not active -->
</springProfile>
Profile expressions can also be more complex, such as:
production & (eu-central | eu-west)
The <springProperty> tag exposes Spring Environment values to Logback.
<springProperty scope="context"
name="fluentHost"
source="myapp.fluentd.host"
defaultValue="localhost"/>
<appender name="FLUENT"
class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
</appender>
The source should be written in kebab case, such as my.property-name.
Spring Boot also provides extensions for Log4j2 through log4j2-spring.xml.
log4j2.xml loads too early for Spring Boot extensions. Use log4j2-spring.xml or configure logging.config.<SpringProfile name="staging">
<!-- staging configuration -->
</SpringProfile>
<SpringProfile name="dev | staging">
<!-- dev OR staging -->
</SpringProfile>
<SpringProfile name="!production">
<!-- not production -->
</SpringProfile>
Log4j2 can use spring:-prefixed lookups:
<Properties>
<Property name="applicationName">
${spring:spring.application.name}
</Property>
<Property name="applicationGroup">
${spring:spring.application.group}
</Property>
</Properties>
Lookup keys should be specified in kebab case.
A simple production-oriented starting point might look like this:
spring.application.name=order-service # Normal application logging logging.level.root=INFO # More detail for your application logging.level.com.example.orders=DEBUG # Keep framework noise lower logging.level.org.hibernate=WARN # Write to a file logging.file.name=logs/order-service.log # Rotate logs logging.logback.rollingpolicy.max-file-size=20MB logging.logback.rollingpolicy.max-history=14 logging.logback.rollingpolicy.total-size-cap=500MB
logging.file.name and logging.file.path are set, the name wins.logback-spring.xml.-spring logging configuration files for Spring Boot extensions.Logback when using Spring Boot starters.
Q2. What is the difference between DEBUG mode and setting every logger to DEBUG?Spring Boot debug mode increases detail for selected core loggers. It does not automatically make every application logger DEBUG.
Q3. How do you change the log level for a package?logging.level.com.example=DEBUGQ4. How do you write Spring Boot logs to a file?
logging.file.name=logs/application.log
or use logging.file.path for a directory.
logging.file.name is used and logging.file.path is ignored.
A named collection of loggers that can be configured together.
Q7. Why use logback-spring.xml instead of logback.xml?Spring Boot extensions require the Spring-aware configuration file because standard logback.xml is loaded too early.
Q8. What is structured logging?Logging in a predictable, often machine-readable format such as JSON.
Q9. Which structured formats does Spring Boot support out of the box?ECS, GELF and Logstash.
Q10. When is structured logging useful?Especially when logs are collected, searched and analyzed by centralized observability/log analytics systems.
logs/app.log.tomcat logging group.dev.logback-spring.xml is preferred for Spring Boot extensions.| Goal | Configuration |
|---|---|
| Root level | logging.level.root=INFO |
| Package level | logging.level.com.example=DEBUG |
| File logging | logging.file.name=logs/app.log |
| Directory logging | logging.file.path=logs |
| Disable console | logging.console.enabled=false |
| Debug mode | --debug or debug=true |
| Trace mode | --trace or trace=true |
| Logging group | logging.group.name=logger1,logger2 |
| Group level | logging.level.name=TRACE |
| Shutdown hook off | logging.register-shutdown-hook=false |
| Custom config | logging.config=... |
| ECS | logging.structured.format.console=ecs |
| GELF | logging.structured.format.console=gelf |
| Logstash | logging.structured.format.console=logstash |
Spring Boot Logging →
Default Logback → Log levels → Console → Files → Rotation → Logger levels → Groups → Shutdown hook → Custom configuration → Structured logging → ECS / GELF / Logstash → JSON customization → Stack traces → Logback extensions → Log4j2 extensions
Spring Boot gives you useful logging defaults so you can start without complicated configuration. As the application grows, you can control where logs go, which levels are emitted, how files rotate, which loggers are grouped, and how logs are structured for machines.
The most important practical progression is: