MDC (Mapped Diagnostic Context) Logging in AKKA
Asked Answered
C

1

6

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

Coparcener answered 7/5, 2015 at 3:21 Comment(1)
I detailed a solution to this in https://mcmap.net/q/1329572/-scala-akka-logging-with-slf4j-mdcBombproof
A
1

akka.actor.DiagnosticActorLogging might should solve your problem.

Assent answered 7/10, 2015 at 7:25 Comment(1)
This only works within actors. To propagate the MDC to other loggers (which the referenced post is about) some additional work is needed.Bombproof

© 2022 - 2024 — McMap. All rights reserved.