Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add logging function in sending and receiving action in akka

Tags:

scala

akka

Now, I am asked to add logging function in akka's actor.

When a message is received, before it is handled, this message should be written into log. And before a message is sent out, this message should be logged first.

I think I should override the receive and send functions in Actor. Suppose I create a trait actorlog which extends Actor. And class myActor extends actorlog. But in myActor, I need to override receive function (it seems it causes problems here). So I am confused what I should do.

PS. I know akka provides logging. But now I need implement this function by myself.

like image 288
city Avatar asked Nov 07 '13 02:11

city


People also ask

How do I configure Akka to log unhandled messages?

To configure a custom logger inside your Akka.Config, you need to use a fully qualified .NET class name like this: It is possible to configure akka so that Unhandled messages are logged as Debug log events for debug purposes. This can be achieved using the following configuration setting:

How are akka logs processed?

For historical reasons logging by the Akka internals and by classic actors are performed asynchronously through an event bus. Such log events are processed by an event handler actor, which then emits them to SLF4J or directly to standard out.

What is the default logging backend for Akka?

Logging in Akka is not tied to a specific logging backend. By default log messages are printed to STDOUT, but you can plug-in a SLF4J logger or your own logger. Logging is performed asynchronously to ensure that logging has minimal performance impact.

When is the timestamp of an Akka log entry taken?

For typed actors the log event timestamp is taken when the log call was made but for Akka’s internal logging as well as the classic actor logging is asynchronous which means that the timestamp of a log entry is taken from when the underlying logger implementation is called, which can be surprising at first.


Video Answer


2 Answers

Besides the other answers here, another approach is to use orElse to prepend a partial function to your receive. In that partial function, put the logging in isDefinedAt so it gets called on every message.

For example:

trait ReceiveLogger {
  this: Actor with ActorLogging =>

  def logMessage: Receive = new Receive {
    def isDefinedAt(x: Any) = {
      log.debug(s"Got a $x")
      false
    }
    def apply(x: Any) = throw new UnsupportedOperationException  
  }
}  

class MyActor extends Actor with ActorLogging with ReceiveLogger {
  def receive: Receive = logMessage orElse {
     case ...
  }
}

Using orElse is a general approach for composing receive behavior. In most cases I am composing things like this:

def otherBehavior: Receive = {
  case OtherMessage => ...
}

class MyActor extends Actor {
  def receive = otherBehavior orElse {
    case ...
  }
} 

A good example of the stackable traits approach can be seen in this presentation: http://www.slideshare.net/EvanChan2/akka-inproductionpnw-scala2013

like image 60
sourcedelica Avatar answered Nov 12 '22 15:11

sourcedelica


There is a utility to get logging of the received messages in Akka. It's briefly mentioned in the logging documentation. Basically you wrap your receive function in it like this:

def receive = LoggingReceive {
                // your normal receive here
              }

And then you enable it in your config with:

akka.actor.debug.receive=on

The information will be logged at debug level.

like image 24
Björn Antonsson Avatar answered Nov 12 '22 13:11

Björn Antonsson