apache-spark – 在Spark Scala应用程序中使用Log4J2进行异步日志记录

问题:在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"

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>

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

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

为了测试异步行为,我在初始化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")

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

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

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

主要问题:SPARK有哪些如何解释我的LOG4J2配置并违反其LOG4J配置,还是不允许ASYNC记录行为?

最佳答案 您应该确保唯一的事情是在初始化Log4j2之前设置系统属性.

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

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

点赞