Как остановить отображение сообщений 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"

Заметки:

  1. Файлы загружены в spark-cluster с --files будет доступен в корневом каталоге, поэтому нет необходимости добавлять какой-либо путь в file:log4j.properties,
  2. Файлы, перечисленные в --files должен быть указан абсолютный путь!
  3. 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, Конфигурация

шаги:

  1. Копировать кластеры conf папка (подробнее, метод № 3)
  2. редактировать log4j.properties в этой папке (пример в методе № 2)
  3. Задавать 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)

  1. Настройте conf/log4j.properties, как описано в другом log4j.rootCategory = ОШИБКА, консоль
  2. Убедитесь, что во время выполнения задания spark вы передаете флаг --file с путем к файлу log4j.properties
  3. Если он все еще не работает, у вас может быть 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 а затем приступить к вышеуказанным изменениям.

sparkContext.setLogLevel("OFF")

В дополнение ко всем вышеупомянутым постам, вот что решило проблему для меня.

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

Надеюсь это поможет!

Другие вопросы по тегам