Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to log uncaught exceptions in Akka actors?

We've been having a difficult time detecting and investigating errors in our Akka actors within a Play 2.0.4 application.

How does one get all uncaught exceptions in the Akka actors to be logged with useful stacktraces?

The best we've been able to do thus far is to add the following to 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
        }
    }
}

However, given the following actor:

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

All that we see getting logged is:

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

Can anyone help us get informative stacktraces across all our actors, when there is an uncaught exception?

Thanks.

like image 691
Chris Avatar asked Mar 06 '13 21:03

Chris


1 Answers

If you can't find out of the box handling in Akka, then you can create a simple trait to mix into your actors like so:

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")
  }
}

Pre-restart will be called when an uncaught exception has occurred and the actor is about to be restarted. Seems like a good place to hook into your own more detailed logging. As a bonus, the received message that caused the failure is available for additional context within the log.

You could also refactor this code a little to set up the trait to be stackable in case you have other actors that were already overriding preRestart

like image 95
cmbaxter Avatar answered Nov 01 '22 11:11

cmbaxter