Spark使用log4j记录日志,并在Yarn WebUi显示

spark on yarn在执行的时候,开发人员通常希望能够单独使用log4j来记录自己的日志。一般来说当我们使用System.out.println的时候,日志会输出在stdout,而且其他的日志会显示在stderr里面。那么如何使用log4j记录日志并显示在自己的日志文件中,并在Yarn WebUI呢?

我们使用spark默认自带的pi程序来作为例子。

/data/spark-2.4.3/bin/spark-submit  --master yarn --deploy-mode cluster   /data/spark-2.4.3/examples/src/main/python/pi.py 10

spark自带的examples中有个pi的python程序,要实现通过log4j记录自己的日志,并展示在webui需要做2件事。

1.编写一个产生日志代码,并上传到HDFS上一个目录下,比如:hdfs:///tmp/logger.py

import os
import logging
import sys

class YarnLogger:
    @staticmethod
    def setup_logger():
        if not 'LOG_DIRS' in os.environ:
            sys.stderr.write('Missing LOG_DIRS environment variable, pyspark logging disabled')
            return 

        file = os.environ['LOG_DIRS'].split(',')[0] + '/pyspark.log'
        logging.basicConfig(filename=file, level=logging.INFO, 
                format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s')

    def __getattr__(self, key):
        return getattr(logging, key)

YarnLogger.setup_logger()

上述代码会构造一个静态方法,产生pyspark.log文件。

 

2. 修改默认的pi python代码,添加log4j的信息


from __future__ import print_function

import sys
from random import random
from operator import add
import logging
from pyspark.sql import SparkSession


if __name__ == "__main__":
    """
        Usage: pi [partitions]
    """
    spark = SparkSession\
        .builder\
        .appName("PythonPi")\
        .getOrCreate()
    spark.sparkContext.addPyFile('hdfs:///tmp/logger.py')
    import logger
    logger = logger.YarnLogger()
    logger.info("start to do----------------------------------------------------------------------------------------------------------------------------------- ")

    partitions = int(sys.argv[1]) if len(sys.argv) > 1 else 2
    n = 100000 * partitions

    def f(_):
        logger.info("start to do the function------------------------------------------------------------")
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x ** 2 + y ** 2 <= 1 else 0

    count = spark.sparkContext.parallelize(range(1, n + 1), partitions).map(f).reduce(add)
    print("Pi is roughly %f" % (4.0 * count / n))

    spark.stop()

上述代码添加了几行代码:

    spark.sparkContext.addPyFile('hdfs:///tmp/logger.py')
    import logger
    logger = logger.YarnLogger()

通过获取logger的静态方法,并logger.info即可。Spark使用log4j记录日志,并在Yarn WebUi显示_第1张图片

通过简单的2个简单的步骤,我们就可以把我们自己的日志单独记录在pyspark.log文件中,方便开发能够查阅代码错误。而不需要使用System.out.println。

参考文档:https://stackoverflow.com/questions/40806225/pyspark-logging-from-the-executor/40839220

你可能感兴趣的:(Spark,Hadoop)