city
city

Reputation: 2154

how to add logging function in sending and receiving action in 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.

Upvotes: 9

Views: 4633

Answers (3)

sourcedelica
sourcedelica

Reputation: 24040

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

Upvotes: 10

Björn Antonsson
Björn Antonsson

Reputation: 1019

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.

Upvotes: 25

Yuriy
Yuriy

Reputation: 2769

  1. use stackable modificator abstract override for stackable call of receive method.
  2. use new feature of Akka: event-sourced actor system (docs here).

Upvotes: 2

Related Questions