2015-11-20 16 views
8

Trong khi điều này không ngăn mã của tôi hoạt động, tôi sẽ phát điên khi cố gắng hiểu tại sao cảnh báo này lại xảy ra. Tôi đang sử dụng Scala 2.11.7, ScalaIDE, SBT 0.13.9.Spark 1.5.2 và SLF4J StaticLoggerBinder

15/11/20 12:17:05 INFO akka.event.slf4j.Slf4jLogger: Slf4jLogger started 
15/11/20 12:17:06 INFO Remoting: Starting remoting 
15/11/20 12:17:06 INFO Remoting: Remoting started; listening on addresses :[akka.tcp://[email protected]:36509] 
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". 
SLF4J: Defaulting to no-operation (NOP) logger implementation 
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 

[Stage 0:=======================================================> (31 + 1)/32] 
[Stage 0:=========================================================(32 + 0)/32] 

Bây giờ tôi hiểu bình thường tại sao lỗi này xảy ra, nhưng vấn đề mà tôi chưa hề làm hỏng đăng nhập của Spark. Bây giờ nếu tôi thêm nói slf4j-đơn giản cho dự án của tôi, nó phàn nàn về nhiều ràng buộc SLF4j, nhưng không phải cảnh báo này. Tôi không thể cho cuộc sống của tôi tìm ra cách để làm cho cả hai thứ này trở nên tốt đẹp. Mã của tôi chính nó đang sử dụng log4j 2.4 cho đăng nhập của riêng tôi.

Tôi đã cố gắng, nhưng không tận dụng

  1. Trừ Logging Spark và bao gồm cả của riêng tôi.
  2. Sử dụng log4j2 để định tuyến các cuộc gọi SLF4j tới log4j2 và loại trừ Spark của SLF4j
  3. Bao gồm nghĩa đen mọi SLF4j ràng buộc trong một nỗ lực để làm cho một trong những chọn nó lên.
  4. Thêm lọ SLF4J, để classpath của tôi, tia lửa của ổ đĩa và chấp hành viên classpath

Nếu tôi cố gắng và loại trừ khai thác gỗ Spark tôi sẽ nhận được vấn đề ClassNotFound từ Spark, nhưng đối với cuộc sống của tôi, tôi không thể hình những gì địa ngục đang làm điều này.

Chỉ cần một số chi tiết, tôi đang sử dụng Spark, nhưng tôi không bao gồm và bao gồm cả phiên bản riêng của tôi về Hadoop (2.7.1)

Dưới đây là là của tôi lọ Tôi nghĩ là có liên quan được cung cấp theo bộ nạp lớp hệ thống.

~/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.10.jar 
~/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.7.10.jar 
~/.ivy2/cache/log4j/log4j/bundles/log4j-1.2.17.jar 
~/.ivy2/cache/org.slf4j/jul-to-slf4j/jars/jul-to-slf4j-1.7.10.jar 
~/.ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.7.10.jar 
~/.ivy2/cache/com.typesafe.akka/akka-slf4j_2.11/jars/akka-slf4j_2.11-2.3.11.jar 
~/.ivy2/cache/org.apache.logging.log4j/log4j-api/jars/log4j-api-2.4.1.jar 
~/.ivy2/cache/org.apache.logging.log4j/log4j-core/jars/log4j-core-2.4.1.jar 
~/.ivy2/cache/com.typesafe.akka/akka-slf4j_2.11/jars/akka-slf4j_2.11-2.4.0.jar 

Có ai có thông tin chi tiết về điều này không? Tôi đánh giá cao nó.

log4j: Trying to find [log4j.xml] using context classloader [email protected] 
log4j: Trying to find [log4j.xml] using [email protected] class loader. 
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource(). 
log4j: Trying to find [log4j.properties] using context classloader [email protected] 
log4j: Using URL [file:/home/scarman/workspace-scala/Ingestions/ingestion/bin/log4j.properties] for automatic log4j configuration. 
log4j: Reading configuration from URL file:/home/scarman/workspace-scala/Ingestions/ingestion/bin/log4j.properties 
log4j: Parsing for [root] with value=[INFO, console]. 
log4j: Level token is [INFO]. 
log4j: Category root set to INFO 
log4j: Parsing appender named "console". 
log4j: Parsing layout options for "console". 
log4j: Setting property [conversionPattern] to [%d{yy/MM/dd HH:mm:ss} %p %c: %m%n]. 
log4j: End of parsing for "console". 
log4j: Setting property [target] to [System.err]. 
log4j: Parsed "console" options. 
log4j: Parsing for [org.spark-project.jetty] with value=[WARN]. 
log4j: Level token is [WARN]. 
log4j: Category org.spark-project.jetty set to WARN 
log4j: Handling log4j.additivity.org.spark-project.jetty=[null] 
log4j: Parsing for [org.spark-project.jetty.util.component.AbstractLifeCycle] with value=[ERROR]. 
log4j: Level token is [ERROR]. 
log4j: Category org.spark-project.jetty.util.component.AbstractLifeCycle set to ERROR 
log4j: Handling log4j.additivity.org.spark-project.jetty.util.component.AbstractLifeCycle=[null] 
log4j: Parsing for [org.apache.spark] with value=[WARN]. 
log4j: Level token is [WARN]. 
log4j: Category org.apache.spark set to WARN 
log4j: Handling log4j.additivity.org.apache.spark=[null] 
log4j: Parsing for [org.apache.hadoop.hive.metastore.RetryingHMSHandler] with value=[FATAL]. 
log4j: Level token is [FATAL]. 
log4j: Category org.apache.hadoop.hive.metastore.RetryingHMSHandler set to FATAL 
log4j: Handling log4j.additivity.org.apache.hadoop.hive.metastore.RetryingHMSHandler=[null] 
log4j: Parsing for [parquet] with value=[INFO]. 
log4j: Level token is [INFO]. 
log4j: Category parquet set to INFO 
log4j: Handling log4j.additivity.parquet=[null] 
log4j: Parsing for [org.apache.hadoop] with value=[WARN]. 
log4j: Level token is [WARN]. 
log4j: Category org.apache.hadoop set to WARN 
log4j: Handling log4j.additivity.org.apache.hadoop=[null] 
log4j: Parsing for [org.apache.spark.repl.SparkILoop$SparkILoopInterpreter] with value=[INFO]. 
log4j: Level token is [INFO]. 
log4j: Category org.apache.spark.repl.SparkILoop$SparkILoopInterpreter set to INFO 
log4j: Handling log4j.additivity.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=[null] 
log4j: Parsing for [org.apache.spark.repl.SparkIMain$exprTyper] with value=[INFO]. 
log4j: Level token is [INFO]. 
log4j: Category org.apache.spark.repl.SparkIMain$exprTyper set to INFO 
log4j: Handling log4j.additivity.org.apache.spark.repl.SparkIMain$exprTyper=[null] 
log4j: Parsing for [org.apache.parquet] with value=[ERROR]. 
log4j: Level token is [ERROR]. 
log4j: Category org.apache.parquet set to ERROR 
log4j: Handling log4j.additivity.org.apache.parquet=[null] 
log4j: Parsing for [org.apache.hadoop.hive.ql.exec.FunctionRegistry] with value=[ERROR]. 
log4j: Level token is [ERROR]. 
log4j: Category org.apache.hadoop.hive.ql.exec.FunctionRegistry set to ERROR 
log4j: Handling log4j.additivity.org.apache.hadoop.hive.ql.exec.FunctionRegistry=[null] 
log4j: Finished configuring 

Thêm bindings lớp học của tôi mà SLF4J nằm khi tải ...

jar:file:/home/scarman/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/Log4jLoggerFactory.class 
[email protected] 
org.slf4j.impl.Log4jLoggerFactory 
+0

Bạn có tệp 'log4j.properties' trong' src/main/resources' không? –

+0

@MariusSoutier Vâng thưa ngài, tôi có. –

+0

Lạ lùng, đối với tôi hoạt động (không loại trừ bất kỳ JAR nào từ Spark). Mặc dù tôi cũng đang sử dụng tính năng ghi nhật ký của Spark, vì vậy trên đường dẫn lớp của tôi chỉ có log4j 1.2.17. –

Trả lời

6

Cập nhật: Đây vẫn áp dụng đối với Spark 1.6.1

Chỉ cần một theo dõi và trả lời cho điều này trong trường hợp bất cứ ai khác đang tự hỏi. Vì vậy, tôi nhận thấy rằng cảnh báo này chỉ xảy ra trong quá trình sử dụng giao diện lát gỗ của Spark. Tôi đã thử nghiệm điều này để xác nhận nó và cũng tìm thấy một người nào đó đã viết về nó trong SPARK-10057. Vấn đề với vấn đề đó là các nhà phát triển khác không thể sao chép nó, nhưng trong tất cả sự công bằng, phóng viên ban đầu khá mơ hồ khi mô tả vấn đề.

Dù bằng cách nào, tôi quyết định theo dõi nó xuống không có lý do gì khác ngoài việc thỏa mãn OCD-ness của tôi về những vấn đề này.

Vì vậy, tôi đã thử nghiệm sử dụng cả hai tệp trong S3 và trên đĩa cục bộ của mình. Các tệp văn bản và JSON không kích hoạt cảnh báo này, nhưng việc sử dụng sàn gỗ đã kích hoạt cảnh báo này cho dù các tệp là cục bộ hay trong S3. Điều này là cho cả đọc và viết các tập tin bằng gỗ. Nhìn vào ParquetRelation.scala, chúng tôi chỉ thấy tham chiếu đến SLF4j ở đó.

// Parquet initializes its own JUL logger in a static block which always prints to stdout. Here 
    // we redirect the JUL logger via SLF4J JUL bridge handler. 
    val redirectParquetLogsViaSLF4J: Unit = { 
    def redirect(logger: JLogger): Unit = { 
     logger.getHandlers.foreach(logger.removeHandler) 
     logger.setUseParentHandlers(false) 
     logger.addHandler(new SLF4JBridgeHandler) 
    } 

Vì vậy, có vẻ hợp lý để tôi khẳng định rằng cầu nối giữa khai thác gỗ JUL của Parquet và cầu SLF4j đang khiến cảnh báo này xuất hiện.Tôi cho rằng nó khởi tạo cây cầu và một cái gì đó xảy ra ở nơi nó không thể tải được trình kết dính Static Logger thích hợp. Tôi sẽ phải đào sâu thêm một chút vào mã của Spark và kiểm tra để tìm hiểu, nhưng đó là ít nhất những gì đang gây ra nó. Tôi sẽ cố gắng và có được một sửa chữa với nhau nếu thời gian cho phép.

Cuối cùng, đây là mẫu mã để tái tạo cục bộ cảnh báo.

scala> sc.setLogLevel("WARN") 

scala> val d = sc.parallelize(Array[Int](1,2,3,4,5)) 
d: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:21 

scala> val ddf = d.toDF() 
ddf: org.apache.spark.sql.DataFrame = [_1: int] 

scala> ddf.write.parquet("/home/scarman/data/test.parquet") 
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". 
SLF4J: Defaulting to no-operation (NOP) logger implementation 
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 
0

Có thể bạn đang thiếu org.slf4j.slf4j-simple trong các phụ thuộc của dự án.

+1

Đọc bài đăng, tôi đã thêm nó. –

Các vấn đề liên quan