[[features.logging]]
= Logging

Spring Boot uses https://commons.apache.org/logging[Commons Logging] for all internal logging but leaves the underlying log implementation open.
Default configurations are provided for {apiref-openjdk}/java.logging/java/util/logging/package-summary.html[Java Util Logging], https://logging.apache.org/log4j/2.x/[Log4j2], and https://logback.qos.ch/[Logback].
In each case, loggers are pre-configured to use console output with optional file output also available.

By default, if you use the starters, Logback is used for logging.
Appropriate Logback routing is also included to ensure that dependent libraries that use Java Util Logging, Commons Logging, Log4J, or SLF4J all work correctly.

TIP: There are a lot of logging frameworks available for Java.
Do not worry if the above list seems confusing.
Generally, you do not need to change your logging dependencies and the Spring Boot defaults work just fine.

TIP: When you deploy your application to a servlet container or application server, logging performed with the Java Util Logging API is not routed into your application's logs.
This prevents logging performed by the container or other applications that have been deployed to it from appearing in your application's logs.



[[features.logging.log-format]]
== Log Format

The default log output from Spring Boot resembles the following example:

[source]
----
include::ROOT:partial$logging/logging-format.txt[]
----

The following items are output:

* Date and Time: Millisecond precision and easily sortable.
* Log Level: `ERROR`, `WARN`, `INFO`, `DEBUG`, or `TRACE`.
* Process ID.
* A `---` separator to distinguish the start of actual log messages.
* Application name: Enclosed in square brackets (logged by default only if configprop:spring.application.name[] is set)
* Application group: Enclosed in square brackets (logged by default only if configprop:spring.application.group[] is set)
* Thread name: Enclosed in square brackets (may be truncated for console output).
* Correlation ID: If tracing is enabled (not shown in the sample above)
* Logger name: This is usually the source class name (often abbreviated).
* The log message.

NOTE: Logback does not have a `FATAL` level.
It is mapped to `ERROR`.

TIP: If you have a configprop:spring.application.name[] property but don't want it logged you can set configprop:logging.include-application-name[] to `false`.

TIP: If you have a configprop:spring.application.group[] property but don't want it logged you can set configprop:logging.include-application-group[] to `false`.

TIP: For more details about correlation IDs, please xref:reference:actuator/tracing.adoc#actuator.micrometer-tracing.logging[see this documentation].



[[features.logging.console-output]]
== Console Output

The default log configuration echoes messages to the console as they are written.
By default, `ERROR`-level, `WARN`-level, and `INFO`-level messages are logged.
You can also enable a "`debug`" mode by starting your application with a `--debug` flag.

[source,shell]
----
$ java -jar myapp.jar --debug
----

NOTE: You can also specify `debug=true` in your `application.properties`.

When the debug mode is enabled, a selection of core loggers (embedded container, Hibernate, and Spring Boot) are configured to output more information.
Enabling the debug mode does _not_ configure your application to log all messages with `DEBUG` level.

Alternatively, you can enable a "`trace`" mode by starting your application with a `--trace` flag (or `trace=true` in your `application.properties`).
Doing so enables trace logging for a selection of core loggers (embedded container, Hibernate schema generation, and the whole Spring portfolio).



[[features.logging.console-output.color-coded]]
=== Color-coded Output

If your terminal supports ANSI, color output is used to aid readability.
You can set `spring.output.ansi.enabled` to a javadoc:org.springframework.boot.ansi.AnsiOutput$Enabled[supported value] to override the auto-detection.

Color coding is configured by using the `%clr` conversion word.
In its simplest form, the converter colors the output according to the log level, as shown in the following example:

[source]
----
%clr(%5p)
----

The following table describes the mapping of log levels to colors:

|===
| Level | Color

| `FATAL`
| Red

| `ERROR`
| Red

| `WARN`
| Yellow

| `INFO`
| Green

| `DEBUG`
| Green

| `TRACE`
| Green
|===

Alternatively, you can specify the color or style that should be used by providing it as an option to the conversion.
For example, to make the text yellow, use the following setting:

[source]
----
%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow}
----

The following colors and styles are supported:

* `black`
* `blue`
* `bright_black`
* `bright_blue`
* `bright_cyan`
* `bright_green`
* `bright_magenta`
* `bright_red`
* `bright_white`
* `bright_yellow`
* `cyan`
* `faint`
* `green`
* `magenta`
* `red`
* `white`
* `yellow`



[[features.logging.file-output]]
== File Output

By default, Spring Boot logs only to the console and does not write log files.
If you want to write log files in addition to the console output, you need to set a configprop:logging.file.name[] or configprop:logging.file.path[] property (for example, in your `application.properties`).
If both properties are set, `logging.file.path` is ignored and only `logging.file.name` is used.

The following table shows how the `logging.*` properties can be used together:

.Logging properties
[cols="1,1,4"]
|===
| configprop:logging.file.name[] | configprop:logging.file.path[] | Description

| _(none)_
| _(none)_
| Console only logging.

| Specific file (for example, `my.log`)
| _(none)_
| Writes to the location specified by `logging.file.name`.
  The location can be absolute or relative to the current directory.

| _(none)_
| Specific directory (for example, `/var/log`)
| Writes `spring.log` to the directory specified by `logging.file.path`.
  The directory can be absolute or relative to the current directory.

| Specific file
| Specific directory
| Writes to the location specified by `logging.file.name` and ignores `logging.file.path`.
  The location can be absolute or relative to the current directory.
|===

Log files rotate when they reach 10 MB and, as with console output, `ERROR`-level, `WARN`-level, and `INFO`-level messages are logged by default.
Note that Log4J2 requires `logging.file.path` to be set with such configuration.

TIP: Logging properties are independent of the actual logging infrastructure.
As a result, specific configuration keys (such as `logback.configurationFile` for Logback) are not managed by spring Boot.



[[features.logging.file-rotation]]
== File Rotation

If you are using the Logback, it is possible to fine-tune log rotation settings using your `application.properties` or `application.yaml` file.
For all other logging system, you will need to configure rotation settings directly yourself (for example, if you use Log4j2 then you could add a `log4j2.xml` or `log4j2-spring.xml` file).

The following rotation policy properties are supported:

|===
| Name | Description

| configprop:logging.logback.rollingpolicy.file-name-pattern[]
| The filename pattern used to create log archives.

| configprop:logging.logback.rollingpolicy.clean-history-on-start[]
| If log archive cleanup should occur when the application starts.

| configprop:logging.logback.rollingpolicy.max-file-size[]
| The maximum size of log file before it is archived.

| configprop:logging.logback.rollingpolicy.total-size-cap[]
| The maximum amount of size log archives can take before being deleted.

| configprop:logging.logback.rollingpolicy.max-history[]
| The maximum number of archive log files to keep (defaults to 7).
|===



[[features.logging.log-levels]]
== Log Levels

All the supported logging systems can have the logger levels set in the Spring javadoc:org.springframework.core.env.Environment[] (for example, in `application.properties`) by using `+logging.level.<logger-name>=<level>+` where `level` is one of TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF.
The `root` logger can be configured by using `logging.level.root`.

The following example shows potential logging settings in `application.properties`:

[configprops,yaml]
----
logging:
  level:
    root: "warn"
    org.springframework.web: "debug"
    org.hibernate: "error"
----

It is also possible to set logging levels using environment variables.
For example, `LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG` will set `org.springframework.web` to `DEBUG`.

NOTE: The above approach will only work for package level logging.
Since relaxed binding xref:features/external-config.adoc#features.external-config.typesafe-configuration-properties.relaxed-binding.maps-from-environment-variables[always converts environment variables to lowercase], it is not possible to configure logging for an individual class in this way.
If you need to configure logging for a class, you can use xref:features/external-config.adoc#features.external-config.application-json[the `SPRING_APPLICATION_JSON`] variable.



[[features.logging.log-groups]]
== Log Groups

It is often useful to be able to group related loggers together so that they can all be configured at the same time.
For example, you might commonly change the logging levels for _all_ Tomcat related loggers, but you can not easily remember top level packages.

To help with this, Spring Boot allows you to define logging groups in your Spring javadoc:org.springframework.core.env.Environment[].
For example, here is how you could define a "`tomcat`" group by adding it to your `application.properties`:

[configprops,yaml]
----
logging:
  group:
    tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"
----

Once defined, you can change the level for all the loggers in the group with a single line:

[configprops,yaml]
----
logging:
  level:
    tomcat: "trace"
----

Spring Boot includes the following pre-defined logging groups that can be used out-of-the-box:

[cols="1,4"]
|===
| Name | Loggers

| web
| `org.springframework.core.codec`, `org.springframework.http`, `org.springframework.web`, `org.springframework.boot.actuate.endpoint.web`, `org.springframework.boot.web.servlet.ServletContextInitializerBeans`

| sql
| `org.springframework.jdbc.core`, `org.hibernate.SQL`, javadoc:org.jooq.tools.LoggerListener[]
|===



[[features.logging.shutdown-hook]]
== Using a Log Shutdown Hook

In order to release logging resources when your application terminates, a shutdown hook that will trigger log system cleanup when the JVM exits is provided.
This shutdown hook is registered automatically unless your application is deployed as a war file.
If your application has complex context hierarchies the shutdown hook may not meet your needs.
If it does not, disable the shutdown hook and investigate the options provided directly by the underlying logging system.
For example, Logback offers https://logback.qos.ch/manual/loggingSeparation.html[context selectors] which allow each Logger to be created in its own context.
You can use the configprop:logging.register-shutdown-hook[] property to disable the shutdown hook.
Setting it to `false` will disable the registration.
You can set the property in your `application.properties` or `application.yaml` file:

[configprops,yaml]
----
logging:
  register-shutdown-hook: false
----



[[features.logging.custom-log-configuration]]
== Custom Log Configuration

The various logging systems can be activated by including the appropriate libraries on the classpath and can be further customized by providing a suitable configuration file in the root of the classpath or in a location specified by the following Spring javadoc:org.springframework.core.env.Environment[] property: configprop:logging.config[].

You can force Spring Boot to use a particular logging system by using the `org.springframework.boot.logging.LoggingSystem` system property.
The value should be the fully qualified class name of a javadoc:org.springframework.boot.logging.LoggingSystem[] implementation.
You can also disable Spring Boot's logging configuration entirely by using a value of `none`.

NOTE: Since logging is initialized *before* the javadoc:org.springframework.context.ApplicationContext[] is created, it is not possible to control logging from javadoc:org.springframework.context.annotation.PropertySources[format=annotation] in Spring javadoc:org.springframework.context.annotation.Configuration[format=annotation] files.
The only way to change the logging system or disable it entirely is through System properties.

Depending on your logging system, the following files are loaded:

|===
| Logging System | Customization

| Logback
| `logback-spring.xml`, `logback-spring.groovy`, `logback.xml`, or `logback.groovy`

| Log4j2
| `log4j2-spring.xml` or `log4j2.xml`

| JDK (Java Util Logging)
| `logging.properties`
|===

NOTE: When possible, we recommend that you use the `-spring` variants for your logging configuration (for example, `logback-spring.xml` rather than `logback.xml`).
If you use standard configuration locations, Spring cannot completely control log initialization.

WARNING: There are known classloading issues with Java Util Logging that cause problems when running from an 'executable jar'.
We recommend that you avoid it when running from an 'executable jar' if at all possible.

To help with the customization, some other properties are transferred from the Spring javadoc:org.springframework.core.env.Environment[] to System properties.
This allows the properties to be consumed by logging system configuration. For example, setting `logging.file.name` in `application.properties` or `LOGGING_FILE_NAME` as an environment variable will result in the `LOG_FILE` System property being set.
The properties that are transferred are described in the following table:

|===
| Spring Environment | System Property | Comments

| configprop:logging.exception-conversion-word[]
| `LOG_EXCEPTION_CONVERSION_WORD`
| The conversion word used when logging exceptions.

| configprop:logging.file.name[]
| `LOG_FILE`
| If defined, it is used in the default log configuration.

| configprop:logging.file.path[]
| `LOG_PATH`
| If defined, it is used in the default log configuration.

| configprop:logging.pattern.console[]
| `CONSOLE_LOG_PATTERN`
| The log pattern to use on the console (stdout).

| configprop:logging.pattern.dateformat[]
| `LOG_DATEFORMAT_PATTERN`
| Appender pattern for log date format.

| configprop:logging.charset.console[]
| `CONSOLE_LOG_CHARSET`
| The charset to use for console logging.

| configprop:logging.threshold.console[]
| `CONSOLE_LOG_THRESHOLD`
| The log level threshold to use for console logging.

| configprop:logging.pattern.file[]
| `FILE_LOG_PATTERN`
| The log pattern to use in a file (if `LOG_FILE` is enabled).

| configprop:logging.charset.file[]
| `FILE_LOG_CHARSET`
| The charset to use for file logging (if `LOG_FILE` is enabled).

| configprop:logging.threshold.file[]
| `FILE_LOG_THRESHOLD`
| The log level threshold to use for file logging.

| configprop:logging.pattern.level[]
| `LOG_LEVEL_PATTERN`
| The format to use when rendering the log level (default `%5p`).

| configprop:logging.structured.format.console[]
| `CONSOLE_LOG_STRUCTURED_FORMAT`
| The structured logging format to use for console logging.

| configprop:logging.structured.format.file[]
| `FILE_LOG_STRUCTURED_FORMAT`
| The structured logging format to use for file logging.

| `PID`
| `PID`
| The current process ID (discovered if possible and when not already defined as an OS environment variable).
|===

If you use Logback, the following properties are also transferred:

|===
| Spring Environment | System Property | Comments

| configprop:logging.logback.rollingpolicy.file-name-pattern[]
| `LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN`
| Pattern for rolled-over log file names (default `$\{LOG_FILE}.%d\{yyyy-MM-dd}.%i.gz`).

| configprop:logging.logback.rollingpolicy.clean-history-on-start[]
| `LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START`
| Whether to clean the archive log files on startup.

| configprop:logging.logback.rollingpolicy.max-file-size[]
| `LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE`
| Maximum log file size.

| configprop:logging.logback.rollingpolicy.total-size-cap[]
| `LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP`
| Total size of log backups to be kept.

| configprop:logging.logback.rollingpolicy.max-history[]
| `LOGBACK_ROLLINGPOLICY_MAX_HISTORY`
| Maximum number of archive log files to keep.
|===


All the supported logging systems can consult System properties when parsing their configuration files.
See the default configurations in `spring-boot.jar` for examples:

* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml[Logback]
* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml[Log4j 2]
* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties[Java Util logging]

[TIP]
====
If you want to use a placeholder in a logging property, you should use xref:features/external-config.adoc#features.external-config.files.property-placeholders[Spring Boot's syntax] and not the syntax of the underlying framework.
Notably, if you use Logback, you should use `:` as the delimiter between a property name and its default value and not use `:-`.
====

[TIP]
====
You can add MDC and other ad-hoc content to log lines by overriding only the `LOG_LEVEL_PATTERN` (or `logging.pattern.level` with Logback).
For example, if you use `logging.pattern.level=user:%X\{user} %5p`, then the default log format contains an MDC entry for "user", if it exists, as shown in the following example.

[source]
----
2019-08-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request
----
====



[[features.logging.structured]]
== Structured Logging

Structured logging is a technique where the log output is written in a well-defined, often machine-readable format.
Spring Boot supports structured logging and has support for the following JSON formats out of the box:

* xref:#features.logging.structured.ecs[Elastic Common Schema (ECS)]
* xref:#features.logging.structured.gelf[Graylog Extended Log Format (GELF)]
* xref:#features.logging.structured.logstash[Logstash]

To enable structured logging, set the property configprop:logging.structured.format.console[] (for console output) or configprop:logging.structured.format.file[] (for file output) to the id of the format you want to use.

If you are using xref:#features.logging.custom-log-configuration[Custom Log Configuration], update your configuration to respect `CONSOLE_LOG_STRUCTURED_FORMAT` and `FILE_LOG_STRUCTURED_FORMAT` system properties.
Take `CONSOLE_LOG_STRUCTURED_FORMAT` for example:
[tabs]
======
Logback::
+
[source,xml]
----
<!-- replace your encoder with StructuredLogEncoder -->
<encoder class="org.springframework.boot.logging.logback.StructuredLogEncoder">
	<format>${CONSOLE_LOG_STRUCTURED_FORMAT}</format>
	<charset>${CONSOLE_LOG_CHARSET}</charset>
</encoder>
----
+
You can also refer to the default configurations included in Spring Boot:
+
* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/structured-console-appender.xml[Logback Structured Console Appender]
* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/structured-file-appender.xml[Logback Structured File Appender]
Log4j2::
+
[source,xml]
----
<!-- replace your PatternLayout with StructuredLogLayout -->
<StructuredLogLayout format="${sys:CONSOLE_LOG_STRUCTURED_FORMAT}" charset="${sys:CONSOLE_LOG_CHARSET}"/>
----
+
You can also refer to the default configurations included in Spring Boot:
+
* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml[Log4j2 Console Appender]
* {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml[Log4j2 Console and File Appender]
======


[[features.logging.structured.ecs]]
=== Elastic Common Schema

https://www.elastic.co/guide/en/ecs/8.11/ecs-reference.html[Elastic Common Schema] is a JSON based logging format.

To enable the Elastic Common Schema log format, set the appropriate `format` property to `ecs`:

[configprops,yaml]
----
logging:
  structured:
    format:
      console: ecs
      file: ecs
----

A log line looks like this:

[source,json]
----
{"@timestamp":"2024-01-01T10:15:00.067462556Z","log":{"level":"INFO","logger":"org.example.Application"},"process":{"pid":39599,"thread":{"name":"main"}},"service":{"name":"simple"},"message":"No active profile set, falling back to 1 default profile: \"default\"","ecs":{"version":"8.11"}}
----

This format also adds every key value pair contained in the MDC to the JSON object.
You can also use the https://www.slf4j.org/manual.html#fluent[SLF4J fluent logging API] to add key value pairs to the logged JSON object with the https://www.slf4j.org/apidocs/org/slf4j/spi/LoggingEventBuilder.html#addKeyValue(java.lang.String,java.lang.Object)[addKeyValue] method.

The `service` values can be customized using `logging.structured.ecs.service` properties:

[configprops,yaml]
----
logging:
  structured:
    ecs:
      service:
        name: MyService
        version: 1.0
        environment: Production
        node-name: Primary
----

NOTE: configprop:logging.structured.ecs.service.name[] will default to configprop:spring.application.name[] if not specified.

NOTE: configprop:logging.structured.ecs.service.version[] will default to configprop:spring.application.version[] if not specified.



[[features.logging.structured.gelf]]
=== Graylog Extended Log Format (GELF)

https://go2docs.graylog.org/current/getting_in_log_data/gelf.html[Graylog Extended Log Format] is a JSON based logging format for the Graylog log analytics platform.

To enable the Graylog Extended Log Format, set the appropriate `format` property to `gelf`:

[configprops,yaml]
----
logging:
  structured:
    format:
      console: gelf
      file: gelf
----

A log line looks like this:

[source,json]
----
{"version":"1.1","short_message":"No active profile set, falling back to 1 default profile: \"default\"","timestamp":1725958035.857,"level":6,"_level_name":"INFO","_process_pid":47649,"_process_thread_name":"main","_log_logger":"org.example.Application"}
----

This format also adds every key value pair contained in the MDC to the JSON object.
You can also use the https://www.slf4j.org/manual.html#fluent[SLF4J fluent logging API] to add key value pairs to the logged JSON object with the https://www.slf4j.org/apidocs/org/slf4j/spi/LoggingEventBuilder.html#addKeyValue(java.lang.String,java.lang.Object)[addKeyValue] method.

Several fields can be customized using `logging.structured.gelf` properties:

[configprops,yaml]
----
logging:
  structured:
    gelf:
      host: MyService
      service:
        version: 1.0
----

NOTE: configprop:logging.structured.gelf.host[] will default to configprop:spring.application.name[] if not specified.

NOTE: configprop:logging.structured.gelf.service.version[] will default to configprop:spring.application.version[] if not specified.



[[features.logging.structured.logstash]]
=== Logstash JSON format

The https://github.com/logfellow/logstash-logback-encoder?tab=readme-ov-file#standard-fields[Logstash JSON format] is a JSON based logging format.

To enable the Logstash JSON log format, set the appropriate `format` property to `logstash`:

[configprops,yaml]
----
logging:
  structured:
    format:
      console: logstash
      file: logstash
----

A log line looks like this:

[source,json]
----
{"@timestamp":"2024-01-01T10:15:00.111037681+02:00","@version":"1","message":"No active profile set, falling back to 1 default profile: \"default\"","logger_name":"org.example.Application","thread_name":"main","level":"INFO","level_value":20000}
----

This format also adds every key value pair contained in the MDC to the JSON object.
You can also use the https://www.slf4j.org/manual.html#fluent[SLF4J fluent logging API] to add key value pairs to the logged JSON object with the https://www.slf4j.org/apidocs/org/slf4j/spi/LoggingEventBuilder.html#addKeyValue(java.lang.String,java.lang.Object)[addKeyValue] method.

If you add https://www.slf4j.org/api/org/slf4j/Marker.html[markers], these will show up in a `tags` string array in the JSON.



[[features.logging.structured.customizing-json]]
=== Customizing Structured Logging JSON

Spring Boot attempts to pick sensible defaults for the JSON names and values output for structured logging.
Sometimes, however, you may want to make small adjustments to the JSON for your own needs.
For example, it's possible that you might want to change some of the names to match the expectations of your log ingestion system.
You might also want to filter out certain members since you don't find them useful.

The following properties allow you to change the way that structured logging JSON is written:

|===
| Property | Description

| configprop:logging.structured.json.include[] & configprop:logging.structured.json.exclude[]
| Filters specific paths from the JSON

| configprop:logging.structured.json.rename[]
| Renames a specific member in the JSON

| configprop:logging.structured.json.add[]
| Adds additional members to the JSON
|===

For example, the following will exclude `log.level`, rename `process.id` to `procid` and add a fixed `corpname` field:

[configprops,yaml]
----
logging:
  structured:
    json:
      exclude: log.level
      rename:
        process.id: procid
      add:
        corpname: mycorp
----

TIP: For more advanced customizations, you can use the javadoc:org.springframework.boot.logging.structured.StructuredLoggingJsonMembersCustomizer[] interface.
You can reference one or more implementations using the configprop:logging.structured.json.customizer[] property.
You can also declare implementations by listing them in a `META-INF/spring.factories` file.



[[features.logging.structured.customizing-stack-traces]]
=== Customizing Structured Logging Stack Traces

Complete stack traces are included in the JSON output whenever a message is logged with an exception.
This amount of information may be costly to process by your log ingestion system, so you may want to tune the way that stack traces are printed.

To do this, you can use one or more of the following properties:

|===
| Property | Description

| configprop:logging.structured.json.stacktrace.root[]
| Use `last` to print the root item last (same as Java) or `first` to print the root item first.

| configprop:logging.structured.json.stacktrace.max-length[]
| The maximum length that should be printed

| configprop:logging.structured.json.stacktrace.max-throwable-depth[]
| The maximum number of frames to print per stack trace (including common and suppressed frames)

| configprop:logging.structured.json.stacktrace.include-common-frames[]
| If common frames should be included or removed

| configprop:logging.structured.json.stacktrace.include-hashes[]
| If a hash of the stack trace should be included
|===

For example, the following will use root first stack traces, limit their length, and include hashes.

[configprops,yaml]
----
logging:
  structured:
    json:
      stacktrace:
        root: first
        max-length: 1024
        include-common-frames: true
        include-hashes: true
----

[TIP]
====
If you need complete control over stack trace printing you can set configprop:logging.structured.json.stacktrace.printer[] to the name of a javadoc:org.springframework.boot.logging.StackTracePrinter[] implementation.
You can also set it to `logging-system` to force regular logging system stack trace output to be used.

Your `StackTracePrinter` implementation can also include a constructor argument that accepts a javadoc:org.springframework.boot.logging.StandardStackTracePrinter[] if it wishes to apply further customization to the stack trace printer created from the properties.
====



[[features.logging.structured.other-formats]]
=== Supporting Other Structured Logging Formats

The structured logging support in Spring Boot is extensible, allowing you to define your own custom format.
To do this, implement the javadoc:org.springframework.boot.logging.structured.StructuredLogFormatter[] interface. The generic type argument has to be javadoc:ch.qos.logback.classic.spi.ILoggingEvent[] when using Logback and javadoc:org.apache.logging.log4j.core.LogEvent[] when using Log4j2 (that means your implementation is tied to a specific logging system).
Your implementation is then called with the log event and returns the javadoc:java.lang.String[] to be logged, as seen in this example:

include-code::MyCustomFormat[]

As you can see in the example, you can return any format, it doesn't have to be JSON.

To enable your custom format, set the property configprop:logging.structured.format.console[] or configprop:logging.structured.format.file[] to the fully qualified class name of your implementation.

Your implementation can use some constructor parameters, which are injected automatically.
Please see the JavaDoc of javadoc:org.springframework.boot.logging.structured.StructuredLogFormatter[] for more details.



[[features.logging.logback-extensions]]
== Logback Extensions

Spring Boot includes a number of extensions to Logback that can help with advanced configuration.
You can use these extensions in your `logback-spring.xml` configuration file.

NOTE: Because the standard `logback.xml` configuration file is loaded too early, you cannot use extensions in it.
You need to either use `logback-spring.xml` or define a configprop:logging.config[] property.

WARNING: The extensions cannot be used with Logback's https://logback.qos.ch/manual/configuration.html#autoScan[configuration scanning].
If you attempt to do so, making changes to the configuration file results in an error similar to one of the following being logged:

[source]
----
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
----



[[features.logging.logback-extensions.profile-specific]]
=== Profile-specific Configuration

The `<springProfile>` tag lets you optionally include or exclude sections of configuration based on the active Spring profiles.
Profile sections are supported anywhere within the `<configuration>` element.
Use the `name` attribute to specify which profile accepts the configuration.
The `<springProfile>` tag can contain a profile name (for example `staging`) or a profile expression.
A profile expression allows for more complicated profile logic to be expressed, for example `production & (eu-central | eu-west)`.
Check the {url-spring-framework-docs}/core/beans/environment.html#beans-definition-profiles-java[Spring Framework reference guide] for more details.
The following listing shows three sample profiles:

[source,xml]
----
<springProfile name="staging">
	<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
	<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
	<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
----



[[features.logging.logback-extensions.environment-properties]]
=== Environment Properties

The `<springProperty>` tag lets you expose properties from the Spring javadoc:org.springframework.core.env.Environment[] for use within Logback.
Doing so can be useful if you want to access values from your `application.properties` file in your Logback configuration.
The tag works in a similar way to Logback's standard `<property>` tag.
However, rather than specifying a direct `value`, you specify the `source` of the property (from the javadoc:org.springframework.core.env.Environment[]).
If you need to store the property somewhere other than in `local` scope, you can use the `scope` attribute.
If you need a fallback value (in case the property is not set in the javadoc:org.springframework.core.env.Environment[]), you can use the `defaultValue` attribute.
The following example shows how to expose properties for use within Logback:

[source,xml]
----
<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>
----

NOTE: The `source` must be specified in kebab case (such as `my.property-name`).
However, properties can be added to the javadoc:org.springframework.core.env.Environment[] by using the relaxed rules.



[[features.logging.log4j2-extensions]]
== Log4j2 Extensions

Spring Boot includes a number of extensions to Log4j2 that can help with advanced configuration.
You can use these extensions in any `log4j2-spring.xml` configuration file.

NOTE: Because the standard `log4j2.xml` configuration file is loaded too early, you cannot use extensions in it.
You need to either use `log4j2-spring.xml` or define a configprop:logging.config[] property.

NOTE: The extensions supersede the https://logging.apache.org/log4j/2.x/log4j-spring-boot.html[Spring Boot support] provided by Log4J.
You should make sure not to include the `org.apache.logging.log4j:log4j-spring-boot` module in your build.



[[features.logging.log4j2-extensions.profile-specific]]
=== Profile-specific Configuration

The `<SpringProfile>` tag lets you optionally include or exclude sections of configuration based on the active Spring profiles.
Profile sections are supported anywhere within the `<Configuration>` element.
Use the `name` attribute to specify which profile accepts the configuration.
The `<SpringProfile>` tag can contain a profile name (for example `staging`) or a profile expression.
A profile expression allows for more complicated profile logic to be expressed, for example `production & (eu-central | eu-west)`.
Check the {url-spring-framework-docs}/core/beans/environment.html#beans-definition-profiles-java[Spring Framework reference guide] for more details.
The following listing shows three sample profiles:

[source,xml]
----
<SpringProfile name="staging">
	<!-- configuration to be enabled when the "staging" profile is active -->
</SpringProfile>

<SpringProfile name="dev | staging">
	<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</SpringProfile>

<SpringProfile name="!production">
	<!-- configuration to be enabled when the "production" profile is not active -->
</SpringProfile>
----



[[features.logging.log4j2-extensions.environment-properties-lookup]]
=== Environment Properties Lookup

If you want to refer to properties from your Spring javadoc:org.springframework.core.env.Environment[] within your Log4j2 configuration you can use `spring:` prefixed https://logging.apache.org/log4j/2.x/manual/lookups.html[lookups].
Doing so can be useful if you want to access values from your `application.properties` file in your Log4j2 configuration.

The following example shows how to set Log4j2 properties named `applicationName` and `applicationGroup` that read `spring.application.name` and `spring.application.group` from the Spring javadoc:org.springframework.core.env.Environment[]:

[source,xml]
----
<Properties>
	<Property name="applicationName">${spring:spring.application.name}</Property>
	<Property name="applicationGroup">${spring:spring.application.group}</Property>
</Properties>
----

NOTE: The lookup key should be specified in kebab case (such as `my.property-name`).



[[features.logging.log4j2-extensions.environment-property-source]]
=== Log4j2 System Properties

Log4j2 supports a number of https://logging.apache.org/log4j/2.x/manual/systemproperties.html[System Properties] that can be used to configure various items.
For example, the `log4j2.skipJansi` system property can be used to configure if the javadoc:org.apache.logging.log4j.core.appender.ConsoleAppender[] will try to use a https://github.com/fusesource/jansi[Jansi] output stream on Windows.

All system properties that are loaded after the Log4j2 initialization can be obtained from the Spring javadoc:org.springframework.core.env.Environment[].
For example, you could add `log4j2.skipJansi=false` to your `application.properties` file to have the javadoc:org.apache.logging.log4j.core.appender.ConsoleAppender[] use Jansi on Windows.

NOTE: The Spring javadoc:org.springframework.core.env.Environment[] is only considered when system properties and OS environment variables do not contain the value being loaded.

WARNING: System properties that are loaded during early Log4j2 initialization cannot reference the Spring javadoc:org.springframework.core.env.Environment[].
For example, the property Log4j2 uses to allow the default Log4j2 implementation to be chosen is used before the Spring Environment is available.
