2014-12-02 4 views
19

So dank leicht googleable Blogs Ich habe versucht:Wie kann man die Spark-Protokollierung von Komponententests unterdrücken?

import org.specs2.mutable.Specification 

class SparkEngineSpecs extends Specification { 
    sequential 

    def setLogLevels(level: Level, loggers: Seq[String]): Map[String, Level] = loggers.map(loggerName => { 
    val logger = Logger.getLogger(loggerName) 
    val prevLevel = logger.getLevel 
    logger.setLevel(level) 
    loggerName -> prevLevel 
    }).toMap 

    setLogLevels(Level.WARN, Seq("spark", "org.eclipse.jetty", "akka")) 

    val sc = new SparkContext(new SparkConf().setMaster("local").setAppName("Test Spark Engine")) 

    // ... my unit tests 

Aber leider funktioniert es nicht, ich habe noch eine Menge Funken Ausgabe erhalten, zB:

14/12/02 12:01:56 INFO MemoryStore: Block broadcast_4 of size 4184 dropped from memory (free 583461216) 
14/12/02 12:01:56 INFO ContextCleaner: Cleaned broadcast 4 
14/12/02 12:01:56 INFO ContextCleaner: Cleaned shuffle 4 
14/12/02 12:01:56 INFO ShuffleBlockManager: Deleted all files for shuffle 4 

Antwort

32

Fügen Sie den folgenden Code in die log4j.properties Datei im src/test/resources dir, erstellen Sie die Datei/dir, wenn nicht

# Change this to set Spark log level 
log4j.logger.org.apache.spark=WARN 

# Silence akka remoting 
log4j.logger.Remoting=WARN 

# Ignore messages below warning level from Jetty, because it's a bit verbose 
log4j.logger.org.eclipse.jetty=WARN 

existieren Wenn ich meine Unit-Tests (ich bin mit JUnit und Maven) laufen, ich nur Sie erhalten WARN-Level-Logs, das heißt, es wird nicht mehr mit INFO-Level-Logs überladen (obwohl sie manchmal für das Debuggen nützlich sein können).

Ich hoffe, das hilft.

+0

Funktioniert für SBT mit specs2 – samthebest

+1

danke @Emre. es funktionierte wie Charme für Java in IntelliJ Idee. –

2

Sie einen separaten Logback verwenden können Konfiguration für Tests. Abhängig von Ihrer Umgebung ist es möglich, dass Sie nur conf/logback-test.xml mit etwas erstellen müssen, das die Protokolle versteckt. Ich denke, das sollte das tun:

<configuration> 
    <root level="debug"> 
    </root> 
</configuration> 

Wie ich es verstehe, dies fängt alle Protokolle (Level debug und höher) und weist keinen Logger ihnen, so dass sie verworfen bekommen. Eine bessere Option besteht darin, einen Datei-Logger für sie zu konfigurieren, sodass Sie bei Bedarf auf die Protokolle zugreifen können.

Eine ausführliche Dokumentation finden Sie unter http://logback.qos.ch/manual/configuration.html.

+0

Danke für die Antwort, also habe ich versucht, eine Datei in "src/test/resources/conf" namens "logback-test.xml" mit den Inhalten, die Sie bereitstellen (mit Level "warn" versucht), aber es hatte keine Auswirkung :( – samthebest

+0

Ich bin wirklich unsicher über all das, sorry. Aber unser Projekt leitet Protokolle in eine Datei während der Tests, so müssen wir nur herausfinden, wie es eingerichtet ist :). logback-test.xml befindet sich hier in /conf. Die Datei wird nirgendwo in unserer Quelle erwähnt, daher ist sie möglicherweise ein magischer Standardspeicherort. Ich sehe nichts anderes ... Wenn ich die Datei lösche, bekomme ich während der Tests Log-Ausgabe (von "warn" nach oben). Wir benutzen Scalatest. –

+1

Ich habe versucht, es in 'proj-root/conf /' kein Glück zu setzen. Ich bin ein wenig verwirrt, wie es je pit genommen werden würde, da der Dateiname noch inhaltlicher Verweis ist. In der Zwischenzeit verwende ich ein wirklich hacky Skript, das eine 'grep-v' mit einer Regex macht, die irgendwie die Spark-Logs entfernt. – samthebest

3

Ein wenig spät zur Party, aber ich fand dies in der spark example code:

def setStreamingLogLevels() { 
    val log4jInitialized = Logger.getRootLogger.getAllAppenders.hasMoreElements 
    if (!log4jInitialized) { 
     // We first log something to initialize Spark's default logging, then we override the 
     // logging level. 
     logInfo("Setting log level to [WARN] for streaming example." + 
     " To override add a custom log4j.properties to the classpath.") 
     Logger.getRootLogger.setLevel(Level.WARN) 
    } 
} 

Ich fand auch mit Ihrem Code, wenn Sie setLogLevels nennen wie darunter eine Menge aus für mich setzen auszuschneiden.

setLogLevels(Level.WARN, Seq("spark", "org", "akka")) 
5

Nach einiger Zeit mit Spark-Log-Ausgabe als auch zu kämpfen, fand ich ein blog post mit einer Lösung, die ich besonders gern.

Wenn Sie slf4j verwenden, kann man einfach die zugrunde liegende Protokollimplementierung austauschen. Ein guter Kandidat für den Testumfang ist slf4j-nop, der die Log-Ausgabe geschickt übernimmt und dort platziert, wo die Sonne nie scheint.

Wenn Maven verwenden, können Sie die folgenden an die Spitze Ihrer Abhängigkeiten Liste hinzu:

<dependency> 
    <groupId>org.slf4j</groupId> 
    <artifactId>slf4j-api</artifactId> 
    <version>1.7.12</version> 
    <scope>provided</scope> 
</dependency> 

<dependency> 
    <groupId>org.slf4j</groupId> 
    <artifactId>slf4j-nop</artifactId> 
    <version>1.7.12</version> 
    <scope>test</scope> 
</dependency> 

Beachten Sie, dass es wichtig sein, könnte es am Anfang der Abhängigkeitsliste zu haben, um sicherzustellen, dass die angegebenen Implementierungen werden anstelle von denen verwendet, die mit anderen Paketen geliefert werden können (und die Sie ausschließen können, um Ihren Klassenpfad sauber zu halten und unerwartete Konflikte zu vermeiden).

+1

das ist das einzige, was für mich funktionierte – Kratos

2

In meinem Fall brachte eine meiner eigenen Bibliotheken logback-classic in den Mix.Diese materialisiert in einer Warnung am Anfang:

SLF4J: Class path contains multiple SLF4J bindings. 
SLF4J: Found binding in [jar:file:/home/alex/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] 
SLF4J: Found binding in [jar:file:/home/alex/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class] 

ich dieses Problem gelöst, indem sie aus der Abhängigkeit ausgenommen:

"com.mystuff" % "mylib" % "1.0.0" exclude("ch.qos.logback", "logback-classic") 

Jetzt konnte ich eine log4j.properties Datei in test/resources hinzufügen, die von Spark wird jetzt verwendet.

Verwandte Themen