如何使用 log4j 将日志记录到在 YARN 上运行的 Spark 应用程序内的本地文件系统?
How to log using log4j to local file system inside a Spark application that runs on 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
我在运行s YARN 的机器的本地文件系统上看不到任何/tmp/application.log
。
我错过了什么
看起来您需要附加到启动 tasks/jobs 时使用的 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 的 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
编辑:更新 link 到 log4j 文档。 Spark 使用 log4j 2,而不是 v1.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 文件中,您还应该将 log4j.rootCategory
从 INFO,console
修改为 INFO,file
。
log4j.rootCategory=INFO, console
log4j.rootCategory=INFO,file
1) 要调试 YARN 上的 Spark 如何解释您的 log4j 设置,请使用 log4j.debug
标志。
2) Spark 会创建两种 YARN 容器,driver 和 worker。所以你想从你提交应用程序的地方与所有容器共享一个文件(你不能使用 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 上查看。
我正在构建一个 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
我在运行s YARN 的机器的本地文件系统上看不到任何/tmp/application.log
。
我错过了什么
看起来您需要附加到启动 tasks/jobs 时使用的 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 的 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
编辑:更新 link 到 log4j 文档。 Spark 使用 log4j 2,而不是 v1.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 文件中,您还应该将 log4j.rootCategory
从 INFO,console
修改为 INFO,file
。
log4j.rootCategory=INFO, console
log4j.rootCategory=INFO,file
1) 要调试 YARN 上的 Spark 如何解释您的 log4j 设置,请使用 log4j.debug
标志。
2) Spark 会创建两种 YARN 容器,driver 和 worker。所以你想从你提交应用程序的地方与所有容器共享一个文件(你不能使用 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 上查看。