I want to implement logback MDC logging on my AKKA application to organize and have a more infomative log; however, I also read that MDC might not work well with AKKA because AKKA has asynchronous logging system (MDC might be stored on a different thread). I used the Custom Dispatcher for MDC Logging defined here hoping to solve my problem but I can't make it work on my application. My application is not a play framework app though.
I have a RequestHandler
Actor that receives different types of request and delegates it to a RequestSpecificHandler
Actor which will process it.
class RequestHandler() extends Actor with akka.actor.ActorLogging {
def receive: Receive = {
//Requests
case req: RequestA =>
org.slf4j.MDC.put("messageId", req.msgId)
org.slf4j.MDC.put("requestType", req.requestType)
log.debug("FIRST LOG Received a RequestA")
val actorA = context.ActorOf(ActorA.props)
actorA ! req.msg
case req: RequestB => //...
//other requests...
//Response
case res: ResponseA =>
log.debug("Received responseA")
org.slf4j.MDC.remove("messageId")
org.slf4j.MDC.remove("requestType")
//other response
}
}
In my RequestSpecificHandler
Actors, I also create new or refer to other existing HelperActors
class ActorA () extends Actor with akka.actor.ActorLogging {
val helperA = context.actorSelection("/user/helperA")
val helperB = context.actorOf("HelperB.props")
def receive: Receive = {
case msg: MessageTypeA =>
//do some stuff
log.debug("received MessageTypeA")
helperA ! taskForA
case doneByA =>
//do some stuff
log.debug("received doneByA")
helperB ! taskForB
case doneByB =>
log.debug("send reponseA")
sender ! ResponseA
}
}
Logging differs everytime I send a request, sometimes it logs with correct MDC messageId and requestType, sometimes it does not have any value. Even the "FIRST LOG Received a RequestA"
log behaves this way, I assume it should always have the correct logstamp as it is in the same class where I call MDC.put
Here is my application.conf:
akka {
log-dead-letters = 10
loggers = ["akka.event.slf4j.Slf4jLogger"]
loglevel = DEBUG
logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
actor{
default-dispatcher {
type = "some.package.monitoring.MDCPropagatingDispatcherConfigurator"
}
...
How can I do MDC logging where all the code logs (including dependency lib logs) executed during a certain request will have the same messageId, requestType logstamp? Are there other ways to do this aside from Custom Dispatcher for AKKA? Also, what is a more organize way to declare MDC.put
and MDC.remove
codes? Right now I'm having it on each case on receive.
Thanks