Our Akka project depends on some other non akka code. From within this code our way to get a logger is by calling org.slf4j.LoggerFactory.getLogger(ThisClass.class)
I would like to have the real time and real thread when and where the event took place, included in the log print, so I fetch the values of akkaTimestamp and sourceThread, as following:
log4j.appender.console.layout.ConversionPattern=[%-5p] [%X{akkaTimestamp}] [%X{sourceThread}] %c{5}: %m%n
Problem is that these values, which are extracted from the MDC, are not available in the prints which were dispatched from the non-akka loggers.
Here they say
It will probably be a good idea to use the sourceThread MDC value also in non-Akka parts of the application in order to have this property consistently available in the logs.
But they never say how /:
As Konrad says, its not that complicated. This is what worked for me:
import akka.util.Helpers
import ch.qos.logback.core.ConsoleAppender
import org.slf4j.MDC
/**
* Decorates MDC with same keys as Akka in
* <a href="https://github.com/akka/akka/blob/master/akka-slf4j/src/main/scala/akka/event/slf4j/Slf4jLogger.scala#L89">Slf4jLogger</a>
* So that logging messages dispatched from non-akka threads has same data.
*/
class AkkaCompatibleConsoleAppender[E] extends ConsoleAppender[E] {
val mdcThreadAttributeName = "sourceThread"
val mdcAkkaTimestamp = "akkaTimestamp"
override def append(eventObject: E): Unit = {
try {
MDC.put(mdcAkkaTimestamp, Helpers.currentTimeMillisToUTCString(System.currentTimeMillis()))
MDC.put(mdcThreadAttributeName, Thread.currentThread().getName)
super.append(eventObject)
} finally {
MDC.remove(mdcAkkaTimestamp)
MDC.remove(mdcThreadAttributeName)
}
}
}
And then in logback.xml:
<appender name="STDOUT" class="agordo.server.AkkaCompatibleConsoleAppender">
<encoder>
<pattern>%X{akkaTimestamp} %-5level %logger{36} %X{sourceThread} %X{akkaSource} - %msg%n</pattern>
</encoder>
</appender>
You could set up your non-akka loggers to use the same style of MDC. It's not very complicated and you can look at Akka's Slf4jLogger class to see how it is done.
For the current thread you can simply use Thread.currentThread.getName
and for the time (in order to be 1:1 with the Akka impl) you can have a look at the Helpers.currentTimeMillisToUTCString
method in Akka (see here for currentTimeMillisToUTCString)
Happy hakking!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With