AWS EMR Spark Python日志记录

时间:2017-03-06 01:05:28

标签: python apache-spark emr

我在AWS EMR上运行一个非常简单的Spark工作,似乎无法从我的脚本中获取任何日志输出。

我试过打印到stderr:

from pyspark import SparkContext
import sys

if __name__ == '__main__':
    sc = SparkContext(appName="HelloWorld")
    print('Hello, world!', file=sys.stderr)
    sc.stop()

使用如here所示的火花记录器:

from pyspark import SparkContext

if __name__ == '__main__':
    sc = SparkContext(appName="HelloWorld")

    log4jLogger = sc._jvm.org.apache.log4j
    logger = log4jLogger.LogManager.getLogger(__name__)
    logger.error('Hello, world!')

    sc.stop()

EMR在作业运行后为我提供了两个日志文件:controllerstderr。这两个日志都不包含"Hello, world!"字符串。我理解stdout被重定向到stderr的火花。 stderr日志显示作业已成功接受,运行和完成。

所以我的问题是,我在哪里可以查看我的脚本的日志输出?或者我应该在脚本中更改哪些内容才能正确记录?

编辑:我使用此命令提交步骤:

aws emr add-steps --region us-west-2 --cluster-id x-XXXXXXXXXXXXX --steps Type=spark,Name=HelloWorld,Args=[--deploy-mode,cluster,--master,yarn,--conf,spark.yarn.submit.waitAppCompletion=true,s3a://path/to/simplejob.py],ActionOnFailure=CONTINUE

4 个答案:

答案 0 :(得分:8)

我发现EMR针对特定步骤的日志记录几乎从未在控制台或stderr日志中出现,这些日志与AWS控制台中的步骤一起被拉出。

通常我会在作业的容器日志中找到我想要的东西(通常是在stdout中)。

这些通常位于s3://mybucket/logs/emr/spark/j-XXXXXX/containers/application‌​_XXXXXXXXX/container‌​_XXXXXXX/...之类的路径上。您可能需要在application_...内的各个container_...containers目录中进行搜索。

最后一个容器目录应该有stdout.logstderr.log

答案 1 :(得分:0)

要捕获脚本的输出,您可以尝试类似下面的内容

/usr/bin/spark-submit --master yarn --num-executors 300 myjob.py param1 > s3://databucket/log.out 2>&1 &

这会将脚本输出写入s3位置的日志文件中。

答案 2 :(得分:0)

值得。假设j-XXX为EMR群集的ID,并假定它已配置为使用logs_bucket来在S3上持久保存日志。如果要查找代码发出的日志,请执行以下操作:

  1. 在AWS控制台中,找到您要查看的步骤
  2. 转到stderr,然后搜索application_。记下您发现的全名,它应该类似于application_15489xx175355_0yy5
  3. 转到s3://logs_bucket/j-XXX/containers并找到文件夹application_15489xx175355_0yy5
  4. 在此文件夹中,您将至少找到一个名为application_15489xx175355_0yy5_ww_vvvv的文件夹。在这些文件夹中,您将找到名为stderr.gz的文件,其中包含您的代码发出的日志。

答案 3 :(得分:0)

我使用的是在 YARN 客户端模式下运行的 emr-5.30.1,并使用 Python logging 库使其正常工作。

我不喜欢在 Spark 中使用 JVM 私有方法的解决方案。除了作为私有方法之外,这些还导致我的应用程序日志出现在 Spark 日志中(这些日志已经非常冗长),并且还迫使我使用 Spark 的日志记录格式。

使用 logging 的示例代码:

import logging

logging.basicConfig(
    format="""%(asctime)s,%(msecs)d %(levelname)-8s[%(filename)s:%(funcName)s:%(lineno)d] %(message)s""",
    datefmt="%Y-%m-%d %H:%M:%S",
    level=logging.INFO,
)

if __name__ == '__main__':
    logging.info('test')
    ...

创建集群时,我通过控制台/CLI/boto 指定 LogUri='s3://mybucket/emr/'

日志输出显示在相关步骤的 stdout.gz 中,可以使用以下任一选项找到。

  1. 在 EMR 控制台中选择您的集群。在“摘要”选项卡上,单击“日志 URI”旁边的小文件夹图标。在弹出窗口中,导航到步骤,选择您的步骤 ID,然后打开 stdout.gz

  2. 在 S3 中直接导航到日志。它们位于 emr/j-<cluster-id>/steps/s-<step-id>/stdout.gzmybucket