18

我们一直很难在 Play 2.0.4 应用程序中检测和调查 Akka Actor 中的错误。

如何使用有用的堆栈跟踪记录 Akka Actor 中所有未捕获的异常?

到目前为止,我们能做的最好的事情是将以下内容添加到application.conf

logger.akka=DEBUG

akka {
    loglevel = DEBUG
    stdout-loglevel = DEBUG
    loggers = ["akka.event.slf4j.Slf4jLogger"]
    actor {
        debug {
            receive = on
            autoreceive = on
            fsm = on
            lifecycle = on
            unhandled = on
            event-stream = on
            router-misconfiguration = on
        }
    }
}

但是,鉴于以下演员:

class ThrowingActor{
  def receive = {
    case _ => {
      throw new Exception("--------------ASDFASDFASDFASDFASDFASDFASDF------------------")
    }
  }
}

我们看到的所有记录是:

[DEBUG] [03/06/2013 16:15:44.311] [application-akka.actor.default-dispatcher-16] [Future] --------------ASDFASDFASDFASDFASDFASDFASDF------------------

当有未捕获的异常时,任何人都可以帮助我们获取所有参与者的信息堆栈跟踪吗?

谢谢。

4

2 回答 2

7

如果您无法在 Akka 中找到开箱即用的处理方式,那么您可以创建一个简单的特征来混合到您的演员中,如下所示:

import akka.actor._

trait UnhandledExceptionLogging{
  self: Actor with ActorLogging =>

  override def preRestart(reason:Throwable, message:Option[Any]){
    super.preRestart(reason, message)
    log.error(reason, "Unhandled exception for message: {}", message)
  }
}

class MyActor extends Actor with ActorLogging with UnhandledExceptionLogging{
  def receive = {
    case _ =>
      throw new Exception("blah blah")
  }
}

当发生未捕获的异常并且actor即将重新启动时,将调用预重新启动。似乎是一个挂钩到您自己的更详细日志记录的好地方。作为奖励,收到的导致失败的消息可用于日志中的其他上下文。

您还可以稍微重构此代码以将特征设置为可堆叠,以防您有其他演员已经被覆盖preRestart

于 2013-04-23T18:53:23.790 回答
0

当您使用 slf4j 记录器时,不再使用 Akka 的日志记录配置。根据您的日志记录框架和设置,您可能必须:

  • 更改 logback.xml、logback.groovy 或 logback-test.xml
  • 更改 log4j.xml 或 log4j.properties
  • 在你的类路径上添加一个 logback 或 log4j jar

通常,当系统启动时,它会打印一些有关日志框架的详细信息(特别是如果它配置错误)。可能有很多原因,但您很可能查看了错误的配置文件。

于 2013-03-12T10:41:36.060 回答