在使用Akka Typed时,我们可能遇到需要将MDC(Mapped Diagnostic Context)信息添加到Actor日志中的情况。但是,如果子Actor发生异常,它的MDC信息将不会被正确处理。
为了解决这个问题,我们可以在Actor的SupervisorStrategy中重写handleChildTerminated()方法,将子Actor的MDC信息传递给父Actor。
下面是一个示例代码:
class MyActor extends AbstractBehavior[String](context) {
private val log = LoggerFactory.getLogger(classOf[MyActor])
override def onMessage(msg: String): Behavior[String] = {
log.info("Received message: {}", msg)
this
}
override def onSignal: PartialFunction[Signal, Behavior[String]] = {
case PostStop =>
log.info("MyActor stopped")
this
}
}
class ParentActor extends AbstractBehavior[String](context) {
private val log = LoggerFactory.getLogger(classOf[ParentActor])
private val childMdc = new ConcurrentHashMap[String, String]()
override def onMessage(msg: String): Behavior[String] = {
val childActor = context.spawnAnonymous(MyActor())
context.watch(childActor)
childMdc.put("message", msg)
Behaviors.supervise(childActor)
.onFailure[Exception](SupervisorStrategy.restartWithBackoff(
minBackoff = 3.seconds,
maxBackoff = 30.seconds,
randomFactor = 0.2
).withLogger(new ChildFailedLogger(childMdc, log)))
.asInstanceOf[Behavior[String]]
}
override def onSignal: PartialFunction[Signal, Behavior[String]] = {
case PostStop =>
log.info("ParentActor stopped")
this
}
}
class ChildFailedLogger(childMdc: ConcurrentHashMap[String, String], log: Logger) extends Logger {
override def getName: String = log.getName
override def isTraceEnabled: Boolean = log.isTraceEnabled
override def trace(msg: String): Unit = log.trace(msg)
override def trace(format: String, arg: Any): Unit = log.trace(format, arg)
override
上一篇:Akka图形与消息限流