Scala中的Apache Spark日志记录

Bog*_*n N 54 logging scala apache-spark

我正在寻找一种解决方案,能够在Apache Spark节点上执行代码时记录其他数据,这有助于稍后调查执行期间可能出现的一些问题.尝试使用传统的解决方案,例如com.typesafe.scalalogging.LazyLogging失败,因为日志实例无法在Apache Spark等分布式环境中进行序列化.

我已经调查了这个问题,现在我找到的解决方案就是使用这样的org.apache.spark.Logging特性:

class SparkExample with Logging {
  val someRDD = ...
  someRDD.map {
    rddElement => logInfo(s"$rddElement will be processed.")
    doSomething(rddElement)
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,看起来Logging特性不是Apache Spark的永久解决方案,因为它被标记为@DeveloperApi,类文档提到:

这可能会在将来的版本中更改或删除.

我想知道 - 他们是否可以使用任何已知的日志记录解决方案,并允许我在Apache Spark节点上执行RDD时记录数据?

@Later Edit:下面的一些评论建议使用Log4J.我尝试过使用Log4J,但是当我从Scala类(而不是Scala对象)使用logger时我仍然遇到问题.这是我的完整代码:

import org.apache.log4j.Logger
import org.apache.spark._

object Main {
 def main(args: Array[String]) {
  new LoggingTestWithRDD().doTest()
 }
}

class LoggingTestWithRDD extends Serializable {

  val log = Logger.getLogger(getClass.getName)

  def doTest(): Unit = {
   val conf = new SparkConf().setMaster("local[4]").setAppName("LogTest")
   val spark = new SparkContext(conf)

   val someRdd = spark.parallelize(List(1, 2, 3))
   someRdd.map {
     element =>
       log.info(s"$element will be processed")
       element + 1
    }
   spark.stop()
 }
Run Code Online (Sandbox Code Playgroud)

}

我看到的例外是:

线程"main"中的异常org.apache.spark.SparkException:任务不可序列化 - >由以下引起:java.io.NotSerializableException:org.apache.log4j.Logger

flo*_*ins 46

您可以使用
https://www.mail-archive.com/user@spark.apache.org/msg29010.html中提出的Akhil解决方案.我自己使用它,它的工作原理.

Akhil Das Mon,2015年5月25日08:20:40 -0700
尝试这种方式:

object Holder extends Serializable {      
   @transient lazy val log = Logger.getLogger(getClass.getName)    
}


val someRdd = spark.parallelize(List(1, 2, 3)).foreach { element =>
   Holder.log.info(element)
}
Run Code Online (Sandbox Code Playgroud)

  • 我有一个火花流动的定制接收器将NullPointering本身弄死,并花了一天时间拉我的胡须.这是解决方案.谢谢. (3认同)

Rya*_*ack 10

使用 Log4j 2.x。核心记录器已可序列化。问题解决了。

Jira 讨论:https : //issues.apache.org/jira/browse/LOG4J2-801

"org.apache.logging.log4j" % "log4j-api" % "2.x.x"

"org.apache.logging.log4j" % "log4j-core" % "2.x.x"

"org.apache.logging.log4j" %% "log4j-api-scala" % "2.x.x"
Run Code Online (Sandbox Code Playgroud)

  • 您能否完整实现此日志记录?就像如何创建 log4j2.properties 以及如何在代码中实现。 (3认同)

Ven*_*hik 1

val log = Logger.getLogger(getClass.getName),
Run Code Online (Sandbox Code Playgroud)

您可以使用“log”来写入日志。另外,如果您需要更改记录器属性,您需要在 /conf 文件夹中包含 log4j.properties。默认情况下,我们将在该位置有一个模板。

  • 简单的解决方案:在本地方法范围内声明日志变量。 (3认同)
  • 如果你让“log”@transient 怎么样? (2认同)