【问题标题】:How to override Google DataFlow logging with logback?如何使用 logback 覆盖 Google DataFlow 日志记录?
【发布时间】:2022-12-23 02:22:17
【问题描述】:

我们在 Google Cloud 中部署了 DataFlows。数据流是使用 Apache Beam 开发的。

数据流日志记录不包括跟踪管道中的事务所需的事务 ID。

Google Cloud 忽略了 logback 中使用的任何日志记录模式。

我们如何在 Google Cloud 日志记录中捕获跟踪 ID?

logback.xml

<configuration >
<property name="projectId" value="${projectId:-${GOOGLE_CLOUD_PROJECT}}"/>
<appender name="CONSOLE_JSON" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="org.springframework.cloud.gcp.logging.StackdriverJsonLayout">
            <projectId>${projectId}</projectId>
            <includeTraceId>true</includeTraceId>
            <includeSpanId>true</includeSpanId>
            <includeLevel>true</includeLevel>
            <includeThreadName>true</includeThreadName>
            <includeMDC>true</includeMDC>
            <includeLoggerName>true</includeLoggerName>
            <includeFormattedMessage>true</includeFormattedMessage>
            <includeExceptionInMessage>true</includeExceptionInMessage>
            <includeContextName>true</includeContextName>
            <includeMessage>false</includeMessage>
            <includeException>false</includeException>
        </layout>
    </encoder>
</appender>

<root level="INFO">
    <appender-ref ref="CONSOLE_JSON"/>
</root>
</configuration>

Java:
     MDC.put("traceId", "12345");
     log.info("Logging from test class");


Google Cloud:

jsonPayload: {
  job: "2022-09-08_19_05_07-12432432432"
  logger: "TestLogger"
  message: "Logging from test class"
  stage: "A1"
  step: "Test Step"
  thread: "49"
  work: "3243243"
  worker: "test-worker"
}

【问题讨论】:

    标签: google-cloud-dataflow apache-beam logback


    【解决方案1】:

    Dataflow 依赖于使用 java.util.logging(又名 JUL)作为 SLF4J 的日志记录后端,并添加各种桥接以确保也输出来自其他库的日志。使用这种设置,我们仅限于向日志消息本身添加任何其他详细信息。

    这也适用于任何执行可移植作业的运行器,因为带有 SDK 工具的容器具有类似的日志记录配置。例如 Dataflow Runner V2。

    为此,我们要创建一个自定义格式化程序以应用于根 JUL 记录器。例如:

    public class CustomFormatter extends SimpleFormatter {
      public String formatMessage(LogRecord record) {
        // implement whatever logic the is needed to add details to the message portion of the log statement
        return super.formatMessage(record);
      }
    }
    

    然后在 worker 启动期间,我们需要更新根记录器以使用此格式化程序。我们可以使用 JvmInitializer 实现这一点,并像这样实现 beforeProcessing 方法:

    @AutoService(JvmInitializer.class)
    public class LoggerInitializer implements JvmInitializer {
      public void beforeProcessing(PipelineOptions options) {
        LogManager logManager = LogManager.getLogManager();
        Logger rootLogger = logManager.getLogger("");
        for (Handler handler : rootLogger.getHandlers()) {
          handler.setFormatter(new CustomFormatter());
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 2012-01-12
      • 2014-10-25
      • 2016-04-27
      • 2015-01-09
      • 2014-03-17
      • 2022-01-27
      • 1970-01-01
      • 2017-05-06
      相关资源
      最近更新 更多