scala - 如何在 Spark 应用程序中进行有效的日志记录

标签 scala apache-spark apache-spark-sql

我有一个用 Scala 编写的 Spark 应用程序代码,它运行一系列 Spark-SQL 语句。这些结果是通过最后针对最终数据帧调用操作“计数”来计算的。我想知道从 Spark-scala 应用程序作业中进行日志记录的最佳方法是什么?由于所有数据帧的数量(大约 20 个)最终都是使用单个操作计算的,因此在记录某些语句的输出/序列/成功时,我有哪些选择。

问题本质上很少通用。由于 spark 适用于惰性求值,因此执行计划由 spark 决定,我想知道应用程序语句成功运行到什么时候以及该阶段的中间结果是什么。

这里的目的是监控长期运行的任务,看看它到什么时候都很好,以及问题在哪里。

如果我们尝试在转换之前/之后放置日志记录,那么它会在读取代码时打印出来。因此,在实际执行期间必须使用自定义消息进行日志记录(在 Scala 代码的末尾调用操作)。如果我尝试将 count/take/first 等放在代码之间,那么作业的执行速度会减慢很多。

最佳答案

我了解您面临的问题。让我为此提出一个简单的解决方案。

您需要利用 org.apache.log4j.Logger .使用以下代码行生成记录器消息。

org.apache.log4j.Logger logger = org.apache.log4j.Logger.getRootLogger();

logger.error(errorMessage);
logger.info(infoMessage);
logger.debug(debugMessage);

现在,为了将这些消息重定向到日志文件,您需要创建一个包含以下内容的 log4j 属性文件。
# Root logger option

# Set everything to be logged to the console
log4j.rootCategory=INFO, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n

# Settings to quiet third party logs that are too verbose
log4j.logger.org.eclipse.jetty=OFF
log4j.logger.org.eclipse.jetty.util.component.AbstractLifeCycle=OFF
log4j.logger.org.spark-project.jetty.servlet.ServletHandler=OFF
log4j.logger.org.spark-project.jetty.server=OFF
log4j.logger.org.spark-project.jetty=OFF
log4j.category.org.spark_project.jetty=OFF
log4j.logger.Remoting=OFF
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO
log4j.logger.org.apache.parquet=ERROR
log4j.logger.parquet=ERROR

# Setting properties to have logger logs in local file system 
log4j.appender.rolling=org.apache.log4j.RollingFileAppender
log4j.appender.rolling.encoding=UTF-8
log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling.layout.conversionPattern=[%d] %p %m (%c)%n
log4j.appender.rolling.maxBackupIndex=5
log4j.appender.rolling.maxFileSize=50MB
log4j.logger.org.apache.spark=OFF
log4j.logger.org.spark-project=OFF
log4j.logger.org.apache.hadoop=OFF
log4j.logger.io.netty=OFF
log4j.logger.org.apache.zookeeper=OFF
log4j.rootLogger=INFO, rolling
log4j.appender.rolling.file=/tmp/logs/application.log

您可以在最后一条语句中命名日志文件。确保每个节点上的文件夹具有适当的权限。

现在,我们需要在提交 spark 作业时传递配置,如下所示。
 --conf spark.executor.extraJavaOptions=-Dlog4j.configuration=spark-log4j.properties --conf spark.driver.extraJavaOptions=-Dlog4j.configuration=spark-log4j.properties 

和,
--files "location of spark-log4j.properties file"

希望这可以帮助!

关于scala - 如何在 Spark 应用程序中进行有效的日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57767064/

相关文章:

scala - 以字符串表示日期2018-01-01T17:11:11.111 + 06:00的格式

python - 类型错误: 'DataFrame' 对象不可调用 - Spark 数据框

apache-spark - 根据先前的值对 Spark 中的列中的值进行排名

scala - 为什么 `Source.fromFile(...).getLines()` 在我遍历之后是空的?

scala - 如何在scala中的对象内部使用方法?

scala - 如何修复喷雾示例的编译错误?

json - NetcatSource:客户端发送的长度超过最大长度

scala - 使用 Spark scala 从 BigQuery 读取数据

dataframe - 如何使用 Spark DataFrames 查询 JSON 数据列?

scala - Spark DeltaLake Upsert(合并)抛出 "org.apache.spark.sql.AnalysisException"