Самый близкий механизм в Apache Spark к тому, что вы пытаетесь сделать, это аккумуляторы . Вы можете накапливать строки журнала на исполнителях и получать доступ к результату в драйвере:
// create a collection accumulator using the spark context:
val logLines: CollectionAccumulator[String] = sc.collectionAccumulator("log")
// log function adds a line to accumulator
def log(msg: String): Unit = logLines.add(msg)
// driver-side function can print the log using accumulator's *value*
def writeLog() {
import scala.collection.JavaConverters._
println("start write")
logLines.value.asScala.foreach(println)
println("end write")
}
val CleanText = udf((s: Int) => {
log(s"I am in this UDF, got: $s")
s+2
})
// use UDF in some transformation:
Seq(1, 2).toDF("a").select(CleanText($"a")).show()
writeLog()
// prints:
// start write
// I am in this UDF, got: 1
// I am in this UDF, got: 2
// end write
НО : это на самом деле не рекомендуется, особенно для целей регистрации. Если вы войдете в каждую запись, этот аккумулятор в конечном итоге вылетит вашего драйвера на OutOfMemoryError
или просто ужасно замедлит вас.
Поскольку вы используете блоки данных, я бы проверил, какие опции они поддерживают для агрегации журналов, или просто использовал интерфейс Spark для просмотра журналов исполнителя.