如何在Spark中关闭INFO日志记录?

185

我按照AWS EC2指南安装了Spark,使用bin/pyspark脚本可以成功启动程序并进入spark提示符,也能顺利完成快速入门指南。

但是,我却无法弄清楚如何在每个命令之后停止冗长的INFO日志输出。

我尝试了在启动应用程序的位置以及每个节点上的conf文件夹中的log4j.properties文件中几乎所有可能情况的代码(包括注释掉、设置为OFF),但没有任何效果。每次执行语句后,我仍然会看到INFO日志记录输出。

我对这个东西到底应该如何工作感到非常困惑。

#Set everything to be logged to the console log4j.rootCategory=INFO, console                                                                        
log4j.appender.console=org.apache.log4j.ConsoleAppender 
log4j.appender.console.target=System.err     
log4j.appender.console.layout=org.apache.log4j.PatternLayout 
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n

# Settings to quiet third party logs that are too verbose
log4j.logger.org.eclipse.jetty=WARN
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO

使用SPARK_PRINT_LAUNCH_COMMAND时,我的完整类路径如下:

Spark命令: /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/bin/java -cp :/root/spark-1.0.1-bin-hadoop2/conf:/root/spark-1.0.1-bin-hadoop2/conf:/root/spark-1.0.1-bin-hadoop2/lib/spark-assembly-1.0.1-hadoop2.2.0.jar:/root/spark-1.0.1-bin-hadoop2/lib/datanucleus-api-jdo-3.2.1.jar:/root/spark-1.0.1-bin-hadoop2/lib/datanucleus-core-3.2.2.jar:/root/spark-1.0.1-bin-hadoop2/lib/datanucleus-rdbms-3.2.1.jar -XX:MaxPermSize=128m -Djava.library.path= -Xms512m -Xmx512m org.apache.spark.deploy.SparkSubmit spark-shell --class org.apache.spark.repl.Main

spark-env.sh的内容:

#!/usr/bin/env bash

# This file is sourced when running various Spark programs.
# Copy it as spark-env.sh and edit that to configure Spark for your site.

# Options read when launching programs locally with 
# ./bin/run-example or ./bin/spark-submit
# - HADOOP_CONF_DIR, to point Spark towards Hadoop configuration files
# - SPARK_LOCAL_IP, to set the IP address Spark binds to on this node
# - SPARK_PUBLIC_DNS, to set the public dns name of the driver program
# - SPARK_CLASSPATH=/root/spark-1.0.1-bin-hadoop2/conf/

# Options read by executors and drivers running inside the cluster
# - SPARK_LOCAL_IP, to set the IP address Spark binds to on this node
# - SPARK_PUBLIC_DNS, to set the public DNS name of the driver program
# - SPARK_CLASSPATH, default classpath entries to append
# - SPARK_LOCAL_DIRS, storage directories to use on this node for shuffle and RDD data
# - MESOS_NATIVE_LIBRARY, to point to your libmesos.so if you use Mesos

# Options read in YARN client mode
# - HADOOP_CONF_DIR, to point Spark towards Hadoop configuration files
# - SPARK_EXECUTOR_INSTANCES, Number of workers to start (Default: 2)
# - SPARK_EXECUTOR_CORES, Number of cores for the workers (Default: 1).
# - SPARK_EXECUTOR_MEMORY, Memory per Worker (e.g. 1000M, 2G) (Default: 1G)
# - SPARK_DRIVER_MEMORY, Memory for Master (e.g. 1000M, 2G) (Default: 512 Mb)
# - SPARK_YARN_APP_NAME, The name of your application (Default: Spark)
# - SPARK_YARN_QUEUE, The hadoop queue to use for allocation requests (Default: ‘default’)
# - SPARK_YARN_DIST_FILES, Comma separated list of files to be distributed with the job.
# - SPARK_YARN_DIST_ARCHIVES, Comma separated list of archives to be distributed with the job.

# Options for the daemons used in the standalone deploy mode:
# - SPARK_MASTER_IP, to bind the master to a different IP address or hostname
# - SPARK_MASTER_PORT / SPARK_MASTER_WEBUI_PORT, to use non-default ports for the master
# - SPARK_MASTER_OPTS, to set config properties only for the master (e.g. "-Dx=y")
# - SPARK_WORKER_CORES, to set the number of cores to use on this machine
# - SPARK_WORKER_MEMORY, to set how much total memory workers have to give executors (e.g. 1000m, 2g)
# - SPARK_WORKER_PORT / SPARK_WORKER_WEBUI_PORT, to use non-default ports for the worker
# - SPARK_WORKER_INSTANCES, to set the number of worker processes per node
# - SPARK_WORKER_DIR, to set the working directory of worker processes
# - SPARK_WORKER_OPTS, to set config properties only for the worker (e.g. "-Dx=y")
# - SPARK_HISTORY_OPTS, to set config properties only for the history server (e.g. "-Dx=y")
# - SPARK_DAEMON_JAVA_OPTS, to set config properties for all daemons (e.g. "-Dx=y")
# - SPARK_PUBLIC_DNS, to set the public dns name of the master or workers

export SPARK_SUBMIT_CLASSPATH="$FWDIR/conf"

3
在 Spark 程序中,创建会话后,您可以按照以下方式设置日志级别,对于 Java SparkSession spark= SparkSession.builder().master("local").getOrCreate(); spark.sparkContext().setLogLevel("INFO"); - iKing
16个回答

188

只需在Spark目录中执行此命令:

cp conf/log4j.properties.template conf/log4j.properties

编辑log4j.properties:

# Set everything to be logged to the console
log4j.rootCategory=INFO, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n

# Settings to quiet third party logs that are too verbose
log4j.logger.org.eclipse.jetty=WARN
log4j.logger.org.eclipse.jetty.util.component.AbstractLifeCycle=ERROR
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO

替换第一行:

log4j.rootCategory=INFO, console

作者:

log4j.rootCategory=WARN, console

保存并重新启动您的shell。在我的 OS X 上,这对于 Spark 1.1.0 和 Spark 1.5.1 是有效的。


1
这很有帮助,重要的是要意识到除非你创建它,否则log4j.properties不存在。在Ubuntu上,我不需要重新启动以使这些更改生效。 - disruptive
对我无效。Spark 1.5。RHEL 6。CDH 5.5。尝试创建新文件/opt/cloudera/parcels/CDH/etc/spark/conf.dist/log4j.properties并按照上述说明进行更改。还尝试编辑现有文件/etc/spark/conf/log4j.properties。对于pyspark shell和pyspark-shell均没有影响。 - Tagar
我们需要为 Spark 集群中的所有节点都执行这个操作吗? - cloud
这正阻止了我手动传递的信息日志。我如何限制它仅隐藏Spark信息日志? - ss301

84
在Spark 2.0中,您还可以使用setLogLevel动态为您的应用程序配置日志记录级别:
    from pyspark.sql import SparkSession
    spark = SparkSession.builder.\
        master('local').\
        appName('foo').\
        getOrCreate()
    spark.sparkContext.setLogLevel('WARN')
pyspark 控制台中,一个默认的 spark 会话已经可用。

1
你只是压制了日志信息。但实际的代码仍在后台运行。如果你看到CPU使用率很高,那么Spark即使在空闲时也会占用大量CPU。 - hurelhuyag
1
这正是 PySpark 工作中 log4j 不可访问的解决方案。 - yeliabsalohcin

63

受 pyspark/tests.py 的启发,我做了...

def quiet_logs(sc):
    logger = sc._jvm.org.apache.log4j
    logger.LogManager.getLogger("org"). setLevel( logger.Level.ERROR )
    logger.LogManager.getLogger("akka").setLevel( logger.Level.ERROR )

在创建 SparkContext 后立即调用此函数可将我的测试记录的 stderr 行数从 2647 减少到 163。但是,创建 SparkContext 本身会记录 163 行,直到...

15/08/25 10:14:16 INFO SparkDeploySchedulerBackend: SchedulerBackend is ready for scheduling beginning after reached minRegisteredResourcesRatio: 0.0

对我来说,如何通过编程进行调整并不清楚。


3
如果您对如何调整这些行有任何想法,请分享。 - Irene
我认为在 PySpark 中没有直接更改默认调试级别的解决方案,直到 SparkContext 开始。因为 sc._jvm 是在 SC 创建后才被创建的。不过,你仍然可以通过 log4j.properties 文件进行更改,就像其他答案中所讨论的那样。Spark 应该创建一个名为 spark.default.logging 的变量,作为选项传递给 SparkConf,以覆盖默认的 Root Logger 级别。 - Tagar

38

编辑你的 conf/log4j.properties 文件并更改以下行:

   log4j.rootCategory=INFO, console

    log4j.rootCategory=ERROR, console

另一种方法是:

启动spark-shell并输入以下内容:

import org.apache.log4j.Logger
import org.apache.log4j.Level

Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)

之后您将不会看到任何日志。


3
对于使用spark-shell(scala)的情况,后面的选项可行。但在不更改log4j文件的情况下,如何处理pyspark呢? - hmi2015
将log4j属性文件更改为“warn”可能更好,但除此之外,wannik的这个答案确实适用于将日志级别更改为pyspark控制台。https://dev59.com/F18e5IYBdhLWcg3w7-Nz#34487962 - michael

34
>>> log4j = sc._jvm.org.apache.log4j
>>> log4j.LogManager.getRootLogger().setLevel(log4j.Level.ERROR)

我在pyspark中使用了这个。作为一种单行黑客技巧,效果很好。我仍然会收到愚蠢的YarnExecutor died消息,但在我看来这不应该是一个错误。就这样... - jatal
3
执行后这会抑制日志记录,但是在那之前有很多INFO级别的日志,不幸的是。 - DavidJ

32

对于 PySpark,您也可以在脚本中使用 sc.setLogLevel("FATAL") 设置日志级别。来自 文档:

控制我们的日志级别。这将覆盖任何用户定义的日志设置。有效的日志级别包括: ALL, DEBUG, ERROR, FATAL, INFO, OFF, TRACE, WARN


伟大的解决方案适用于1.4版本之后的Spark(因此,自2015年中期以来)。 - Jealie
我尝试了使用Spark 1.6.2和Scala,但似乎不起作用。 - Yeikel
@Yeikel 这个解决方案适用于 PySpark。很抱歉之前没有说清楚 - 我现在会编辑答案。 - Galen Long

23

你可以使用setLogLevel

val spark = SparkSession
      .builder()
      .config("spark.master", "local[1]")
      .appName("TestLog")
      .getOrCreate()

spark.sparkContext.setLogLevel("WARN")

14

这可能是由于Spark计算其类路径的方式造成的。我猜测Hadoop的log4j.properties文件在类路径上出现在Spark之前,阻止了您所做的更改生效。

如果您运行

SPARK_PRINT_LAUNCH_COMMAND=1 bin/spark-shell

然后Spark将打印用于启动shell的完整类路径;在我的情况下,我看到

Spark Command: /usr/lib/jvm/java/bin/java -cp :::/root/ephemeral-hdfs/conf:/root/spark/conf:/root/spark/lib/spark-assembly-1.0.0-hadoop1.0.4.jar:/root/spark/lib/datanucleus-api-jdo-3.2.1.jar:/root/spark/lib/datanucleus-core-3.2.2.jar:/root/spark/lib/datanucleus-rdbms-3.2.1.jar -XX:MaxPermSize=128m -Djava.library.path=:/root/ephemeral-hdfs/lib/native/ -Xms512m -Xmx512m org.apache.spark.deploy.SparkSubmit spark-shell --class org.apache.spark.repl.Main

/root/ephemeral-hdfs/conf置于类路径的开头。

我已经打开了一个问题[SPARK-2913]来在下一个版本中修复这个问题(我应该很快发布一个补丁)。

与此同时,这里有一些解决方法:

  • export SPARK_SUBMIT_CLASSPATH="$FWDIR/conf"添加到spark-env.sh
  • 删除(或重命名)/root/ephemeral-hdfs/conf/log4j.properties

谢谢。我尝试将其添加到我的spark-env.sh文件中,并尝试删除log4j.properties文件,但仍然得到INFO输出。我已经在问题中添加了完整的类路径。 - horatio1701d
谢谢您提供的额外信息。您能否也发布 spark-env.sh 的内容(您可以删除私人信息,例如主机名)? - Josh Rosen
感谢您。我发布了spark-env.sh文件。如果我误解了如何进行基本设置,对不起。目前我尽可能将所有内容保持默认状态,只是为了进行一些测试。 - horatio1701d

13

只需在您的spark-submit命令中添加以下参数

--conf "spark.driver.extraJavaOptions=-Dlog4jspark.root.logger=WARN,console"

这将临时覆盖系统值,仅适用于该作业。请从log4j.properties文件中检查确切的属性名称(此处为log4jspark.root.logger)。

希望这可以帮到你,干杯!


1
另一个我发现有用的是,你可以指定log4j.properties文件: --conf spark.driver.extraJavaOptions='-Dlog4j.configuration=file:/home/foobar/log4j.properties - selle
使用Spark 2.4.7,@oleksii的答案中的设置hadoop.root.logger完美地工作: --conf“spark.driver.extraJavaOptions=-Dhadoop.root.logger=WARN,console” - edrabc
1
非常感谢,这正是我想要的。不幸的是,无论是 -Dlog4jspark.root.logger 还是 -Dhadoop.root.logger,都没有起作用,因为有点沮丧,所以我尝试了 -Droot.logger,它奏效了。如果有帮助的话,以下是我所做的:--conf "spark.driver.extraJavaOptions=-Droot.logger=FATAL,console"。 - alwayslearning

11

Spark 1.6.2:

log4j = sc._jvm.org.apache.log4j
log4j.LogManager.getRootLogger().setLevel(log4j.Level.ERROR)

Spark 2.x:

spark.sparkContext.setLogLevel('WARN')

(其中SparkSession是Spark的一个会话)

或者使用旧方法,将conf/log4j.properties.template重命名为conf/log4j.properties,放在Spark目录下。

log4j.properties文件中,将log4j.rootCategory=INFO, console更改为log4j.rootCategory=WARN, console

不同的日志级别包括:

  • OFF(最具体,没有日志)
  • FATAL(最具体,少量数据)
  • ERROR - 仅记录错误情况
  • WARN - 仅记录警告或错误情况
  • INFO(默认)
  • DEBUG - 记录详细步骤(以及以上所有日志)
  • TRACE(最不具体,大量数据)
  • ALL(最不具体,所有数据)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接