Programming

스파크 콘솔에서 정보 메시지 표시를 중지하는 방법?

procodes 2020. 6. 2. 22:04
반응형

스파크 콘솔에서 정보 메시지 표시를 중지하는 방법?


스파크 셸에서 오는 다양한 메시지를 중지하고 싶습니다.

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

이것들을 어떻게 막을 수 있습니까?


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")

.conf파일 변경을 제안한 @AkhlD 및 @Sachin Janani에게 감사 합니다.

다음 코드는 내 문제를 해결했습니다.

1) import org.apache.log4j.{Level, Logger}가져 오기 섹션에 추가

2) 스파크 컨텍스트 객체 생성 후 다음 라인을 추가했습니다 val sc = new SparkContext(conf).

val rootLogger = Logger.getRootLogger()
rootLogger.setLevel(Level.ERROR)

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>

콘솔 대신 파일에 로그를 쓰려면 log4j.xml에서 FileAppender로 전환하십시오. LOG_DIR를 사용하여 제공 할 수있는 logs 디렉토리의 변수입니다 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 : ERROR 구성 파일 [log4j.properties]를 읽을 수 없습니다. java.io.FileNotFoundException : log4j.properties (파일 또는 디렉토리가 없음)

이 문제를 해결하기위한 힌트

분산 파일 시스템 (HDFS 또는 mesos)에 log4j 구성 파일을 유지하고 log4j PropertyConfigurator를 사용하여 외부 구성을 추가하십시오 . 또는 sparkContext addFile 을 사용하여 각 노드에서 사용할 수있게 한 다음 log4j PropertyConfigurator를 사용하여 구성을 다시로드하십시오.


다음과 같이 로그 수준을 OFF로 설정하여 로그 비활성화를 설정합니다.

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

또는 다음 속성을 변경하여 로그 파일을 편집하고 로그 수준을 해제로 설정하십시오.

log4j.rootCategory=OFF, console

수입 명세서 바로 아래에있는 모든 pyspark 스크립트 에이 줄을 추가하십시오.

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 코어 로깅 conf로 기본 설정되어 있다고 생각합니다.

따라서 나와 같은데 위의 답변이 도움이되지 않으면 log4j conf 파일에서 '.template'접미사를 제거해야하며 위의 내용이 완벽하게 작동합니다!

http://apache-spark-user-list.1001560.n3.nabble.com/disable-log4j-for-spark-shell-td11278.html


예제로 수집 된 모든 방법

소개

실제로 는 여러 가지 방법이 있습니다 . 어떤 사람들은 다른 사람들로부터 더 힘들지만, 당신에게 가장 적합한 것은 당신에게 달려 있습니다. 나는 그들 모두를 보여 주려고 노력할 것이다.


앱에서 프로그래밍 방식으로 # 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)

log4jAPI를 사용하여 훨씬 더 많은 것을 얻을 수 있습니다 .
출처 : [ Log4J 구성 문서 , 구성 섹션]


# 2 패스 log4j.propertiesspark-submit

이것은 매우 까다 롭지 만 불가능하지는 않습니다. 그리고 내가 가장 좋아하는 것.

앱 시작 중 Log4J는 항상 log4j.properties클래스 경로에서 파일을 찾고로드 합니다.

그러나 spark-submitSpark 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-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-defaults.conf, spark-env.sh, log4j.properties, 이 디렉토리에서).

출처 : Spark 문서, 구성

단계 :

  1. 클러스터 conf폴더 복사 (추가 정보, 방법 # 3)
  2. log4j.properties해당 폴더에서 편집 (방법 # 2의 예)
  3. Set SPARK_CONF_DIR to this folder, before executing spark-submit,
    example:

    export SPARK_CONF_DIR=/absolute/path/to/custom/conf
    
    spark-submit \
        --master yarn \
        --deploy-mode cluster \
        --class com.github.atais.Main \
        "SparkApp.jar"
    

Conclusion

I am not sure if there is any other method, but I hope this covers the topic from A to Z. If not, feel free to ping me in the comments!

Enjoy your way!


In Python/Spark we can do:

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 )

The after defining Sparkcontaxt 'sc' call this function by : quiet_logs( sc )


tl;dr

For Spark Context you may use:

sc.setLogLevel(<logLevel>)

where loglevel can be ALL, DEBUG, ERROR, FATAL, INFO, OFF, TRACE or WARN.


Details-

Internally, setLogLevel calls org.apache.log4j.Level.toLevel(logLevel) that it then uses to set using org.apache.log4j.LogManager.getRootLogger().setLevel(level).

You may directly set the logging levels to OFF using:

LogManager.getLogger("org").setLevel(Level.OFF)

You can set up the default logging for Spark shell in conf/log4j.properties. Use conf/log4j.properties.template as a starting point.

Setting Log Levels in Spark Applications

In standalone Spark applications or while in Spark Shell session, use the following:

import org.apache.log4j.{Level, Logger}

Logger.getLogger(classOf[RackResolver]).getLevel
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)

Disabling logging(in log4j):

Use the following in conf/log4j.properties to disable logging completely:

log4j.logger.org=OFF

Reference: Mastering Spark by Jacek Laskowski.


Simply add below param to your spark-shell OR spark-submit command

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

Check exact property name (log4jspark.root.logger here) from log4j.properties file. Hope this helps, cheers!


An interesting idea is to use the RollingAppender as suggested here: http://shzhangji.com/blog/2015/05/31/spark-streaming-logging-configuration/ so that you don't "polute" the console space, but still be able to see the results under $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

Another method that solves the cause is to observe what kind of loggings do you usually have (coming from different modules and dependencies), and set for each the granularity for the logging, while turning "quiet" third party logs that are too verbose:

For instance,

    # 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 to do on the command line...

spark2-submit --driver-java-options="-Droot.logger=ERROR,console" ..other options..


  1. Adjust conf/log4j.properties as described by other log4j.rootCategory=ERROR, console
  2. Make sure while executing your spark job you pass --file flag with log4j.properties file path
  3. If it still doesn't work you might have a jar that has log4j.properties that is being called before your new log4j.properties. Remove that log4j.properties from jar (if appropriate)

sparkContext.setLogLevel("OFF")

In addition to all the above posts, here is what solved the issue for me.

Spark uses slf4j to bind to loggers. If log4j is not the first binding found, you can edit log4j.properties files all you want, the loggers are not even used. For example, this could be a possible SLF4J output:

SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [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: Found binding in [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: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]

So here the SimpleLoggerFactory was used, which does not care about log4j settings.

Excluding the slf4j-simple package from my project via

<dependency>
        ...
        <exclusions>
            ...
            <exclusion>
                <artifactId>slf4j-simple</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>

resolved the issue, as now the log4j logger binding is used and any setting in log4j.properties is adhered to. F.Y.I. my log4j properties file contains (besides the normal configuration)

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

Hope this helps!


This one worked for me. For only ERROR messages to be displayed as stdout, log4j.properties file may look like:

# 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

NOTE: Put log4j.properties file in src/main/resources folder to be effective. And if log4j.properties doesn't exist (meaning spark is using log4j-defaults.properties file) then you can create it by going to SPARK_HOME/conf and then mv log4j.properties.template log4j.properties and then proceed with above said changes.


If you don't have the ability to edit the java code to insert the .setLogLevel() statements and you don't want yet more external files to deploy, you can use a brute force way to solve this. Just filter out the INFO lines using grep.

spark-submit --deploy-mode client --master local <rest-of-cmd> | grep -v -F "INFO"

If anyone else is stuck on this,

nothing of the above worked for me. I had to remove

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'

from my build.gradle for the logs to disappear. TLDR: Don't import any other logging frameworks, you should be fine just using org.apache.log4j.Logger

참고URL : https://stackoverflow.com/questions/27781187/how-to-stop-info-messages-displaying-on-spark-console

반응형