首页 > 解决方案 > 将线程本地 MDC 值传递给 Scala 中的线程池任务

问题描述

在我们的系统中,我们的记录器依靠 MDC 来传递信息。只要您没有跨线程逻辑溢出的用例,那很好,但不幸的是,这就是现代软件开发的现实。

我想出了以下解决方案,我们希望可以将其用作全局线程池的包装器(Logger / MDC 方法是虚构的,仅用于说明目的):

class MDCAwareExecutionContext(ec: ExecutionContext) extends ExecutionContext {
  override def execute(runnable: Runnable): Unit = {
    val mdc: java.util.Map[_, _] = Logger.getMDCValues()
    ec.execute(() =>
      Logger.clearMDCValues()
      Logger.setMDCValues(mdc)
      runnable.run()
    )
  }

  override def reportFailure(cause: Throwable): Unit =
    ec.reportFailure(cause)
}

但我的同事提到,他过去曾尝试过类似的方法,但通过经验经验,它不起作用。相反,他提出了一个替代方案,它基于ExecutionContext.prepare()声明为已弃用。我没有理由认为他错了,但另一方面,我不明白我的例子中可能出现的问题。

是否有某些原因导致这在 Scala 中无法按预期工作?我假设在未来之外我们仍然可以正确捕获 MDC,并且在未来内部我们已经处于任意线程中,但始终可以安全地读取originalMdc变量。我错过了一些模糊的可能性吗?

标签: scalaconcurrencyfuturethread-localmdc

解决方案


推荐阅读