복붙노트

[SCALA] log4j에에서 스파크 로그에서 Logback에서 응용 프로그램 로그를 분리

SCALA

log4j에에서 스파크 로그에서 Logback에서 응용 프로그램 로그를 분리

나는 그 용도 스파크를 사용하여 스칼라 Maven 프로젝트를 가지고 있고, 나는 Logback를 사용하여 로그인 구현하려합니다. 나는 단지 내 응용 프로그램을 컴파일하고, 스파크 분포가 설치되는 EC2 인스턴스에 배포하고있다. 다음과 같이 내 pom.xml 파일은 스파크 및 Logback에 대한 종속성을 포함합니다 :

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_${scala.binary.version}</artifactId>
            <version>${spark.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

내 스파크 신청서를 제출할 때, 나는 명령 행에 바인딩 SLF4J를 인쇄 할 수 있습니다. 내가 자바를 사용하여 항아리 코드를 실행하면, 바인딩은 Logback이다. I 스파크 사용하는 경우, 그러나, 바인딩의 log4j이다 (즉, 스파크를 제출).

  val logger: Logger = LoggerFactory.getLogger(this.getClass)
  val sc: SparkContext = new SparkContext()
  val rdd = sc.textFile("myFile.txt")

  val slb: StaticLoggerBinder = StaticLoggerBinder.getSingleton
  System.out.println("Logger Instance: " + slb.getLoggerFactory)
  System.out.println("Logger Class Type: " + slb.getLoggerFactoryClassStr)

수율

Logger Instance: org.slf4j.impl.Log4jLoggerFactory@a64e035
Logger Class Type: org.slf4j.impl.Log4jLoggerFactory

나는의 log4j-1.2.17.jar 및 SLF4J-log4j12-1.7.16.jar 모두 / usr / 지방 / 스파크 / 항아리에 있음을 이해하고, 그 불꽃은 대부분 내 pom.xml 파일에서 배제에도 불구하고이 단지를 참조하고 내가 그들을 삭제하면 때문에 내가의 런타임시 ClassNotFoundException가 주어진하고 불꽃을 제출.

내 질문은 : 불꽃의 내부 로깅 기능을 유지하면서 Logback를 사용하여 내 응용 프로그램에서 기본 로깅을 구현하는 방법이있다. 이상적으로, 나는 아직도 STDOUT에 표시에 스파크 로그를 파일로 내 Logback 응용 프로그램 로그를 작성하고 수 있도록하고 싶습니다.

해결법

  1. ==============================

    1.나는 매우 비슷한 문제가 발생했다.

    나는 매우 비슷한 문제가 발생했다.

    우리의 빌드가 당신과 유사했다 (하지만 우리는 SBT 사용) 여기에 자세히 설명되어 있습니다 : https://stackoverflow.com/a/45479379/1549135

    이 솔루션을 실행하면 로컬로 벌금을 작동하지만 모든 제외 및 새로운 로깅 프레임 워크 (logback) 불꽃의 클래스 경로가 배포 된 항아리에 우선을 가지고 있기 때문에 무시할 것이다 스파크 제출합니다. 그것의 log4j 1.2.xx를 포함하고 있기 때문에 그리고 그것은 단순히 그것을로드하고 우리의 설정을 무시합니다.

    나는 여러 소스를 사용했다. 그러나 스파크에게 1.6.1 문서를 인용 (물론 / 2.2.0 최신 스파크 적용) :

    spark.driver.extraClassPath

    spark.executor.extraClassPath

    extraClassPath는 기본 스파크의 클래스 경로 전에 우선합니다 비록 무슨 일이 여기에 기록되지 않습니다!

    그래서 지금이 솔루션은 매우 명백해야한다.

    - log4j-over-slf4j-1.7.25.jar
    - logback-classic-1.2.3.jar
    - logback-core-1.2.3.jar
    
    libs="/absolute/path/to/libs/*"
    
    spark-submit \
      ...
      --master yarn \
      --conf "spark.driver.extraClassPath=$libs" \
      --conf "spark.executor.extraClassPath=$libs" \
      ...
      /my/application/application-fat.jar \
      param1 param2
    

    난 그냥 아직 당신이 HDFS에 그 항아리를 넣을 수있는 경우입니다. 우리는 응용 프로그램 항아리에 로컬 옆에 있습니다.

    이상하게도, 스파크 1.6.1을 사용하여 또한 문서에서이 옵션을 발견했다 :

    spark.driver.userClassPathFirst, spark.executor.userClassPathFirst

    그러나 단순히 설정 :

    --conf "spark.driver.userClassPathFirst=true" \
    --conf "spark.executor.userClassPathFirst=true" \
    

    나를 위해 작동하지 않았다. 그래서 나는 기꺼이 extraClassPath를 사용하고 있습니다!

    건배!

    당신이 불꽃에 logback.xml를로드하는 어떤 문제에 직면하면, 여기에 내 질문에 당신을 도울 수 있습니다 : 에 시스템 속성 패스 불꽃을 제출하고 클래스 경로 또는 사용자 정의 경로에서 파일을 읽을

  2. ==============================

    2.저도 같은 문제를 겪고 : 나는 logback 설정 파일을 사용하려고했다. 나는 많은 순열을 시도했지만 나는 그것이 작동하지 않았다.

    저도 같은 문제를 겪고 : 나는 logback 설정 파일을 사용하려고했다. 나는 많은 순열을 시도했지만 나는 그것이 작동하지 않았다.

    나는이 SBT 종속성을 사용하여 회색 빛을 띤-SLF4J를 통해 logback에 접근했다 :

    "org.clapper" %% "grizzled-slf4j" % "1.3.0",
    

    나는의 log4j 설정 파일을 추가하면 :

    src/main/resources/log4j.properties/log4j.properties files.
    

    내 기록은 벌금을했다.

  3. ==============================

    3.라이브러리 음영 : 많은 투쟁 후 나는 다른 해결책을 발견했습니다. 내가 org.slf4j 음영 처리 한 후, 내 응용 프로그램 로그 스파크 로그에서 분리된다. 또한, 내 응용 프로그램 항아리에 logback.xml은 영광입니다.

    라이브러리 음영 : 많은 투쟁 후 나는 다른 해결책을 발견했습니다. 내가 org.slf4j 음영 처리 한 후, 내 응용 프로그램 로그 스파크 로그에서 분리된다. 또한, 내 응용 프로그램 항아리에 logback.xml은 영광입니다.

    다음은 SBT에서 라이브러리 음영에 대한 정보를 찾을 수 있습니다,이 경우에는 퍼팅에 온다 :

    assemblyShadeRules in assembly += ShadeRule.rename(s"org.slf4j.**" -> "your_favourite_prefix.@0").inAll
    

    당신의 build.sbt 설정한다.

    사이드 노트 : 당신이 확실하지 실제로 무슨 일이 있었 음영 여부를 경우, 일부 아카이브 브라우저에서 항아리를 열고 디렉토리 구조는 당신의 항아리가 포함되어야이 경우, 하나의 음영 반영 여부를 확인 경로 / your_favourite_prefix / 조직 / SLF4J 아니지만 / 조직 / SLF4J

  4. ==============================

    4.나는 지방 항아리에 내 다른 종속성 및 SRC / 메인 / 자원 / logback.xml와 함께 logback와 log4j에 - 투 - SLF4J를 포장.

    나는 지방 항아리에 내 다른 종속성 및 SRC / 메인 / 자원 / logback.xml와 함께 logback와 log4j에 - 투 - SLF4J를 포장.

    내가 실행할 때와 스파크를 제출

    --conf "spark.driver.userClassPathFirst=true" \
    --conf "spark.executor.userClassPathFirst=true"
    

    모든 기록은 logback에 의해 처리됩니다.

  5. from https://stackoverflow.com/questions/42126107/separating-application-logs-in-logback-from-spark-logs-in-log4j by cc-by-sa and MIT license