如何使用log4j将日志记录到在YARN上运行的Spark应用程序内的本地文件系统?

时间:2015-02-11 12:12:32

标签: logging log4j apache-spark yarn

我正在构建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

我错过了什么。

5 个答案:

答案 0 :(得分:24)

[编辑以避免混淆]

看起来您需要附加启动任务/作业时使用的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" ...

答案 1 :(得分:8)

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

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

访问日志
yarn logs -applicationId <application id>

答案 2 :(得分:3)

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

2)Spark将创建2种YARN容器,即驱动程序和worker。因此,您希望共享一个文件,从您向所有容器提交应用程序的位置(您无法在JAR中使用文件,因为这不是真正运行的JAR),因此您必须使用--files Spark submit指令(这将与所有工人共享文件)。

像这样:

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。

答案 3 :(得分:1)

或者,您可以使用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/

答案 4 :(得分:1)

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

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