Reputation: 2154
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
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
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