当我在akka规范中读到演员中的supports mdc时。例如。我可以在mdc中输入unic信息然后在actor中使用它。但是futures呢? akka是否提供任何保证,在演员中启动的未来将具有相同的mdc?另外,发送给其他参与者的消息是默认情况下是否复制了MDC?
注意
对我来说,看起来很奇怪,我只能在一个演员代码中使用MDC。
答案 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(...)
}
。