akka是否将MDC从源角色复制到其他演员和期货?

时间:2015-07-06 03:48:39

标签: scala akka slf4j actor mdc

当我在akka规范中读到演员中的supports mdc时。例如。我可以在mdc中输入unic信息然后在actor中使用它。但是futures呢? akka是否提供任何保证,在演员中启动的未来将具有相同的mdc?另外,发送给其他参与者的消息是默认情况下是否复制了MDC?

注意

对我来说,看起来很奇怪,我只能在一个演员代码中使用MDC。

1 个答案:

答案 0 :(得分:3)

他们可以,但他们实际上没有。当您调用LoggingAdapter的成员时,您实际上调用了actor的成员:

app.api.listen

所以你在这里访问演员的成员。每次处理请求之前都会设置此成员:

package akka.event
trait LoggingAdapter {// and it's implementations DagnosticLoggingAdapter, BusLoggingAdapter

  type MDC = Logging.MDC
  def mdc = Logging.emptyMDC
  def notifyError(message: String): Unit = bus.publish(Error(logSource, logClass, message, mdc))
  ...
}

因此,如果您将来访问它(另一个可能与其他消息同时运行的线程) - 无法保证您为您的消息选择mdc。与接收器相同的问题,但更深入,因为你无法轻松捕获额外的mdc信息。

P.S。 Akka可能更聪明,并且获取mdc信息是隐式的,所以你可以将它捕获为闭包,类似的东西:

package akka.actor
trait DiagnosticActorLogging extends Actor {
  ...

  override protected[akka] def aroundReceive(receive: Actor.Receive, msg: Any): Unit = try {
    log.mdc(mdc(msg))
    super.aroundReceive(receive, msg)
  } finally {
    log.clearMDC()
  }
}

这里的问题是Akka必须在每次登录时将这个metaMdc附加到当前线程的mdc(或者你必须以某种方式初始化它),因为SLF4J的Mdc是thread-local,所以每个线程都不同。所以,Akka不知道您将使用哪个物理MDC执行 implicit val metaMdc = getMetaMdc Future { log.warning(...) }