【问题标题】:how to redirect Scala Spark Dataset.show to log4j logger如何将 Scala Spark Dataset.show 重定向到 log4j 记录器
【发布时间】:2017-05-26 19:14:41
【问题描述】:

Spark API 文档展示了如何从发送到标准输出的数据集或数据帧中获取漂亮的打印片段。

可以将此输出定向到 log4j 记录器吗?或者:有人可以共享将创建类似于 df.show() 格式的输出的代码吗?

有没有办法让标准输出在将 .show() 输出推送到记录器之前和之后都进入控制台?

http://spark.apache.org/docs/latest/sql-programming-guide.htm

val df = spark.read.json("examples/src/main/resources/people.json")

// Displays the content of the DataFrame to stdout
df.show()
// +----+-------+
// | age|   name|
// +----+-------+
// |null|Michael|
// |  30|   Andy|
// |  19| Justin|
// +----+-------+

【问题讨论】:

标签: scala logging apache-spark dataset


【解决方案1】:

teserecter 中的 showString() 函数来自 Spark 代码 (Dataset.scala)。

您不能在代码中使用该函数,因为它是包私有的,但您可以将以下 sn-p 放在源代码中的文件 DatasetShims.scala 中,并在您的类中混入该特征以访问该函数。

package org.apache.spark.sql

trait DatasetShims {
  implicit class DatasetHelper[T](ds: Dataset[T]) {
    def toShowString(numRows: Int = 20, truncate: Int = 20, vertical: Boolean = false): String =
      "\n" + ds.showString(numRows, truncate, vertical)
  }
}

【讨论】:

    【解决方案2】:

    将此实用程序方法放在代码中的某个位置以生成具有 dataframe.show() 格式的格式化字符串。

    然后将其包含在您的日志输出中,例如:

    log.info("此时名为df的数据框显示为\n"+showString(df,100,-40))

    /**
        * Compose the string representing rows for output
        *
        * @param _numRows Number of rows to show
        * @param truncate If set to more than 0, truncates strings to `truncate` characters and
        *                   all cells will be aligned right.
        */
        def showString(
            df:DataFrame
            ,_numRows: Int = 20
            ,truncateWidth: Int = 20
        ): String = {
            val numRows = _numRows.max(0)
            val takeResult = df.take(numRows + 1)
            val hasMoreData = takeResult.length > numRows
            val data = takeResult.take(numRows)
    
            // For array values, replace Seq and Array with square brackets
            // For cells that are beyond `truncate` characters, replace it with the
            // first `truncate-3` and "..."
            val rows: Seq[Seq[String]] = df.schema.fieldNames.toSeq +: data.map { row =>
                row.toSeq.map { cell =>
                val str = cell match {
                    case null => "null"
                    case binary: Array[Byte] => binary.map("%02X".format(_)).mkString("[", " ", "]")
                    case array: Array[_] => array.mkString("[", ", ", "]")
                    case seq: Seq[_] => seq.mkString("[", ", ", "]")
                    case _ => cell.toString
                }
                if (truncateWidth > 0 && str.length > truncateWidth) {
                    // do not show ellipses for strings shorter than 4 characters.
                    if (truncateWidth < 4) str.substring(0, truncateWidth)
                    else str.substring(0, truncateWidth - 3) + "..."
                } else {
                    str
                }
            }: Seq[String]
        }
    

    【讨论】:

    • 我认为答案至少缺少一个花括号,但我认为它没有作为字符串检索,并且缺少名为 rows 的变量的串联。
    猜你喜欢
    • 2011-01-08
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 2019-01-01
    • 2018-04-26
    • 1970-01-01
    • 2012-04-16
    相关资源
    最近更新 更多