Как остановить отображение сообщений INFO на спарк-консоли?
Я хотел бы остановить различные сообщения, которые приходят на спарк-оболочку.
Я пытался редактировать log4j.properties
файл, чтобы остановить эти сообщения.
Вот содержимое log4j.properties
# Define the root logger with appender file
log4j.rootCategory=WARN, 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
Но сообщения все еще отображаются на консоли.
Вот несколько примеров сообщений
15/01/05 15:11:45 INFO SparkEnv: Registering BlockManagerMaster
15/01/05 15:11:45 INFO DiskBlockManager: Created local directory at /tmp/spark-local-20150105151145-b1ba
15/01/05 15:11:45 INFO MemoryStore: MemoryStore started with capacity 0.0 B.
15/01/05 15:11:45 INFO ConnectionManager: Bound socket to port 44728 with id = ConnectionManagerId(192.168.100.85,44728)
15/01/05 15:11:45 INFO BlockManagerMaster: Trying to register BlockManager
15/01/05 15:11:45 INFO BlockManagerMasterActor$BlockManagerInfo: Registering block manager 192.168.100.85:44728 with 0.0 B RAM
15/01/05 15:11:45 INFO BlockManagerMaster: Registered BlockManager
15/01/05 15:11:45 INFO HttpServer: Starting HTTP Server
15/01/05 15:11:45 INFO HttpBroadcast: Broadcast server star
Как мне это остановить?
22 ответа
Спасибо @AkhlD и @Sachin Janani за предложения об изменениях в .conf
файл.
Следующий код решил мою проблему:
1) Добавлено import org.apache.log4j.{Level, Logger}
в разделе импорта
2) Добавлена следующая строка после создания объекта контекста искры, т.е. после val sc = new SparkContext(conf)
:
val rootLogger = Logger.getRootLogger()
rootLogger.setLevel(Level.ERROR)
Отредактируйте свой 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)
После этого вы не увидите никаких журналов.
Другие варианты уровня включают в себя: all
, debug
, error
, fatal
, info
, off
, trace
, trace_int
, warn
Сразу после запуска spark-shell
тип;
sc.setLogLevel("ERROR")
В Spark 2.0:
spark = SparkSession.builder.getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
Все методы собраны с примерами
вступление
На самом деле, есть много способов сделать это. Некоторые из них сложнее других, но вам решать, какой из них подходит вам больше всего. Я постараюсь продемонстрировать их все.
# 1 Программно в вашем приложении
Кажется, это проще всего, но вам нужно будет перекомпилировать приложение, чтобы изменить эти настройки. Лично мне это не нравится, но работает нормально.
Пример:
import org.apache.log4j.{Level, Logger}
val rootLogger = Logger.getRootLogger()
rootLogger.setLevel(Level.ERROR)
Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
Logger.getLogger("org.spark-project").setLevel(Level.WARN)
Вы можете достичь гораздо большего, просто используя log4j
API.
Источник: [ Документы конфигурации Log4J, раздел конфигурации]
# 2 Pass log4j.properties
в течение spark-submit
Это очень сложно, но не невозможно. И мой любимый.
Log4J при запуске приложения всегда ищет и загружает log4j.properties
файл из classpath.
Однако при использовании spark-submit
Путь к классам в Spark Cluster имеет приоритет над классом в приложении! Вот почему размещение этого файла в вашем fat-jar не отменит настройки кластера!
добавлять
-Dlog4j.configuration=<location of configuration file>
вspark.driver.extraJavaOptions
(для водителя) илиspark.executor.extraJavaOptions
(для исполнителей).Обратите внимание, что при использовании файла
file:
протокол должен быть явно указан, а файл должен существовать локально на всех узлах.
Чтобы выполнить последнее условие, вы можете загрузить файл в место, доступное для узлов (например, hdfs
) или получить к нему доступ локально с помощью драйвера при использовании deploy-mode client
, Иначе:
загрузить кастом
log4j.properties
используя spark-submit, добавив его в--files
список файлов для загрузки с приложением.
Источник: документы Spark, отладка
шаги:
пример log4j.properties
:
# Blacklist all to warn level
log4j.rootCategory=WARN, 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
# Whitelist our app to info :)
log4j.logger.com.github.atais=INFO
проведение spark-submit
для режима кластера:
spark-submit \
--master yarn \
--deploy-mode cluster \
--conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" \
--conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" \
--files "/absolute/path/to/your/log4j.properties" \
--class com.github.atais.Main \
"SparkApp.jar"
Обратите внимание, что вы должны использовать --driver-java-options
при использовании client
Режим. Spark Docs, среда выполнения
проведение spark-submit
для режима клиента:
spark-submit \
--master yarn \
--deploy-mode cluster \
--driver-java-options "-Dlog4j.configuration=file:/absolute/path/to/your/log4j.properties \
--conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties" \
--files "/absolute/path/to/your/log4j.properties" \
--class com.github.atais.Main \
"SparkApp.jar"
Заметки:
- Файлы загружены в
spark-cluster
с--files
будет доступен в корневом каталоге, поэтому нет необходимости добавлять какой-либо путь вfile:log4j.properties
, - Файлы, перечисленные в
--files
должен быть указан абсолютный путь! file:
префикс в конфигурации URI является обязательным.
# 3 Редактировать кластеры conf/log4j.properties
Это изменяет файл конфигурации глобальной регистрации.
обновить
$SPARK_CONF_DIR/log4j.properties
файл, и он будет автоматически загружен вместе с другими конфигурациями.
Источник: Документация Spark, Отладка
Чтобы найти свой SPARK_CONF_DIR
ты можешь использовать spark-shell
:
atais@cluster:~$ spark-shell
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.1.1
/_/
scala> System.getenv("SPARK_CONF_DIR")
res0: String = /var/lib/spark/latest/conf
Теперь просто отредактируйте /var/lib/spark/latest/conf/log4j.properties
(с примером из метода #2), и все ваши приложения будут использовать эту конфигурацию.
# 4 Переопределить каталог конфигурации
Если вам нравится решение № 3, но вы хотите настроить его для каждого приложения, вы можете скопировать conf
папку, отредактируйте ее содержимое и укажите в качестве корневой конфигурации при spark-submit
,
Чтобы указать другой каталог конфигурации, отличный от стандартного
“SPARK_HOME/conf”
Вы можете установитьSPARK_CONF_DIR
, Spark будет использовать файлы конфигурации (spark-defaults.conf
,spark-env.sh
,log4j.properties
и т. д.) из этого каталога.
Источник: Spark Docs, Конфигурация
шаги:
- Копировать кластеры
conf
папка (подробнее, метод № 3) - редактировать
log4j.properties
в этой папке (пример в методе № 2) Задавать
SPARK_CONF_DIR
в эту папку, перед выполнениемspark-submit
,
пример:export SPARK_CONF_DIR=/absolute/path/to/custom/conf spark-submit \ --master yarn \ --deploy-mode cluster \ --class com.github.atais.Main \ "SparkApp.jar"
Заключение
Я не уверен, есть ли какой-либо другой метод, но я надеюсь, что это охватывает тему от А до Я. Если нет, не стесняйтесь пинговать меня в комментариях!
Приятного пути!
Используйте следующую команду, чтобы изменить уровень журнала при отправке приложения с использованием spark-submit или spark-sql:
spark-submit \
--conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=file:<file path>/log4j.xml" \
--conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:<file path>/log4j.xml"
Примечание: заменить <file path>
где log4j
Конфигурационный файл сохраняется.
Log4j.properties:
log4j.rootLogger=ERROR, console
# set the log level for these components
log4j.logger.com.test=DEBUG
log4j.logger.org=ERROR
log4j.logger.org.apache.spark=ERROR
log4j.logger.org.spark-project=ERROR
log4j.logger.org.apache.hadoop=ERROR
log4j.logger.io.netty=ERROR
log4j.logger.org.apache.zookeeper=ERROR
# add a ConsoleAppender to the logger stdout to write to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
# use a simple message format
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
</layout>
</appender>
<logger name="org.apache.spark">
<level value="error" />
</logger>
<logger name="org.spark-project">
<level value="error" />
</logger>
<logger name="org.apache.hadoop">
<level value="error" />
</logger>
<logger name="io.netty">
<level value="error" />
</logger>
<logger name="org.apache.zookeeper">
<level value="error" />
</logger>
<logger name="org">
<level value="error" />
</logger>
<root>
<priority value ="ERROR" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Переключитесь на FileAppender в log4j.xml, если вы хотите записывать журналы в файл, а не в консоль. LOG_DIR
переменная для каталога журналов, которую вы можете использовать, используя spark-submit --conf "spark.driver.extraJavaOptions=-D
,
<appender name="file" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${LOG_DIR}"/>
<param name="datePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %x - %m%n"/>
</layout>
</appender>
Еще одна важная вещь, которую следует понимать здесь: когда задание запускается в распределенном режиме (кластер режима развертывания и мастер в виде пряжи или мезо), файл конфигурации log4j должен существовать на узлах драйвера и рабочего (log4j.configuration=file:<file path>/log4j.xml
) иначе log4j init пожалуется
log4j: ОШИБКА Не удалось прочитать файл конфигурации [log4j.properties]. java.io.FileNotFoundException: log4j.properties (нет такого файла или каталога)
Намек на решение этой проблемы
Сохраните файл конфигурации log4j в распределенной файловой системе (HDFS или mesos) и добавьте внешнюю конфигурацию, используя log4j PropertyConfigurator. или используйте sparkContext addFile, чтобы сделать его доступным на каждом узле, затем используйте log4j PropertyConfigurator, чтобы перезагрузить конфигурацию.
Вы устанавливаете отключение журналов, устанавливая его уровень на OFF следующим образом:
Logger.getLogger("org").setLevel(Level.OFF);
Logger.getLogger("akka").setLevel(Level.OFF);
или отредактируйте файл журнала и отключите его, просто изменив следующее свойство:
log4j.rootCategory=OFF, console
Я просто добавляю эту строку ко всем моим сценариям pyspark сверху чуть ниже операторов import.
SparkSession.builder.getOrCreate().sparkContext.setLogLevel("ERROR")
пример заголовка моих скриптов pyspark
from pyspark.sql import SparkSession, functions as fs
SparkSession.builder.getOrCreate().sparkContext.setLogLevel("ERROR")
Ответы выше верны, но не помогли мне, поскольку мне потребовалась дополнительная информация.
Я только что настроил Spark, поэтому в файле log4j все еще был суффикс ".template", и он не читался. Я полагаю, что в этом случае по умолчанию в журнале Spark используется ведение логов.
Так что если вы похожи на меня и обнаружите, что приведенные выше ответы не помогли, то, возможно, вам тоже придется удалить суффикс ".template" из файла conf log4j, и тогда вышеприведенное работает отлично!
http://apache-spark-user-list.1001560.n3.nabble.com/disable-log4j-for-spark-shell-td11278.html
Добавление следующего в PySpark помогло мне:
self.spark.sparkContext.setLogLevel("ERROR")
self.spark - это сеанс искры (self.spark = spark_builder.getOrCreate()
)
Просто добавьте ниже param к вашей команде spark-submit
--conf "spark.driver.extraJavaOptions=-Dlog4jspark.root.logger=WARN,console"
Проверьте точное имя свойства (log4jspark.root.logger здесь) из файла log4j.properties. Надеюсь, это поможет, ура!
В Python/Spark мы можем сделать:
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 )
После определения Sparkcontaxt 'sc' вызовите эту функцию с помощью: quiet_logs( sc)
ТЛ; др
Для Spark Context вы можете использовать:
sc.setLogLevel(<logLevel>)
где
loglevel
может быть ВСЕ, ОТЛАДКА, ОШИБКА, ФАТАЛЬНО, ИНФОРМАЦИЯ, ВЫКЛ, TRACE или WARN.
Подробности-
Внутренне setLogLevel
звонки org.apache.log4j.Level.toLevel(logLevel)
что он затем использует для установки с помощью org.apache.log4j.LogManager.getRootLogger().setLevel(level)
,
Вы можете напрямую установить уровни регистрации
OFF
с помощью:LogManager.getLogger("org").setLevel(Level.OFF)
Вы можете настроить ведение журнала по умолчанию для оболочки Spark в conf/log4j.properties
, использование conf/log4j.properties.template
в качестве отправной точки.
Установка уровней журнала в Spark-приложениях
В автономных приложениях Spark или в сеансе Spark Shell используйте следующее:
import org.apache.log4j.{Level, Logger}
Logger.getLogger(classOf[RackResolver]).getLevel
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)
Отключение регистрации (в log4j):
Используйте следующее в conf/log4j.properties
чтобы полностью отключить ведение журнала:
log4j.logger.org=OFF
Справка: Освоение искры Яцека Ласковского.
Просто сделать в командной строке...
spark2-submit --driver-java-options="-Droot.logger=ERROR,console"
..другие опции..
для Spark 3.5.0: перейдите по ссылке/spark-3.5.0-bin-hadoop3/conf
папку и запустить
cp log4j2.properties.template log4j2.properties
Затем в новом файле изменитеrootLogger.level
отinfo
кwarn
Интересная идея состоит в том, чтобы использовать RollingAppender, как предложено здесь: http://shzhangji.com/blog/2015/05/31/spark-streaming-logging-configuration/ чтобы вы не "напирали" пространство консоли, но все еще сможете увидеть результаты в $YOUR_LOG_PATH_HERE/${dm.logging.name}.log.
log4j.rootLogger=INFO, rolling
log4j.appender.rolling=org.apache.log4j.RollingFileAppender
log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling.layout.conversionPattern=[%d] %p %m (%c)%n
log4j.appender.rolling.maxFileSize=50MB
log4j.appender.rolling.maxBackupIndex=5
log4j.appender.rolling.file=$YOUR_LOG_PATH_HERE/${dm.logging.name}.log
log4j.appender.rolling.encoding=UTF-8
Другой метод, который устраняет причину, состоит в том, чтобы наблюдать, какие типы журналов у вас обычно есть (поступающие из разных модулей и зависимостей), и устанавливать для каждой гранулярность для ведения журнала, одновременно превращая "тихие" сторонние журналы, которые слишком многословны:
Например,
# Silence akka remoting
log4j.logger.Remoting=ERROR
log4j.logger.akka.event.slf4j=ERROR
log4j.logger.org.spark-project.jetty.server=ERROR
log4j.logger.org.apache.spark=ERROR
log4j.logger.com.anjuke.dm=${dm.logging.level}
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
Если у вас нет возможности редактировать код Java для вставки .setLogLevel()
заявления и вы не хотите, чтобы еще больше внешних файлов для развертывания, вы можете использовать метод грубой силы, чтобы решить эту проблему. Просто отфильтруйте строки INFO, используя grep.
spark-submit --deploy-mode client --master local <rest-of-cmd> | grep -v -F "INFO"
Другой способ полной остановки журналов:
import org.apache.log4j.Appender;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.varia.NullAppender;
public class SomeClass {
public static void main(String[] args) {
Appender nullAppender = new NullAppender();
BasicConfigurator.configure(nullAppender);
{...more code here...}
}
}
Это сработало для меня. NullAppender - это
Приложение, которое игнорирует события журнала. (https://logging.apache.org/log4j/2.x/log4j-core/apidocs/org/apache/logging/log4j/core/appender/NullAppender.html)
- Настройте conf/log4j.properties, как описано в другом log4j.rootCategory = ОШИБКА, консоль
- Убедитесь, что во время выполнения задания spark вы передаете флаг --file с путем к файлу log4j.properties
- Если он все еще не работает, у вас может быть jar с log4j.properties, который вызывается перед вашими новыми log4j.properties. Удалите этот log4j.properties из jar (если это необходимо)
Если кто-то еще застрял на этом,
ничего из вышеперечисленного у меня не сработало. Мне пришлось удалить
implementation group: "ch.qos.logback", name: "logback-classic", version: "1.2.3"
implementation group: 'com.typesafe.scala-logging', name: "scala-logging_$scalaVersion", version: '3.9.2'
из моего build.gradle, чтобы журналы исчезли. TL; DR: не импортируйте никакие другие фреймворки ведения журналов, все будет в порядке, просто используяorg.apache.log4j.Logger
Этот работал для меня. Только для сообщений об ошибках, которые будут отображаться как stdout
, log4j.properties
файл может выглядеть так:
# Root logger option
log4j.rootLogger=ERROR, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
ПРИМЕЧАНИЕ: положить
log4j.properties
файл вsrc/main/resources
папка, чтобы быть эффективной. И еслиlog4j.properties
не существует (имеется в видуspark
используетlog4j-defaults.properties
файл), то вы можете создать его, перейдя вSPARK_HOME/conf
а потомmv log4j.properties.template log4j.properties
а затем приступить к вышеуказанным изменениям.
В дополнение ко всем вышеупомянутым постам, вот что решило проблему для меня.
Spark использует slf4j для привязки к логгерам. Если log4j не первая найденная привязка, вы можете редактировать файлы log4j.properties так, как вам хочется, регистраторы даже не используются. Например, это может быть возможный вывод SLF4J:
SLF4J: путь к классу содержит несколько привязок SLF4J. SLF4J: Обнаружена привязка в [jar:file:/C:/Users/~/.m2/repository/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar!/ Org/slf4j/impl/StaticLoggerBinder.class] SLF4J: найдена привязка в [jar:file:/C:/Users/~/.m2/repository/org/slf4j/slf4j-log4j12/1.7.19/slf4j-log4j12-1.7.19.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: См. http://www.slf4j.org/codes.html для объяснения. SLF4J: фактическая привязка имеет тип [org.slf4j.impl.SimpleLoggerFactory]
Так что здесь был использован SimpleLoggerFactory, который не заботится о настройках log4j.
Исключая пакет slf4j-simple из моего проекта через
<dependency>
...
<exclusions>
...
<exclusion>
<artifactId>slf4j-simple</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
решена проблема, так как теперь используется привязка логгера log4j и все настройки в log4j.properties соблюдаются. К сведению, мой файл свойств log4j содержит (помимо обычной конфигурации)
log4j.rootLogger=WARN, stdout
...
log4j.category.org.apache.spark = WARN
log4j.category.org.apache.parquet.hadoop.ParquetRecordReader = FATAL
log4j.additivity.org.apache.parquet.hadoop.ParquetRecordReader=false
log4j.logger.org.apache.parquet.hadoop.ParquetRecordReader=OFF
Надеюсь это поможет!