今天一起学习下 Spring Boot 3.4 中最受关注的功能:结构化日志记录。

为什么结构化日志记录很重要?

通过利用结构化日志记录,我们可以有效地捕获和组织日志信息,从而更轻松地使用其他工具进行解析和分析。这种方法不仅增强了人类日志的可读性,还简化了聚合和搜索日志数据的过程,最终实现更高效的调试和监控应用程序。

Spring Boot 3.4 引入了对结构化日志记录的内置支持,并且开箱即用地支持以下 JSON 格式:

  • Elastic Common Schema
  • Graylog
  • Logstash

如何在 Spring Boot 3.4 中启用结构化日志记录

根据您的要求(文件或控制台输出),我们可以通过将这些属性设置为您要使用的格式(ecs、gelf 或 logstash)的 id 来启用结构化日志记录:

  • logging.structured.format.console (用于控制台输出)
  • logging.structured.format.file (用于文件输出)

看看实践中会发生什么

如果使用 Spring Initializr 创建新的 Spring Boot 3.4 应用程序,则默认的日志记录格式将类似于:

d2b5ca33bd20241219134409

使用 Elastic Common Schema (ECS) 格式

要使用 Elastic Common Schema 日志格式,我们将 logging.structured.format.console 属性设置为 ecs:

d2b5ca33bd20241219135921

日志格式将类似于以下内容,基于 Elastic Common Schema,这是一种基于 JSON 的日志记录格式:

d2b5ca33bd20241219140136

使用 Graylog 扩展日志格式 (GELF)

与 Elastic Common Schema 类似,要使用 Graylog 扩展日志格式,我们将 logging.structured.format.console 属性设置为 gelf:

d2b5ca33bd20241219140155

使用 Logstash JSON 格式

Logstash JSON 格式是 Spring Boot 3.4 支持开箱即用的基于 JSON 的结构化日志记录格式通过将 logging.structured.format.console 属性设置为 logstash,我们可以启用此日志格式。

d2b5ca33bd20241219140217

实现自定义格式

除了在 Spring Boot 3.4 中支持开箱即用的这 3 种 JSON 格式外,我们还可以通过实现 StructuredLogFormatter 接口来实现自定义结构化日志记录格式,具体取决于您使用的日志记录系统,事件对象将提供(Logback 的 ILoggingEvent 和 Log4j2 的 LogEvent):

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";
 }

}

其他

对于文件输出,我们应该改用 logging.structured.format.file property 。

对于这 3 种格式中的每一种,我们都可以使用相关属性自定义 service.name 和版本。Elastic Common Schema 提供了另外两个用于自定义的属性(environment 和 node-name)。

logging.structured.{format_id}.service.name=MyService
logging.structured.{format_id}.service.version=1

所有 3 种格式都会将 MDC 中包含的每个键值对添加到 JSON 对象中。

Spring Boot 提供了一些用于自定义和证明 JSON 结果的属性,例如更改某些名称或过滤掉 JSON 输出中的某些成员(查看官方文档)。

logging.structured.json.exclude=log.level
logging.structured.json.rename.process.id=procid
logging.structured.json.add.corpname=mycorp

总结

通过以一致的机器可读格式提供日志来支持 Spring Boot 3.4 中的结构化日志记录,这是朝着简化与日志聚合工具的集成迈出的一大步,并允许在每个日志条目中嵌入丰富的上下文。

— 感谢阅读 —
广告

一起交流

分享你的思考,让讨论更进一步。