Spring 启动日志记录和 Google 云平台日志查看器

Spring Boot Logging and Google Cloud Platform Log Viewer

我是 运行 Spring 在 Google Cloud Platform 中启动应用程序并通过 Google Platform Logs Viewer 查看日志文件。在使用 Spring 引导并仅使用简单的 servlet 之前,日志条目将显示为:

每个请求都将被分组,并且可以通过展开行来查看该请求的所有日志记录信息。但是,当使用 Spring Boot 时,请求不再分组,日志条目只是逐行显示。当有多个请求时,日志条目会变得非常混乱,因为无法以分组方式查看它们。我以同样的方式设置 logging.properties:

.level = INFO
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n

Logger 在每个 class 中被初始化为:

private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(MyClass.class.getName());

然后日志记录 API 用作: LOG.info("My Message");

我不明白为什么语句以不同的方式记录并且不再分组,但它一定与 Spring 引导处理日志记录的方式有关?

自最近的运行时以来,AppEngine 的行为越来越多地与基于容器的方法融合,更多 "opened" 作为新的其他产品(如 Cloud 运行 for例子)。

这稍微改变了我们使用 GAE 进行开发的方式,特定的遗留库不可用(SearchAPI...),并且它还改变了日志的管理方式。

我们可以使用新的 java11 运行时重现此“嵌套日志功能”,但我们需要自己管理它。

official docs所述:

In the Logs Viewer, log entries correlated by the same trace can be viewed in a "parent-child" format.

这意味着,如果我们检索在我们请求的 X-Cloud-Trace-Context HTTP header 中收到的 trace 标识符,我们就可以使用它来添加一个新的 LogEntry将其作为 trace 标识符属性传递。

这可以通过使用 Stackdriver Logging Client libraries

来完成

使用 Spring GCP

幸运的是,Spring Cloud GCP 可以让我们的生活更轻松。

您可以找到实现它的 sample project。请注意,这是一个 AppEngine Flexible 示例,但它可以在 Standard 运行时正常工作。 它使用 Logback.

来自 GAE Java11 上的工作 Spring 启动项目,要遵循的步骤是:

  • 添加spring-cloud-gcp-starter-logging依赖:
<!-- Starter for Stackriver Logging -->   
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-gcp-starter-logging</artifactId>
   <version>1.2.1.RELEASE</version>
</dependency>

  • src/main/resources 文件夹中添加一个 logback-spring.xml :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/cloud/gcp/autoconfigure/logging/logback-appender.xml" />
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

    <root level="INFO">
        <!-- If running in GCP, remove the CONSOLE appender otherwise logs will be duplicated. -->
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="STACKDRIVER" />
    </root>
</configuration>
  • 启用 Spring GCP 日志记录功能,在 src/main/resources/application.properties 内:
spring.cloud.gcp.logging.enabled=true
  • 并在您的代码中使用 LOGGER:
@SpringBootApplication
@RestController
public class DemoApplication {
    private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @GetMapping()
    public SomeData get() {
        LOGGER.info("My info message");
        LOGGER.warn("My warning message");
        LOGGER.error("My error message");

        return new SomeData("Hello from Spring boot !");
    }
}

结果将显示在 Stackdriver Logging 查看器中,对于 appengine.googleapis.com/request_log :