Scala akka是否将MDC从源参与者复制到其他参与者和未来?

Scala akka是否将MDC从源参与者复制到其他参与者和未来?,scala,akka,slf4j,actor,mdc,Scala,Akka,Slf4j,Actor,Mdc,正如我在akka规范中所读到的,它是在演员中出现的。例如,我可以将unic信息放在mdc中,然后在actor中使用它。但是呢?akka是否提供了任何保证,即在actor中启动的未来将具有相同的mdc?另外,发送给其他参与者的消息呢?默认情况下是否复制了MDC 注 对我来说,这看起来很奇怪,我只能在一个参与者代码中使用MDC。他们可以,但实际上他们没有。当您调用LoggingAdapter的成员时,实际上是调用actor的成员: package akka.event trait LoggingAd

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


对我来说,这看起来很奇怪,我只能在一个参与者代码中使用MDC。

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

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))
  ...
}
所以你在这里访问演员的成员。每次处理请求之前都会设置此成员:

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()
  }
}
因此,如果您将来从另一个线程访问它,该线程可能会与其他消息同时运行,那么不能保证您为消息选择mdc。和receiver的问题相同,但更严重的是,您无法通过简单的方式捕获额外的mdc信息

p.S.Akka可以更聪明,以隐式方式获取mdc信息,因此您可以将其捕获为一个闭包,类似这样:

  implicit val metaMdc = getMetaMdc
  Future {

    log.warning(...)
  }

这里的问题是Akka必须在每次登录时将此metaMdc附加到当前线程的mdc,或者必须像SLF4J的mdc那样对其进行初始化,因此每个线程的情况都不同。因此,Akka不知道要用哪个物理MDC来执行日志。警告…

他们可以,但实际上他们不知道。当您调用LoggingAdapter的成员时,实际上是调用actor的成员:

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))
  ...
}
所以你在这里访问演员的成员。每次处理请求之前都会设置此成员:

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()
  }
}
因此,如果您将来从另一个线程访问它,该线程可能会与其他消息同时运行,那么不能保证您为消息选择mdc。和receiver的问题相同,但更严重的是,您无法通过简单的方式捕获额外的mdc信息

p.S.Akka可以更聪明,以隐式方式获取mdc信息,因此您可以将其捕获为一个闭包,类似这样:

  implicit val metaMdc = getMetaMdc
  Future {

    log.warning(...)
  }
这里的问题是Akka必须在每次登录时将此metaMdc附加到当前线程的mdc,或者必须像SLF4J的mdc那样对其进行初始化,因此每个线程的情况都不同。所以Akka不知道你要用哪个物理MDC来执行日志。警告