【问题标题】:Spark Custom LoggingSpark 自定义日志记录
【发布时间】:2019-11-15 01:20:45
【问题描述】:

我的 IDE 中有多个 spark 项目。默认情况下,spark 会在 spark/conf 文件夹中选择 log4j.properties 文件。

由于我有多个 spark 项目,我想要多个 log4j.properties 文件(每个项目一个)。可能作为项目代码的一部分(资源文件夹)

有没有办法我们可以获取指定的 log4j.properries 而不是默认的 log4j.properties。

注意: 我试过这个

--driver-java-options "-Dlog4j.configuration=file:///usr/local/Cellar/apache-spark/2.4.1/libexec/conf/driver_log4j.properties"

它没有任何问题,但是我正在寻找类似下面的东西。

但是我想在创建 spark 记录器时加载资源文件夹中的 log4j.properties 文件。

class SparkLogger():
    def __init__(self, app_name, sparksession = None):
        self._spark = sparksession
        self.log4jLogger = None

        if self._spark is not None:
            sparkContext =self._spark.sparkContext
            self.log4jLogger = sparkContext._jvm.org.apache.log4j
            self.log4jLogger = self.log4jLogger.LogManager.getLogger(app_name)

    def info(self, info):
        if self.log4jLogger:
            self.log4jLogger.info(str(info))

    def error(self, info):
        if self.log4jLogger:
            self.log4jLogger.error(str(info))

    def warn(self, info):
        if self.log4jLogger:
            self.log4jLogger.warn(str(info))

    def debug(self, info):
        if self.log4jLogger:
            self.log4jLogger.debug(str(info))

【问题讨论】:

    标签: apache-spark logging pyspark log4j


    【解决方案1】:

    我试图构建我的自定义日志,就像你在你的问题中描述的那样,但最后失败了。我不得不说这完全是浪费。

    最后我选择了 java.util.logging 而不是 log4j。实际上,它是 JDK 中的原始 Logging 工具。我使用它的目的是我只想将自己的信息记录到指定的文件中。

    所以类如下所示。

    package org.apache.spark.internal
    
    import java.io.File
    import java.text.SimpleDateFormat
    import java.util.Date
    import java.util.logging._
    
    import scala.collection.mutable
    
    protected [spark] object YLogger extends Serializable with Logging {
    
      private var ylogs_ = new mutable.HashMap[String, Logger]()
    
      private def initializeYLogging(className: String): Unit = {
        // Here we set log file onto user's home.
        val rootPath = System.getProperty("user.home")
        val logPath = rootPath + File.separator + className + ".log"
        logInfo(s"Create ylogger for class [${className}] with log file named [${logPath}]")
        val log_ = Logger.getLogger(className)
        val fileHandler = new FileHandler(logPath, false)
        val formatter = new Formatter {
          override def format(record: LogRecord): String = {
            val time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date)
            new StringBuilder()
              .append("[")
              .append(className)
              .append("]")
              .append("[")
              .append(time)
              .append("]")
              .append(":: ")
              .append(record.getMessage)
              .append("\r\n")
              .toString
          }
        }
        fileHandler.setFormatter(formatter)
        log_.addHandler(fileHandler)
        ylogs_.put(className, log_)
      }
    
      private def ylog(logName: String): Logger = {
        if (!ylogs_.contains(logName)) {
          initializeYLogging(logName)
        }
        ylogs_.get(logName).get
      }
    
      def ylogInfo(logName: String)(info: String): Unit = {
        if (ylog(logName).isLoggable(Level.INFO)) ylog(logName).info(info)
      }
    
      def ylogWarning(logName: String)(warning: String): Unit = {
        if (ylog(logName).isLoggable(Level.WARNING)) ylog(logName).warning(warning)
      }
    }
    

    你可以像下面这样使用它。

    YLogger.ylogInfo("logFileName") ("This is a log.")
    

    使用起来很简单,希望我的回答能帮到你。

    【讨论】:

      【解决方案2】:

      您必须在log4j file 中定义application_name log 记录器属性。当您使用applicaiton_name 调用get logger 方法时,您将能够访问自定义的应用程序基础日志生成。

      【讨论】:

        猜你喜欢
        • 2016-04-23
        • 1970-01-01
        • 1970-01-01
        • 2016-08-29
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多