5

我们的 Akka 项目依赖于其他一些非 akka 代码。在这段代码中,我们获取记录器的方法是调用org.slf4j.LoggerFactory.getLogger(ThisClass.class)

我希望在日志打印中包含事件发生的时间和地点的实时真实线程,因此我获取akkaTimestampsourceThread的值,如下所示:

log4j.appender.console.layout.ConversionPattern=[%-5p] [%X{akkaTimestamp}] [%X{sourceThread}] %c{5}: %m%n

问题是这些从 MDC 中提取的值在从非 akka 记录器发送的打印中不可用。

他们在这里

在应用程序的非 Akka 部分中也使用 sourceThread MDC 值可能是一个好主意,以便在日志中始终使用此属性。

但他们从不说如何/:

4

2 回答 2

6

正如康拉德所说,它没有那么复杂。这对我有用:

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)
    }
  }
}

然后在 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>
于 2015-05-24T16:18:31.760 回答
1

您可以将非 akka 记录器设置为使用相同样式的 MDC。它不是很复杂,你可以查看 Akka 的Slf4jLogger类来了解它是如何完成的。

对于当前线程,您可以简单地使用Thread.currentThread.getName时间(为了与 Akka impl 1:1),您可以查看 Akka 中的方法(有关currentTimeMillisToUTCStringHelpers.currentTimeMillisToUTCString的信息,请参见此处)

哈克快乐!

于 2015-05-03T20:35:07.880 回答