在Spark Scala应用程序中使用Log4J2异步日志记录

Rya*_*ack 5 log4j sbt log4j2 apache-spark spark-streaming

问题:在Spark本地模式下初始化SparkContext后,我无法观察到Log4J2的异步功能。

SBT中的Log4j2依赖关系:

  "com.lmax" % "disruptor" % "3.3.5",
  "org.apache.logging.log4j" % "log4j-api" % "2.8.2",
  "org.apache.logging.log4j" % "log4j-core" % "2.8.2",
  "org.apache.logging.log4j" %% "log4j-api-scala" % "2.8.2"
Run Code Online (Sandbox Code Playgroud)

Log4j2配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
    <Console name="Console-Appender" target="SYSTEM_OUT">
        <PatternLayout>
            <pattern>
                [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
            </pattern>>
        </PatternLayout>
    </Console>
    <File name="File-Appender" fileName="logs/xmlfilelog.log" >
        <PatternLayout>
            <pattern>
                [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
            </pattern>
        </PatternLayout>
    </File>
</Appenders>
<Loggers>
    <Logger  name="guru.springframework.blog.log4j2async" level="debug">
        <AppenderRef ref="File-Appender"/>he preceding c
    </Logger>
    <Root level="debug">
        <AppenderRef ref="Console-Appender"/>
    </Root>
</Loggers>
Run Code Online (Sandbox Code Playgroud)

我在IntelliJ中设置以下系统属性

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
Run Code Online (Sandbox Code Playgroud)

为了测试异步行为,在初始化SparkContext之前和之后,我运行了以下代码段:

val start = System.nanoTime()

for(i <- 1 to 1000) {
  logger.error("Hello")
}

val end = System.nanoTime()
val timeMS = (end - start)/1000000
println(s"Parsed ${iterations} reports in ${timeMS} ms ${timeMS/1000} sec")
Run Code Online (Sandbox Code Playgroud)

成功的结果:我能够看到以下调试行,确认已启用AsyncContext 2017-04-25 14:55:40,541 main DEBUG LoggerContext[name=AsyncContext@6d9c638, org.apache.logging.log4j.core.async.AsyncLoggerContext@758f4f03] started OK.。另外,我的打印行语句“ Parsed ...”显示在记录器输出的中间某处,指示异步行为。

但是,一旦在SparkContext初始化之后移动了此代码块,便不再具有观察者异步活动。打印行语句“ Parsed ...”始终显示在记录器输出之后。令人困惑的是2017-04-25 14:55:40,541 main DEBUG LoggerContext[name=AsyncContext@6d9c638, org.apache.logging.log4j.core.async.AsyncLoggerContext@758f4f03] started OK.。仍然被观察到。

为了进行健全性检查,我还在spark应用程序的范围内打印了logger api的软件包。结果产生了package org.apache.logging.log4j.scala, Apache Log4j Scala 2.11 wrapper for Log4j API, version 2.8.2。根据Log4J2文档,“ og4j 2 Scala API依赖于Log4j 2 API”。因此,我相信我可以推断出我实际上正在使用Log4J2。

主要问题:SPARK是否在拦截我的LOG4J2配置并默认为LOG4J配置,还是不允许同步记录行为?

Rem*_*pma 1

您唯一需要确保的是在Log4j2 初始化之前设置系统属性。

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
Run Code Online (Sandbox Code Playgroud)

在我看来,这是正确完成的:如果您可以看到AsyncLoggerContext使用了 an ,那么您可以确定您正在使用 Disruptor 支持的异步记录器。