Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MDC (Mapped Diagnostic Context) Logging in AKKA

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

like image 963
Frank Smith Avatar asked May 07 '15 03:05

Frank Smith


People also ask

What is MDC logging?

A Mapped Diagnostic Context, or MDC in short, is an instrument for distinguishing interleaved log output from different sources. Log output is typically interleaved when a server handles multiple clients near-simultaneously. The MDC is managed on a per thread basis.

What is SLF4J MDC?

MDC explained MDC stands for Mapped Diagnostic Context, and is a feature that is offered by both plain Log4J and SLF4J with Logback or Log4J as the backing logging framework. It is a map that holds String values keyed by Strings, which is associated with the current thread (using a ThreadLocal).

What is thread context map MDC?

The Thread Context Map allows any number of items to be added and be identified using key/value pairs. The Thread Context Stack allows one or more items to be pushed on the Stack and then be identified by their order in the Stack or by the data itself.

Why is MDC used?

MDC in Log4j allows us to fill a map-like structure with pieces of information that are accessible to the appender when the log message is actually written. The MDC structure is internally attached to the executing thread in the same way a ThreadLocal variable would be.


1 Answers

akka.actor.DiagnosticActorLogging might should solve your problem.

like image 167
Keynash Avatar answered Nov 06 '22 22:11

Keynash