J'aimerais arrêter divers messages qui arrivent sur spark Shell.
J'ai essayé d'éditer le fichier log4j.properties
afin d'arrêter ces messages.
Voici le contenu de 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
Mais les messages sont toujours affichés sur la console.
Voici quelques exemples de messages
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
Comment puis-je les arrêter?
Merci à AkhlD et @Sachin Janani pour les modifications suggérées dans le fichier .conf
.
Le code suivant a résolu mon problème:
1) Ajout de import org.Apache.log4j.{Level, Logger}
dans la section d'importation
2) Ajouté la ligne suivante après la création de spark objet de contexte, c'est-à-dire après val sc = new SparkContext(conf)
:
val rootLogger = Logger.getRootLogger()
rootLogger.setLevel(Level.ERROR)
Editez votre fichier conf/log4j.properties
et changez la ligne suivante:
log4j.rootCategory=INFO, console
à
log4j.rootCategory=ERROR, console
Une autre approche serait de:
Lancez spark-Shell et tapez ce qui suit:
import org.Apache.log4j.Logger
import org.Apache.log4j.Level
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)
Vous ne verrez plus aucun journal après cela.
Les autres options de niveau incluent: all
, debug
, error
, fatal
, info
, off
, trace
, trace_int
, warn
Des détails sur chacun d’entre eux sont disponibles dans la documentation.
Juste après le démarrage de spark-Shell
, tapez;
sc.setLogLevel("ERROR")
Dans Spark 2.0:
spark = SparkSession.builder.getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
Utilisez la commande ci-dessous pour modifier le niveau de journalisation lors de la soumission d'une application à l'aide de spark-submit ou 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"
Remarque: remplacez <file path>
où log4j
fichier de configuration est stocké.
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>
Basculez vers FileAppender dans log4j.xml si vous souhaitez écrire les journaux dans un fichier plutôt que sur la console. LOG_DIR
est une variable pour le répertoire des journaux que vous pouvez fournir à l'aide de 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>
Une autre chose importante à comprendre ici est que, lorsque le travail est lancé en mode distribué (cluster en mode déploiement et maître en tant que fil ou mésos), le fichier de configuration log4j doit exister sur les noeuds de pilote et de travailleur (log4j.configuration=file:<file path>/log4j.xml
), sinon log4j init se plaindra. -
log4j: ERROR Impossible de lire le fichier de configuration [log4j.properties]. Java.io.FileNotFoundException: log4j.properties (aucun fichier ou répertoire de ce type)
Astuce pour résoudre ce problème
Conservez le fichier de configuration log4j dans le système de fichiers distribué (HDFS ou mesos) et ajoutez une configuration externe à l'aide de log4j PropertyConfigurator . ou utilisez sparkContext addFile pour le rendre disponible sur chaque nœud, puis utilisez log4j PropertyConfigurator pour recharger la configuration.
Pour désactiver les journaux, définissez son niveau sur OFF comme suit:
Logger.getLogger("org").setLevel(Level.OFF);
Logger.getLogger("akka").setLevel(Level.OFF);
ou éditez le fichier journal et désactivez le niveau de journalisation en modifiant simplement la propriété suivante:
log4j.rootCategory=OFF, console
Je viens d'ajouter cette ligne à tous mes scripts pyspark en haut juste en dessous des instructions d'importation.
SparkSession.builder.getOrCreate().sparkContext.setLogLevel("ERROR")
exemple en-tête de mes scripts pyspark
from pyspark.sql import SparkSession, functions as fs
SparkSession.builder.getOrCreate().sparkContext.setLogLevel("ERROR")
Les réponses ci-dessus sont correctes mais ne m'ont pas vraiment aidé car il y avait des informations supplémentaires dont j'avais besoin.
Je viens de configurer Spark afin que le fichier log4j ait toujours le suffixe ".template" et qu'il ne soit pas lu. Je pense que la consignation prend alors par défaut la valeur Spark config de consignation de base.
Donc, si vous êtes comme moi et constatez que les réponses ci-dessus ne vous ont pas aidé, alors vous aussi devez peut-être supprimer le suffixe ".template" de votre fichier de configuration log4j, et le précédent fonctionne parfaitement!
http://Apache-spark-user-list.1001560.n3.nabble.com/disable-log4j-for-spark-Shell-td11278.html
En fait, il y a plusieurs façons de le faire . Certains sont plus difficiles que d'autres, mais c'est à vous de choisir lequel vous convient le mieux. Je vais essayer de les présenter tous.
Cela semble être le plus simple, mais vous devrez recompiler votre application pour modifier ces paramètres. Personnellement, je n'aime pas ça mais ça marche bien.
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)
Vous pouvez obtenir beaucoup plus simplement en utilisant log4j
API.
Source: [ Documents de configuration Log4J , Section de configuration]
log4j.properties
pendant spark-submit
Celui-ci est très délicat, mais pas impossible. Et mon préféré.
Au démarrage de l'application, Log4J recherche et charge en permanence le fichier log4j.properties
à partir du chemin de classe.
Cependant, lorsque vous utilisez spark-submit
[Spark, le chemin d'accès aux classes du cluster a la priorité sur celui de l'application! C'est pourquoi le fait de placer ce fichier dans votre fat-jar ne remplacera pas les paramètres du cluster!
Ajoutez
-Dlog4j.configuration=<location of configuration file>
àspark.driver.extraJavaOptions
(pour le pilote) ouspark.executor.extraJavaOptions
(pour les exécuteurs) .Notez que si vous utilisez un fichier, le protocole
file:
doit être explicitement fourni et le fichier doit exister localement sur tous les nœuds .
Pour satisfaire à la dernière condition, vous pouvez télécharger le fichier à l'emplacement disponible pour les nœuds (comme hdfs
) ou y accéder localement avec le pilote si vous utilisez deploy-mode client
. Autrement:
téléchargez un
log4j.properties
personnalisé à l'aide de spark-submit, en l'ajoutant à la liste--files
des fichiers à télécharger avec l'application.
Source: documentation Spark, débogage
Exemple 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
Exécution de spark-submit
, pour le mode cluster:
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"
Notez que vous devez utiliser --driver-Java-options
si vous utilisez le mode client
. Docs Spark, env. Runtime
Exécution de spark-submit
, pour le mode client:
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
avec --files
seront disponibles au répertoire racine. Il n’est donc pas nécessaire d’ajouter de chemin dans file:log4j.properties
.--files
doivent être fournis avec un chemin absolu!file:
le préfixe dans l'URI de configuration est obligatoire.conf/log4j.properties
du clusterCela modifie le fichier de configuration de la journalisation globale .
mettez à jour le fichier
$SPARK_CONF_DIR/log4j.properties
et il sera automatiquement téléchargé avec les autres configurations.
Source: documentation Spark, débogage
Pour trouver votre SPARK_CONF_DIR
, vous pouvez utiliser 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
Maintenant, éditez simplement /var/lib/spark/latest/conf/log4j.properties
(avec l'exemple de la méthode n ° 2) et toutes vos applications partageront cette configuration.
Si vous aimez la solution n ° 3, mais souhaitez la personnaliser pour chaque application, vous pouvez réellement copier le dossier conf
, en modifier le contenu et spécifier la configuration racine pendant spark-submit
.
Pour spécifier un autre répertoire de configuration que le répertoire par défaut
“SPARK_HOME/conf”
, vous pouvez définirSPARK_CONF_DIR
. Spark utilisera les fichiers de configuration (spark-defaults.conf
,spark-env.sh
,log4j.properties
, etc ) de ce répertoire.
Source: documentation Spark, Configuration
conf
du cluster (plus d'informations, méthode 3)log4j.properties
dans ce dossier (exemple de la méthode n ° 2)Définissez SPARK_CONF_DIR
dans ce dossier, avant d’exécuter spark-submit
,
exemple:
export SPARK_CONF_DIR=/absolute/path/to/custom/conf
spark-submit \
--master yarn \
--deploy-mode cluster \
--class com.github.atais.Main \
"SparkApp.jar"
Je ne suis pas sûr s'il existe une autre méthode, mais j'espère que cela couvre le sujet de A à Z. Sinon, n'hésitez pas à m'envoyer une requête dans les commentaires!
Profitez de votre chemin!
Pour le contexte Spark, vous pouvez utiliser:
sc.setLogLevel(<logLevel>)
où
loglevel
peut être ALL, DEBUG, ERREUR, FATAL, INFO, OFF, TRACE ou WARN.
En interne, setLogLevel
appelle org.Apache.log4j.Level.toLevel(logLevel)
qu'il utilise ensuite pour régler à l'aide de org.Apache.log4j.LogManager.getRootLogger().setLevel(level)
.
Vous pouvez directement définir les niveaux de journalisation sur
OFF
en utilisant:LogManager.getLogger("org").setLevel(Level.OFF)
Vous pouvez configurer la journalisation par défaut pour Spark Shell dans conf/log4j.properties
. Utilisez conf/log4j.properties.template
comme point de départ.
Dans les applications autonomes Spark ou en session de shell Spark, utilisez les éléments suivants:
import org.Apache.log4j.{Level, Logger}
Logger.getLogger(classOf[RackResolver]).getLevel
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)
Utilisez les éléments suivants dans conf/log4j.properties
pour désactiver complètement la journalisation:
log4j.logger.org=OFF
Référence: Mastering Spark par Jacek Laskowski.
En Python/Spark, nous pouvons faire:
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 )
Les définitions suivantes de Sparkcontaxt 'sc' appellent cette fonction par: quiet_logs (sc)
Ajoutez simplement les paramètres ci-dessous à votre commande spark-Shell OR spark-submit
--conf "spark.driver.extraJavaOptions=-Dlog4jspark.root.logger=WARN,console"
Vérifiez le nom exact de la propriété (log4jspark.root.logger ici) à partir du fichier log4j.properties. J'espère que cela aide, à la vôtre!
Une idée intéressante consiste à utiliser RollingAppender comme suggéré ici: http://shzhangji.com/blog/2015/05/31/spark-streaming-logging-configuration/ afin que vous ne l'utilisiez pas " polute "l’espace console, mais vous pouvez toujours voir les résultats sous $ 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
Une autre méthode permettant de résoudre ce problème consiste à observer le type de journalisation existant (provenant de différents modules et dépendances) et à définir pour chacun la granularité de la journalisation, tout en transformant des journaux tiers "calmes" qui sont trop détaillés:
Par exemple,
# 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
Simple à faire en ligne de commande ...
spark2-submit --driver-Java-options="-Droot.logger=ERROR,console"
..autres options ..
Si vous ne pouvez pas modifier le code Java pour insérer les instructions .setLogLevel()
et si vous ne souhaitez pas déployer davantage de fichiers externes, vous pouvez utiliser un moyen brutal de résoudre le problème. cette. Il suffit de filtrer les lignes INFO en utilisant grep.
spark-submit --deploy-mode client --master local <rest-of-cmd> | grep -v -F "INFO"
Celui-ci a fonctionné pour moi. Pour que seuls les messages ERROR à afficher sous forme de fichier stdout
, log4j.properties
puissent ressembler à ceci:
# 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
REMARQUE: Placez le fichier
log4j.properties
dans le dossiersrc/main/resources
pour qu'il soit effectif. Et silog4j.properties
n’existe pas (c’est-à-dire quespark
utilise le fichierlog4j-defaults.properties
), vous pouvez le créer en accédant àSPARK_HOME/conf
, puis àmv log4j.properties.template log4j.properties
, puis à continuer. avec les modifications ci-dessus.
sparkContext.setLogLevel("OFF")
Si quelqu'un d'autre est coincé là-dessus,
rien de ce qui précède n'a fonctionné pour moi. Je devais enlever
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'
depuis mon build.gradle pour que les journaux disparaissent. TLDR: N'importez aucun autre framework de journalisation, vous devriez utiliser org.Apache.log4j.Logger
En plus de tous les articles ci-dessus, voici ce qui a résolu le problème pour moi.
Spark utilise slf4j pour se lier à des enregistreurs. Si log4j n'est pas la première liaison trouvée, vous pouvez modifier les fichiers log4j.properties à votre guise, les enregistreurs ne sont même pas utilisés. Par exemple, cela pourrait être une sortie possible de SLF4J:
SLF4J: Le chemin d'accès aux classes contient plusieurs liaisons SLF4J. SLF4J: Liaison trouvée dans [jar: fichier:/C: /Users/~/.m2/repository/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar!/Org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Liaison trouvée dans [jar: fichier:/C: /Users/~/.m2/repository/org/slf4j/slf4j-log4j12/1.7.19/slf4j-log4j12-1.7.19.jar ! /org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Voir http://www.slf4j.org/codes.html#multiple_bindings pour une explication. SLF4J: La liaison réelle est de type [org.slf4j.impl.SimpleLoggerFactory]
Donc, ici, le SimpleLoggerFactory a été utilisé, qui ne se soucie pas des paramètres de log4j.
Exclure le paquet slf4j-simple de mon projet via
<dependency>
...
<exclusions>
...
<exclusion>
<artifactId>slf4j-simple</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
le problème a été résolu, car la liaison log4j est utilisée et les paramètres de log4j.properties sont respectés. F.Y.I. mon fichier de propriétés log4j contient (en plus de la configuration normale)
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
J'espère que cela t'aides!