Google cloud dataflow 如何在apache beam和dataflow中设置logback MDC?

Google cloud dataflow 如何在apache beam和dataflow中设置logback MDC?,google-cloud-dataflow,apache-beam,logback,slf4j,Google Cloud Dataflow,Apache Beam,Logback,Slf4j,我们正在使用ApacheBeam,希望设置logback MDC。logback MDC是一个很好的资源,当您收到一个请求并存储一个用户ID(在我们的例子中,它是custId、fileId、requestId)时,那么每当开发人员登录时,它就会神奇地将该信息标记到开发人员日志中。开发人员不再忘记在每次添加日志语句时添加它 我从一个端到端的集成类型测试开始,该测试将apache beam direct runner嵌入到我们的微服务中进行测试(在生产中,微服务调用数据流)。目前,我看到在调用exp

我们正在使用ApacheBeam,希望设置logback MDC。logback MDC是一个很好的资源,当您收到一个请求并存储一个用户ID(在我们的例子中,它是custId、fileId、requestId)时,那么每当开发人员登录时,它就会神奇地将该信息标记到开发人员日志中。开发人员不再忘记在每次添加日志语句时添加它

我从一个端到端的集成类型测试开始,该测试将apache beam direct runner嵌入到我们的微服务中进行测试(在生产中,微服务调用数据流)。目前,我看到在调用expand()方法之前,MDC是良好的。一旦调用了processElement方法,上下文当然就消失了,因为我在另一个线程中

所以,试着先修复这一块。我应该把这个上下文放在哪里,这样我就可以在这个线程的开头恢复它

例如,如果我有一个Executor.execute(runnable),那么我只需像这样使用该runnable传输上下文

    public class MDCContextRunnable implements Runnable {
    private final Map<String, String> mdcSnapshot;
    private Runnable runnable;

    public MDCContextRunnable(Runnable runnable) {
        this.runnable = runnable;
        mdcSnapshot = MDC.getCopyOfContextMap();
    }


    @Override
    public void run() {
        try {
            MDC.setContextMap(mdcSnapshot);

            runnable.run();
            
        } Catch {
            //Must log errors before mdc is cleared
            log.error("message", e);.  /// Logs error and MDC
        } finally {
            MDC.clear();
        }

    }
}
公共类MDCContextRunnable实现Runnable{
私人最终地图mdcSnapshot;
私人可运行;
公共MDCContextRunnable(Runnable-Runnable){
this.runnable=runnable;
mdcSnapshot=MDC.getCopyOfContextMap();
}
@凌驾
公开募捐{
试一试{
setContextMap(mdcSnapshot);
runnable.run();
}抓住{
//必须在清除mdc之前记录错误
log.error(“message”,e);.///记录错误和MDC
}最后{
MDC.clear();
}
}
}
所以我需要对ApacheBeam基本上做同样的事情。我需要

  • 抓住MDC的关键点
  • 有必要恢复MDC
  • 有必要清除MDC,以防止它泄漏到另一个请求中(真的是为了防止我错过了一些时不时发生的事情)
  • 有什么办法吗

    哦,如果框架记录了任何异常,MDC可以在那里,那就有额外的积分了!!!!(也就是说,理想情况下,框架应该能为您做到这一点,但apache beam似乎没有做到这一点。大多数web框架都内置了这一点)

    谢谢,
    Dean

    根据您给出的上下文和示例,听起来您希望使用MDC为自己的DOFN自动捕获更多信息。这方面的最佳选择是,根据您需要上下文可用的生命周期,在DOFN上使用
    开始绑定
    /
    完成绑定
    设置
    /
    拆卸
    方法来创建MDC上下文(请参阅以了解两者之间的差异)。重要的是,这些方法是针对DoFn的每个实例执行的,这意味着它们将在为执行这些DoFn而创建的新线程上被调用

    幕后 我应该解释一下这里发生了什么,以及这种方法与您最初的目标有何不同。ApacheBeam的执行方式是,您编写的管道在自己的机器上执行,并执行管道构造(所有扩展调用都发生在这里)。但是,一旦构建了管道,它就会被发送到一个运行程序,除非它是直接运行程序,否则它通常在单独的应用程序上执行,然后运行程序要么直接执行您的用户代码,要么在docker环境中运行它

    在最初的方法中,您可以成功地将MDC应用于所有日志,直到执行开始,因为执行可能不仅发生在不同的线程中,还可能发生在不同的应用程序或计算机中。但是,上面描述的方法是作为用户代码的一部分执行的,因此在那里设置MDC将允许它在执行转换的任何线程/应用程序/机器上运行

    请记住,这些方法会为每个DoFn调用,并且每个线程通常会有多个DoFn,这可能需要注意,这取决于MDC的工作方式