Spring Boot 3.4 结构化日志记录


Spring Boot 3.4 中定义明确、通常机器可读的日志记录格式:支持常见的结构化格式,并且可自定义。

日志记录是应用程序故障排除中长期存在的一部分,也是可观察性的三大支柱之一,仅次于指标和跟踪。没有人喜欢在生产中盲目行事,当事件发生时,开发人员很乐意有日志文件。日志通常以人类可读的格式写出。

结构化日志记录是一种以明确定义且通常为机器可读的格式编写日志输出的技术。此格式可以输入到日志管理系统中,并实现强大的搜索和分析功能。结构化日志记录最常用的格式之一是 JSON。

Spring Boot 3.4 开箱即用地支持结构化日志记录。它支持Elastic Common Schema (ECS)Logstash格式,但也可以使用您自己的格式进行扩展。


在start.spring.io上创建一个新项目。您不需要添加任何依赖项,但请确保至少选择 Spring Boot 3.4.0-M2。

要在控制台上启用结构化日志记录,请将其添加到application.properties:

logging.structured.format.console=ecs

这将指示 Spring Boot 以 Elastic Common Schema (ECS) 格式登录。

现在启动应用程序,您将看到日志采用 JSON 格式:

{"@timestamp":"2024-07-30T08:41:10.561295200Z","log.level":"INFO","process.pid":67455,"process.thread.name":"main","service.name":"structured-logging-demo","log.logger":"com.example.structured_logging_demo.StructuredLoggingDemoApplication","message":"Started StructuredLoggingDemoApplication in 0.329 seconds (process running for 0.486)","ecs.version":"8.11"}

结构化记录到文件
您还可以启用将结构化日志记录到文件的功能。例如,这可用于在控制台上打印人性化日志,并将结构化日志写入文件以供机器提取。

要启用该功能,请将其添加到您的设置application.properties并确保删除该logging.structured.format.console=ecs设置:

logging.structured.format.file=ecs
logging.file.name=log.json

现在启动您的应用程序,您将看到控制台上有一个人类可读的日志,并且该文件log.json包含机器可读的 JSON 内容。

添加其他字段
结构化日志记录的一个强大功能是开发人员可以以结构化的方式向日志事件添加信息。例如,您可以将用户 ID 添加到每个日志事件,然后根据该 ID 进行过滤以查看此特定用户执行了哪些操作。

Elastic Common Schema 和 Logstash 均在 JSON 中包含映射诊断上下文的内容。为了实际操作,让我们创建自己的日志消息:

@Component
class MyLogger implements CommandLineRunner {
    private static final Logger LOGGER = LoggerFactory.getLogger(MyLogger.class);

    @Override
    public void run(String... args) {
        MDC.put("userId", "1");
        LOGGER.info(
"Hello structured logging!");
        MDC.remove(
"userId");
    }
}

在记录日志消息之前,此代码还会在 MDC 中设置用户 ID。Spring Boot 会自动将用户 ID 包含在 JSON 中:

{ ... ,"message":"Hello structured logging!","userId":"1" ... }

您还可以使用流畅的日志记录 API来添加其他字段,而无需依赖 MDC:

@Component
class MyLogger implements CommandLineRunner {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyLogger.class);

    @Override
    public void run(String... args) {
        LOGGER.atInfo().setMessage("Hello structured logging!").addKeyValue("userId", "1").log();
    }

}

Elastic Common Schema定义了很多字段名,Spring Boot 内置了对服务名称、服务版本、服务环境和节点名称的支持。要设置这些字段的值,你可以在 中使用以下内容application.properties:

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

查看 JSON 输出时,现在有service.name、service.version和service.environment字段service.node.name。这样,您现在可以在日志系统中根据节点名称、服务版本等进行筛选。

自定义日志格式等更多点击标题