# 7.4.日志记录

Spring Boot 使用[Commons Logging](https://commons.apache.org/logging)进行所有内部日志记录，但对底层日志实现打开。为[Java Util Logging](https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html)、[Log4J2](https://logging.apache.org/log4j/2.x/)和[Logback](https://logback.qos.ch/)提供了默认配置。在每种情况下，记录器都预先配置为使用控制台输出，并且还提供可选的文件输出。

默认情况下，如果您使用“Starters”，则使用 Logback 进行日志记录。还包括适当的 Logback 路由，以确保使用 Java Util Logging、Commons Logging、Log4J 或 SLF4J 的依赖库都能正常工作。 有很多可用于 Java 的日志记录框架。如果上面的列表看起来令人困惑，请不要担心。通常，您不需要更改日志记录依赖项，Spring Boot 默认值就可以正常工作。 当您将应用程序部署到 servlet 容器或应用程序服务器时，使用 Java Util Logging API 执行的日志记录不会路由到应用程序的日志中。这可以防止容器或已部署到它的其他应用程序执行的日志记录出现在应用程序的日志中。

#### 7.4.1日志格式

Spring Boot 的默认日志输出类似于以下示例：

```
2023-06-22T12:08:05.861Z  INFO 22768 --- [           main] o.s.b.d.f.s.MyApplication                : Starting MyApplication using Java 17.0.7 with PID 22768 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2023-06-22T12:08:05.872Z  INFO 22768 --- [           main] o.s.b.d.f.s.MyApplication                : No active profile set, falling back to 1 default profile: "default"
2023-06-22T12:08:09.854Z  INFO 22768 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-06-22T12:08:09.892Z  INFO 22768 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-06-22T12:08:09.892Z  INFO 22768 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.10]
2023-06-22T12:08:10.160Z  INFO 22768 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-06-22T12:08:10.162Z  INFO 22768 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4038 ms
2023-06-22T12:08:11.512Z  INFO 22768 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-22T12:08:11.534Z  INFO 22768 --- [           main] o.s.b.d.f.s.MyApplication                : Started MyApplication in 7.251 seconds (process running for 8.584)
```

输出以下内容：

* 日期和时间：毫秒精度，易于排序。
* 日志级别：`ERROR`、`WARN`、`INFO`、`DEBUG`或`TRACE`。
* 进程标识。
* `---`用于区分实际日志消息开始的分隔符。
* 线程名称：括在方括号中（可能会被截断以用于控制台输出）。
* 记录器名称：这通常是源类名称（通常缩写）。
* 日志消息。

> Logback 没有`FATAL`级别。它被映射到`ERROR`上。

#### 7.4.2. 控制台输出

默认日志配置在写入时将消息回显到控制台。默认情况下，会记录`ERROR`、`WARN`和`INFO`级别消息。您还可以通过使用`--debug`标志启动应用程序来启用“调试”模式。

```shell
$ java -jar myapp.jar --debug
```

你也可以在你的`application.properties`配置`debug=true`.

启用调试模式后，会配置一系列核心记录器（嵌入式容器、Hibernate 和 Spring Boot）以输出更多信息。启用调试模式不会*将*您的应用程序配置为记录所有`DEBUG`级别的消息。

或者，您可以通过使用`--trace`标志或在您的`application.properties`配置`trace=true`. 这样做可以为选择的核心记录器（嵌入式容器、Hibernate 模式生成和整个 Spring 产品组合）启用跟踪日志记录。

7.**4.2.1. 颜色编码输出**

如果您的终端支持 ANSI，则可以使用颜色输出来提高可读性。您可以设置`spring.output.ansi.enabled`为[支持的值](https://docs.spring.io/spring-boot/docs/2.7.3/api/org/springframework/boot/ansi/AnsiOutput.Enabled.html)以覆盖自动检测配置。

使用`%clr`转换字配置颜色编码。在最简单的形式中，转换器根据日志级别为输出着色，如以下示例所示：

```
%clr(%5p)
```

下表描述了日志级别到颜色的映射：

| 等级      | 颜色  |
| ------- | --- |
| `FATAL` | 红色的 |
| `ERROR` | 红色的 |
| `WARN`  | 黄色  |
| `INFO`  | 绿色的 |
| `DEBUG` | 绿色的 |
| `TRACE` | 绿色的 |

或者，您可以通过将其作为转换选项提供来指定应使用的颜色或样式。例如，要将文本变为黄色，请使用以下设置：

```
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
```

支持以下颜色和样式：

* `blue`
* `cyan`
* `faint`
* `green`
* `magenta`
* `red`
* `yellow`

#### 7.4.3. 文件输出

默认情况下，Spring Boot 仅打印日志到控制台，不写入日志文件。如果您想在控制台输出之外写入日志文件，您需要设置一个`logging.file.name`或者`logging.file.path`属性（例如，在您的`application.properties`中）.

下表显示了如何`logging.*`一起使用这些属性：

| `logging.file.name` | `logging.file.path` | 例子         | 描述                                            |
| ------------------- | ------------------- | ---------- | --------------------------------------------- |
| *（无）*               | *（无）*               |            | 仅控制台日志记录。                                     |
| 具体文件                | *（无）*               | `my.log`   | 写入指定的日志文件。名称可以是确切的位置，也可以是相对于当前目录的位置。          |
| *（无）*               | 具体目录                | `/var/log` | 写入`spring.log`指定目录。名称可以是确切的位置，也可以是相对于当前目录的位置。 |

日志文件在达到 10 MB 时会轮换，并且与控制台输出一样，默认情况下会记录`ERROR`、`WARN`和`INFO`消息。

> 日志记录属性独立于实际的日志记录基础设施。因此，特定的配置键（例如 Logback的`logback.configurationFile`）不由 spring Boot 管理。

#### 7.4.4. 文件轮换

如果您使用的是 Logback，则可以使用您的`application.properties`或`application.yaml`文件微调日志轮换设置。对于所有其他日志记录系统，您需要自己直接配置轮换设置（例如，如果您使用 Log4J2，那么您可以添加一个`log4j2.xml`或`log4j2-spring.xml`文件）。

支持以下轮换策略属性：

| 姓名                                                     | 描述                      |
| ------------------------------------------------------ | ----------------------- |
| `logging.logback.rollingpolicy.file-name-pattern`      | 用于创建日志存档的文件名模式。         |
| `logging.logback.rollingpolicy.clean-history-on-start` | 如果应在应用程序启动时进行日志归档清理。    |
| `logging.logback.rollingpolicy.max-file-size`          | 归档前日志文件的最大大小。           |
| `logging.logback.rollingpolicy.total-size-cap`         | 在被删除之前可以占用的最大大小的日志档案。   |
| `logging.logback.rollingpolicy.max-history`            | 要保留的存档日志文件的最大数量（默认为 7）。 |

#### 7.4.5. 日志级别

所有受支持的日志记录系统都可以通过`logging.level.<logger-name>=<level>`使用 TRACE、DEBUG、INFO、WARN、ERROR、FATAL 或 OFF `level`之一在 Spring `Environment`中设置记录器级别（例如在 `application.properties`中）。 `root`记录器可以使用`logging.level.root`设置.

以下示例显示了潜在的日志记录设置`application.properties`：

```properties
logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
```

也可以使用环境变量设置日志记录级别。例如，`LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG`将设置`org.springframework.web`为`DEBUG`。 上述方法仅适用于包级别的日志记录。由于宽松绑定总是将环境变量转换为小写，因此无法以这种方式为单个类配置日志记录。如果需要为类配置日志记录，可以使用[`SPRING_APPLICATION_JSON`](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.application-json)变量。

#### 7.4.6. 日志组

能够将相关的记录器组合在一起通常很有用，以便可以同时配置它们。例如，您可能通常会更改*所有*与 Tomcat 相关的记录器的日志记录级别，但您不容易记住顶级包。

为了解决这个问题，Spring Boot 允许您在 Spring `Environment`中定义日志记录组。例如，您可以通过以下方式定义“tomcat”组，方法是将其添加到您的`application.properties`:

```properties
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
```

定义后，您可以使用一行更改组中所有记录器的级别：

```properties
logging.level.tomcat=trace
```

Spring Boot 包括以下可开箱即用的预定义日志记录组：

| 名称  | 日志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`,`org.jooq.tools.LoggerListener`                                                                                                                           |

#### 7.4.7. 使用日志关闭挂钩

为了在您的应用程序终止时释放日志资源，提供了一个关闭挂钩，该挂钩将在 JVM 退出时触发日志系统清理。除非您的应用程序部署为 war 文件，否则此关闭挂钩会自动注册。如果您的应用程序具有复杂的上下文层次结构，则关闭挂钩可能无法满足您的需求。如果没有，请禁用关闭挂钩并调查底层日志系统直接提供的选项。例如，Logback 提供[上下文选择器](https://logback.qos.ch/manual/loggingSeparation.html)，允许每个 Logger 在其自己的上下文中创建。您可以使用`logging.register-shutdown-hook`属性来禁用关闭挂钩。将其设置为`false`将禁用注册。您可以在`application.properties`或者`application.yaml`文件中设置属性：

```properties
logging.register-shutdown-hook=false
```

#### 7.4.8. 自定义日志配置

各种日志系统可以通过在类路径中包含适当的库来激活，并且可以通过在类路径的根目录或由以下 Spring`Environment`属性指定的位置提供合适的配置文件来进一步定制：`logging.config`

您可以使用system 属性`org.springframework.boot.logging.LoggingSystem`强制 Spring Boot 使用特定的日志记录系统。该值应该是实现的完全限定类名`LoggingSystem`。您还可以使用`none`.

由于在创建`ApplicationContext`**之前** 初始化了日志记录，因此无法从Spring`@Configuration`文件中使用`@PropertySources`控制日志记录。更改日志系统或完全禁用它的唯一方法是通过系统属性。 根据您的日志记录系统，将加载以下文件：

| 对应日志框架             | 定制                                                                              |
| ------------------ | ------------------------------------------------------------------------------- |
| logback            | `logback-spring.xml`, `logback-spring.groovy`, `logback.xml`, 或`logback.groovy` |
| log4j2             | `log4j2-spring.xml`或者`log4j2.xml`                                               |
| JDK（Java 实用程序日志记录） | `logging.properties`                                                            |

> 如果可能，我们建议您为日志配置使用`-spring`变体（例如，`logback-spring.xml`而不是`logback.xml`）。如果使用标准配置位置，Spring 无法完全控制日志初始化。
>
> Java Util Logging 存在已知的类加载问题，这些问题在从“可执行 jar”运行时会导致问题。如果可能，我们建议您在从“可执行 jar”运行时避免使用它。

为了帮助进行自定义，一些其他属性从 Spring 转移`Environment`到 System 属性，如下表所述：

| spring属性                            | 系统属性                            | 注释                              |
| ----------------------------------- | ------------------------------- | ------------------------------- |
| `logging.exception-conversion-word` | `LOG_EXCEPTION_CONVERSION_WORD` | 记录异常时使用的转换字。                    |
| `logging.file.name`                 | `LOG_FILE`                      | 如果已定义，它将在默认日志配置中使用。             |
| `logging.file.path`                 | `LOG_PATH`                      | 如果已定义，它将在默认日志配置中使用。             |
| `logging.pattern.console`           | `CONSOLE_LOG_PATTERN`           | 在控制台上使用的日志模式 (stdout)。          |
| `logging.pattern.dateformat`        | `LOG_DATEFORMAT_PATTERN`        | 日志日期格式的附加模式。                    |
| `logging.charset.console`           | `CONSOLE_LOG_CHARSET`           | 用于控制台日志记录的字符集。                  |
| `logging.pattern.file`              | `FILE_LOG_PATTERN`              | 在文件中使用的日志模式（如果`LOG_FILE`启用）。    |
| `logging.charset.file`              | `FILE_LOG_CHARSET`              | 用于文件日志记录的字符集（如果`LOG_FILE`启用）。   |
| `logging.pattern.level`             | `LOG_LEVEL_PATTERN`             | 呈现日志级别时使用的格式（默认`%5p`）。          |
| `PID`                               | `PID`                           | 当前进程 ID（如果可能且尚未定义为 OS 环境变量时发现）。 |

如果使用 Logback，还会传输以下属性：

| spring属性                                               | 系统属性                                           | 注释                                                |
| ------------------------------------------------------ | ---------------------------------------------- | ------------------------------------------------- |
| `logging.logback.rollingpolicy.file-name-pattern`      | `LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN`      | 翻转日志文件名的模式（默认`${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz`）。 |
| `logging.logback.rollingpolicy.clean-history-on-start` | `LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START` | 是否在启动时清理归档日志文件。                                   |
| `logging.logback.rollingpolicy.max-file-size`          | `LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE`          | 最大日志文件大小。                                         |
| `logging.logback.rollingpolicy.total-size-cap`         | `LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP`         | 要保留的日志备份的总大小。                                     |
| `logging.logback.rollingpolicy.max-history`            | `LOGBACK_ROLLINGPOLICY_MAX_HISTORY`            | 要保留的存档日志文件的最大数量。                                  |

所有受支持的日志记录系统在解析其配置文件时都可以查阅系统属性。`spring-boot.jar`有关示例，请参见中的默认配置：

* [logback](https://github.com/spring-projects/spring-boot/tree/v2.7.3/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml)
* [log4j2](https://github.com/spring-projects/spring-boot/tree/v2.7.3/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml)
* [Java 实用程序日志记录](https://github.com/spring-projects/spring-boot/tree/v2.7.3/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties)

> 如果你想在日志属性中使用占位符，你应该使用[Spring Boot 的语法](https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.files.property-placeholders)，而不是底层框架的语法。值得注意的是，如果你使用 Logback，你应该使用`:`作为属性名称和它的默认值之间的分隔符，而不是使用`:-`.
>
> 您可以通过仅覆盖`LOG_LEVEL_PATTERN`（或使用 Logback的`logging.pattern.level`）的方式将 MDC 和其他临时内容添加到日志行。例如，配置为`logging.pattern.level=user:%X{user} %5p`，则默认日志格式包含“用户”的 MDC 条目（如果存在），如以下示例所示。
>
> `2019-08-30 12:30:04.031 user:someone INFO 22174 --- [ nio-8080-exec-0] demo.Controller Handling authenticated request`

#### 7.4.9. Logback 扩展

Spring Boot 包含许多对 Logback 的扩展，可以帮助进行高级配置。您可以在`logback-spring.xml`配置文件中使用这些扩展。

因为标准`logback.xml`配置文件加载得太早，所以不能在里面使用扩展。您需要使用`logback-spring.xml`或定义`logging.config`属性。 扩展不能与 Logback 的[配置扫描](https://logback.qos.ch/manual/configuration.html#autoScan)一起使用。如果您尝试这样做，则对配置文件进行更改会导致记录类似于以下内容之一的错误：

```
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]]
```

7.**4.9.1. 配置文件特定的配置**

`<springProfile>`标签允许您根据活动的 Spring 配置文件选择性地包含或排除配置部分。`<configuration>`元素内的任何位置都支持配置文件部分。使用`name`属性来指定哪个配置文件接受配置。`<springProfile>`标签可以包含配置文件名称（例如`staging`）或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑，例如`production & (eu-central | eu-west)`. 查看[参考指南](https://docs.spring.io/spring-framework/docs/5.3.22/reference/html/core.html#beans-definition-profiles-java)以获取更多详细信息。以下清单显示了三个示例配置文件：

```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>
```

7.**4.9.2. 环境属性**

`<springProperty>`标签允许您公开 Spring `Environment`中的属性以在 Logback 中使用。如果您想在 Logback 配置中访问`application.properties`文件中的值，这样做会很有用。该标签的工作方式与 Logback 的标准`<property>`标签类似。但是，您可以指定属性的 `source`（来自`Environment`） ，而不是直接指定`value`。如果您需要将属性存储在`local`范围以外的某个位置，则可以使用`scope`属性。如果您需要一个备用值（如果该属性未在`Environment` 中设置），您可以使用`defaultValue`属性。以下示例显示了如何公开属性以在 Logback 中使用：

```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>
```

必须在 kebab case中指定`source`（例如`my.property-name`）。但是，可以使用宽松的规则将属性添加到`Environment` 中。

**7.4.10. Log4j2 扩展**

Spring Boot 包含许多对 Log4j2 的扩展，可以帮助进行高级配置。您可以在任何`log4j2-spring.xml`配置文件中使用这些扩展。

> 由于标准的`log4j2.xml`配置文件加载得太早，因此无法在其中使用扩展。您需要使用`log4j2-spring.xml`或定义一个`logging.config`属性。
>
> 这些扩展取代了Log4J 提供的[Spring Boot 支持。](https://logging.apache.org/log4j/2.x/log4j-spring-boot/index.html)您应该确保不要将`org.apache.logging.log4j:log4j-spring-boot`模块包含在您的构建中。

**特定于配置文件的配置**

`<SpringProfile>`标签允许您根据活动的 Spring 配置文件选择包含或排除配置部分。`<Configuration>`元素内的任何位置都支持配置文件部分。使用`name`属性指定哪个配置文件接受配置。`<SpringProfile>`标签可以包含配置文件名称（例如`staging`）或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑，例如`production & (eu-central | eu-west)`。查看[Spring 框架参考指南](https://docs.spring.io/spring-framework/reference/6.1/core/beans/environment.html#beans-definition-profiles-java)以获取更多详细信息。以下清单显示了三个示例配置文件：

```
<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>
```

**环境属性查找**

如果您想在 Log4j2 配置中引用 Spring `Environment`的属性，您可以使用带`spring:`前缀的[查找](https://logging.apache.org/log4j/2.x/manual/lookups.html)。如果您想要访问Log4j2 配置中的`application.properties`文件中的值，那么这样做会很有用。

以下示例显示如何设置`applicationName`的Log4j2 属性，从 Spring `Environment`中读取`spring.application.name`：

```
<Properties>
    <Property name="applicationName">${spring:spring.application.name}</Property>
</Properties>
```

> 查找键应以短横线大小写指定（例如`my.property-name`）。

**Log4j2 系统属性**

Log4j2 支持许多可用于配置各种项目的[系统属性。](https://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties)例如，系统属性`log4j2.skipJansi`可用于配置`ConsoleAppender`是否尝试在 Windows 上使用[Jansi输出流。](https://github.com/fusesource/jansi)

Log4j2 初始化后加载的所有系统属性都可以从 Spring`Environment`获取。例如，您可以添加`log4j2.skipJansi=false`到`application.properties`文件中以便`ConsoleAppender`在 Windows 上使用 Jansi。

> 仅当系统属性和操作系统环境变量不包含正在加载的值时才考虑 Spring `Environment`。
>
> 在早期 Log4j2 初始化期间加载的系统属性无法引用 Spring `Environment`。例如，在 Spring 环境可用之前，使用 Log4j2 属性来允许选择默认的 Log4j2 实现。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.shiker.tech/spring-boot-can-kao-wen-dang/7.-he-xin-te-xing/7.4.-ri-zhi-ji-lu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
