【问题标题】:How to log using log4j to local file system inside a Spark application that runs on YARN?如何使用 log4j 将日志记录到在 YARN 上运行的 Spark 应用程序内的本地文件系统?
【发布时间】:2015-04-11 19:23:36
【问题描述】:

我正在构建一个 Apache Spark Streaming 应用程序,在 YARN 上运行时无法将其记录到本地文件系统上的文件中。如何做到这一点?

我已经设置了log4.properties文件,这样它就可以成功写入本地文件系统上/tmp目录下的一个日志文件(如下图部分):

log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=/tmp/application.log
log4j.appender.file.append=false
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

当我使用以下命令在本地运行我的 Spark 应用程序时:

spark-submit --class myModule.myClass --master local[2] --deploy-mode client myApp.jar

它运行良好,我可以看到日志消息已写入我本地文件系统上的/tmp/application.log

但是当我通过 YARN 运行相同的应用程序时,例如

spark-submit --class myModule.myClass --master yarn-client  --name "myModule" --total-executor-cores 1 --executor-memory 1g myApp.jar

spark-submit --class myModule.myClass --master yarn-cluster  --name "myModule" --total-executor-cores 1 --executor-memory 1g myApp.jar

我在运行 YARN 的机器的本地文件系统上看不到任何 /tmp/application.log

我错过了什么。

【问题讨论】:

  • 我刚刚粘贴了你的 log4j.properties 部分并在本地运行它,但它没有为我的 /tmp 创建任何日志文件。我错过了什么吗?
  • 我发现这篇文章很有用-stackoverflow.com/questions/27781187/…

标签: logging log4j apache-spark hadoop-yarn


【解决方案1】:

看起来您需要附加到启动任务/作业时使用的 JVM 参数。

尝试将conf/spark-defaults.conf 编辑为described here

spark.executor.extraJavaOptions=-Dlog4j.configuration=file:/apps/spark-1.2.0/conf/log4j.properties

spark.driver.extraJavaOptions=-Dlog4j.configuration=file:/apps/spark-1.2.0/conf/log4j.properties

或者尝试将 conf/spark-env.sh 编辑为 described here 以添加相同的 JVM 参数,尽管 conf/spark-defaults.conf 中的条目应该可以工作。

如果您仍然没有得到任何乐趣,您可以在命令行上显式传递 log4j.properties 文件的位置以及您的 spark-submit,如果该文件包含在您的 JAR 文件和根目录中,则像这样你的类路径

spark-submit --class sparky.MyApp --master spark://my.host.com:7077 --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=log4j-executor.properties" myapp.jar

如果文件不在您的类路径中,请使用 file: 前缀和完整路径,如下所示

spark-submit ... --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:/apps/spark-1.2.0/conf/log4j-executor.properties" ...

【讨论】:

  • 我有点困惑。我的 log4j.properties 文件被打包到 JAR 文件中。我的应用程序是一个 Maven 项目,我正在创建单个、大、自包含的 JAR 文件,其中还包含 log4j.properties 文件。当我在本地运行 Spark 时,这工作正常。当我在 YARN 集群上运行 Spark 时,这(将 log4j.properties 放入 JAR)是不可能的吗?
  • 是的,应该可以。我试图通过剥离您正在使用的配置来帮助简化问题。我不是 Spark 方面的专家。我在 Windows 主机上有一个独立的集群日志记录。
  • @Emre 我玩弄了答案中提到的各种设置,这让我重新编写了它。我通过编辑spark-defaults.conf 使日志记录工作,然后还通过使用spark-submit --conf 使其工作。一个或另一个应该可以工作(你不应该同时需要)
  • 嗨,以上可以用于不在类路径上也不包含在 jar 中的日志文件吗?我已将 log.properties 复制到执行程序并使用命令行 arg 但它告诉它找不到,谢谢
  • @EmreSevinç 这行不通。 Spark worker 应用程序不是您的 jar,而是仅从驱动程序发送的运行 Spark 代码的应用程序,请参阅我的回答,您必须使用静态文件(在 HDFS 或任何其他共享文件系统中,或通过 --files Spark 指令) .
【解决方案2】:

上述使用 spark.executor.extraJavaOptions、spark.driver.extraJavaOptions 指定 log4j.properties 的选项只会在本地记录它,并且 log4.properties 应该在每个节点上本地存在。

https://spark.apache.org/docs/1.2.1/running-on-yarn.html 文档中所述,您也可以使用 --files 选项上传 log4j.properties 以及您的应用程序。这将在 HDFS 上进行纱线聚合日志记录,您可以使用命令访问日志

yarn logs -applicationId <application id>

【讨论】:

  • 你有 log4j.properties 文件的例子来记录到 HDFS 吗?
  • @Irene 这是与其他常规 log4.properties 文件的唯一区别。 log4j.appender.file_appender.File=${spark.yarn.app.container.log.dir}/spark.log
【解决方案3】:

1) 要调试 YARN 上的 Spark 如何解释您的 log4j 设置,请使用 log4j.debug 标志。

2) Spark 将创建 2 种 YARN 容器,驱动程序和工作程序。所以你想与所有容器共享一个你提交应用程序的文件(你不能在 JAR 中使用文件,因为这不是真正运行的 JAR),所以你必须使用 --files Spark 提交指令(这个将与所有工作人员共享文件)。

像这样:

spark-submit     
    --class com.X.datahub.djobi.Djobi \
    --files "./log4j.properties" \
    --driver-java-options "-Dlog4j.debug=true -Dlog4j.configuration=log4j.properties" \
    --conf "spark.executor.extraJavaOptions=-Dlog4j.debug=true -Dlog4j.configuration=log4j.properties " \
    ./target/X-1.0.jar "$@"

其中 log4j.properties 是 src/main/resources/config 文件夹中的项目文件。

我可以在控制台看到:

log4j: Trying to find [config/log4j.properties] using context 
classloader org.apache.spark.util.MutableURLClassLoader@5bb21b69.
log4j: Using URL [jar:file:/home/hdfs/djobi/latest/lib/djobi-1.0.jar!/config/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL jar:file:/home/hdfs/djobi/latest/lib/djobi-1.0.jar!/config/log4j.properties

所以文件被考虑在内,你也可以在 Spark webUI 上查看。

【讨论】:

    【解决方案4】:

    或者,您可以使用 log4j 的 PropertyConfigurator 来定义您的自定义日志属性。

    例如

     import com.foo.Bar;
    
     import org.apache.log4j.Logger;
     import org.apache.log4j.PropertyConfigurator;
    
     public class MySparkApp {
    
       static Logger logger = Logger.getLogger(MySparkApp.class.getName());
    
       public static void main(String[] args) {
    
         // Location to property file
         PropertyConfigurator.configure(args[0]);
    
         logger.info("Entering application.");
    
         logger.info("Exiting application.");
       }
     }
    

    您的属性文件应具有以下属性,

    log4j.appender.file=org.apache.log4j.FileAppender
    
    log4j.appender.file.File=/tmp/application.log
    
    log4j.appender.file.append=false
    
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    
    log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
    

    编辑:更新 log4j 文档的链接。 Spark 使用 log4j 2,而不是 v1.2

    参考:http://logging.apache.org/log4j/2.x/

    【讨论】:

    • 我不知道这是否适用于执行程序和驱动程序。在上面的代码中,它可能只会为驱动程序配置代码。
    【解决方案5】:

    在您的 log4j.properties 文件中,您还应该将 log4j.rootCategoryINFO,console 修改为 INFO,file

    log4j.rootCategory=INFO, console    
    log4j.rootCategory=INFO,file
    

    【讨论】:

    猜你喜欢
    • 2020-08-16
    • 1970-01-01
    • 2011-10-26
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    相关资源
    最近更新 更多