Jak wyłączyć logowanie INFO w Spark?

144

Zainstalowałem Sparka za pomocą przewodnika AWS EC2 i mogę poprawnie uruchomić program za pomocą bin/pysparkskryptu, aby dostać się do podpowiedzi iskry, a także mogę pomyślnie wykonać przewodnik Szybki start.

Jednak do końca życia nie mogę wymyślić, jak zatrzymać wszystkie szczegółowe INFOrejestrowanie po każdym poleceniu.

Wypróbowałem prawie każdy możliwy scenariusz w poniższym kodzie (komentowanie, ustawienie na OFF) w moim log4j.propertiespliku w conffolderze, z którego uruchamiam aplikację, a także na każdym węźle i nic nie robi. Ciągle otrzymuję instrukcje logowania INFOdrukowane po wykonaniu każdej instrukcji.

Jestem bardzo zdezorientowany, jak to ma działać.

#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

Oto moja pełna ścieżka klas, kiedy używam SPARK_PRINT_LAUNCH_COMMAND:

Spark Command: /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

zawartość 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"
horatio1701d
źródło
W programie Spark po utworzeniu sesji możesz ustawić poziom Logowania, jak podano poniżej dla Java SparkSession spark = SparkSession.builder (). Master ("local"). GetOrCreate (); spark.sparkContext (). setLogLevel ("INFO");
iKing

Odpowiedzi:

158

Po prostu wykonaj to polecenie w katalogu Spark:

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

Edytuj 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

Zastąp w pierwszym wierszu:

log4j.rootCategory=INFO, console

przez:

log4j.rootCategory=WARN, console

Zapisz i uruchom ponownie powłokę. U mnie działa w przypadku Spark 1.1.0 i Spark 1.5.1 na OS X.

poiuytrez
źródło
1
Pomogło to, ważne, aby zdać sobie sprawę, że log4j.properties nie istnieje, dopóki go nie utworzysz. Na Ubuntu nie musiałem restartować, aby zmiany zostały wprowadzone.
uciążliwy
Nie działa dla mnie. Spark 1.5. RHEL 6. CDH 5.5. Próbowałem utworzyć nowy plik /opt/cloudera/parcels/CDH/etc/spark/conf.dist/log4j.properties i zmienić jak wyjaśniono powyżej. Próbowałem także edytować istniejący plik /etc/spark/conf/log4j.properties. Brak efektu dla muszli pysparka ani dla muszli pysparka.
Tagar
czy musimy to zrobić dla wszystkich węzłów w klastrze iskier?
chmura
54

Zainspirowany pyspark / tests.py, który zrobiłem

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 )

Wywołanie tego zaraz po utworzeniu SparkContext zmniejszyło liczbę wierszy stderr rejestrowanych dla mojego testu z 2647 do 163. Jednak samo utworzenie SparkContext rejestruje 163, aż do

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

i nie jest dla mnie jasne, jak dostosować je programowo.

FDS
źródło
2
jeśli masz jakieś pomysły, jak dostosować te linie, podziel się nimi
Irene,
Myślę, że nie ma bezpośredniego rozwiązania, aby zmienić domyślny poziom debugowania w PySpark .. do momentu uruchomienia SparkContext. Ponieważ sc._jvm jest tworzony dopiero po utworzeniu SC. Nadal możesz to zmienić za pomocą pliku log4j.properies, chociaż omówiono to w innych odpowiedziach. Spark powinien utworzyć na przykład zmienną spark.default.logging, którą można przekazać do SparkConf jako opcję zastąpienia domyślnego poziomu głównego rejestratora.
Tagar
37

W Spark 2.0 możesz również skonfigurować go dynamicznie dla swojej aplikacji za pomocą setLogLevel :

    from pyspark.sql import SparkSession
    spark = SparkSession.builder.\
        master('local').\
        appName('foo').\
        getOrCreate()
    spark.sparkContext.setLogLevel('WARN')

W konsoli pyspark domyślna sparksesja będzie już dostępna.

mdh
źródło
Właśnie zablokowałeś komunikaty dziennika. Ale rzeczywisty kod działa w tle. Jeśli widzisz użycie procesora. Spark zużywa dużo procesora, nawet gdy jest bezczynny.
hurelhuyag
To było dokładnie to rozwiązanie do pracy PySpark, gdzie log4jnie jest dostępny.
yeliabsalohcin
35

Edytuj plik conf / log4j.properties i zmień następujący wiersz:

   log4j.rootCategory=INFO, console

do

    log4j.rootCategory=ERROR, console

Innym podejściem byłoby:

Odpal osłonę iskrową i wpisz:

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

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

Po tym nie zobaczysz żadnych dzienników.

AkhlD
źródło
3
późniejsza opcja działa dla spark-shell (scala), ale co należy zrobić w przypadku pyspark bez zmiany pliku log4j?
hmi2015
Zmiana właściwości pliku log4j do „ostrzec” byłoby lepiej, ale w przeciwnym razie ta odpowiedź przez wannik działa na zmianę poziomu dziennika do konsoli pyspark stackoverflow.com/a/34487962/127971
Michael
32
>>> log4j = sc._jvm.org.apache.log4j
>>> log4j.LogManager.getRootLogger().setLevel(log4j.Level.ERROR)
wannik
źródło
Użyłem tego do pysparka. Świetnie sprawdza się jako hack jednoliniowy. Nadal otrzymuję głupie komunikaty o śmierci YarnExecutor, które nie powinny być błędem, imho. I tak to idzie ...
jatal
2
To blokuje rejestrowanie po jego wykonaniu, ale niestety przed tym punktem istnieje wiele dzienników INFO.
DavidJ
28

W przypadku PySpark możesz również ustawić poziom logowania w swoich skryptach za pomocą sc.setLogLevel("FATAL"). Z dokumentów :

Kontroluj nasz logLevel. Zastępuje wszelkie ustawienia dziennika zdefiniowane przez użytkownika. Prawidłowe poziomy dziennika obejmują: ALL, DEBUG, ERROR, FATAL, INFO, OFF, TRACE, WARN

Galen Long
źródło
Świetne rozwiązanie, które działa dla wersji Spark nowszych niż 1.4 (czyli od połowy 2015 roku).
Jealie
Wypróbowałem to ze Spark 1.6.2 i Scalą i wydaje się, że nie działa
Yeikel
@Yeikel To rozwiązanie jest przeznaczone dla PySpark. Przepraszam, że nie zostało to wyjaśnione - teraz poprawię odpowiedź.
Galen Long,
15

Możesz użyć setLogLevel

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

spark.sparkContext.setLogLevel("WARN")
Unmesha SreeVeni
źródło
14

Może to być spowodowane tym, jak Spark oblicza swoją ścieżkę klas. Moje przeczucie jest takie, że log4j.propertiesplik Hadoopa pojawia się przed Sparkiem na ścieżce klas, uniemożliwiając wprowadzenie zmian.

Jeśli uciekniesz

SPARK_PRINT_LAUNCH_COMMAND=1 bin/spark-shell

następnie Spark wypisze pełną ścieżkę klasy używaną do uruchomienia powłoki; w moim przypadku rozumiem

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

gdzie /root/ephemeral-hdfs/confjest na początku ścieżki klas.

Otworzyłem problem [SPARK-2913], aby to naprawić w następnym wydaniu (wkrótce powinienem mieć łatkę).

Tymczasem oto kilka obejść:

  • Dodaj export SPARK_SUBMIT_CLASSPATH="$FWDIR/conf"do spark-env.sh.
  • Usuń (lub zmień nazwę) /root/ephemeral-hdfs/conf/log4j.properties.
Josh Rosen
źródło
Dziękuję Ci. Próbowałem dodać to do mojego pliku spark-env.sh, a także próbowałem usunąć plik log4j.properties, ale nadal otrzymywałem INFO. Dodałem pełną ścieżkę do klasy do pytania.
horatio1701d
Dzięki za dodatkowe informacje. Czy możesz również opublikować zawartość spark-env.sh (możesz redagować prywatne informacje, takie jak nazwy hostów)?
Josh Rosen
Dziękuję Ci. wysłane spark-env.sh. Przepraszam, jeśli nie rozumiem, jak uruchomić podstawową konfigurację. Po prostu zostawiłem wszystko jako domyślne na razie tylko po to, aby wypróbować kilka testów.
horatio1701d
9

Spark 1.6.2:

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

Spark 2.x:

spark.sparkContext.setLogLevel('WARN')

(iskra będąca SparkSession)

Alternatywnie stare metody,

Zmień nazwę conf/log4j.properties.templatena conf/log4j.propertiesw Spark Dir.

W programie log4j.propertieszmień log4j.rootCategory=INFO, consolenalog4j.rootCategory=WARN, console

Dostępne różne poziomy dziennika:

  • WYŁ. (Najbardziej szczegółowe, bez logowania)
  • FATAL (najbardziej szczegółowe, mało danych)
  • BŁĄD - rejestruj się tylko w przypadku błędów
  • OSTRZEŻENIE - loguj się tylko w przypadku ostrzeżeń lub błędów
  • INFO (domyślnie)
  • DEBUGOWANIE - kroki szczegółów dziennika (i wszystkie dzienniki wymienione powyżej)
  • TRACE (najmniej szczegółowe, dużo danych)
  • WSZYSTKIE (najmniej szczegółowe, wszystkie dane)
Ani Menon
źródło
8

Sposób programowy

spark.sparkContext.setLogLevel("WARN")

dostępne opcje

ERROR
WARN 
INFO 
samotna gwiazda
źródło
5

Użyłem tego z Amazon EC2 z 1 master i 2 slave i Spark 1.2.1.

# Step 1. Change config file on the master node
nano /root/ephemeral-hdfs/conf/log4j.properties

# Before
hadoop.root.logger=INFO,console
# After
hadoop.root.logger=WARN,console

# Step 2. Replicate this change to slaves
~/spark-ec2/copy-dir /root/ephemeral-hdfs/conf/
oleksii
źródło
4

Po prostu dodaj poniższy parametr do polecenia wysyłania iskry

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

To tymczasowo przesłania wartość systemową tylko dla tego zadania. Sprawdź dokładną nazwę właściwości (tutaj log4jspark.root.logger) z pliku log4j.properties.

Mam nadzieję, że to pomoże!

Gaurav Adurkar
źródło
Innym, który uznałem za przydatny, jest to, że możesz określić plik log4j.properties:--conf spark.driver.extraJavaOptions='-Dlog4j.configuration=file:/home/foobar/log4j.properties
selle
2

Poniższy fragment kodu dla użytkowników Scala:

Opcja 1 :

Poniżej fragment możesz dodać na poziomie pliku

import org.apache.log4j.{Level, Logger}
Logger.getLogger("org").setLevel(Level.WARN)

Opcja 2 :

Uwaga: która będzie miała zastosowanie do wszystkich aplikacji korzystających z sesji Spark.

import org.apache.spark.sql.SparkSession

  private[this] implicit val spark = SparkSession.builder().master("local[*]").getOrCreate()

spark.sparkContext.setLogLevel("WARN")

Wariant 3:

Uwaga: Tę konfigurację należy dodać do pliku log4j.properties .. (na przykład /etc/spark/conf/log4j.properties (gdzie znajduje się instalacja Spark) lub na poziomie folderu projektu log4j.properties), ponieważ zmiana odbywa się na poziom modułu. Będzie to miało zastosowanie do wszystkich aplikacji.

log4j.rootCategory=ERROR, console

IMHO, opcja 1 jest rozsądna, ponieważ można ją wyłączyć na poziomie pliku.

Ram Ghadiyaram
źródło
1

Sposób, w jaki to robię, to:

w miejscu, w którym uruchamiam spark-submitskrypt

$ cp /etc/spark/conf/log4j.properties .
$ nano log4j.properties

zmień INFOna dowolny poziom logowania, który chcesz, a następnie uruchomspark-submit

user3827333
źródło
cp /etc/spark/conf/log4j.properties.template .
deepelement
0

Jeśli chcesz nadal korzystać z logowania (narzędzia do rejestrowania dla Pythona), możesz spróbować podzielić konfiguracje dla swojej aplikacji i dla Sparka:

LoggerManager()
logger = logging.getLogger(__name__)
loggerSpark = logging.getLogger('py4j')
loggerSpark.setLevel('WARNING')
santifinland
źródło