【问题标题】:AWS EMR Spark Python LoggingAWS EMR Spark Python 日志记录
【发布时间】:2017-07-25 18:08:35
【问题描述】:

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

我尝试过打印到标准错误:

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 在 spark 中被重定向到 stderrstderr 日志显示作业已被接受、运行并成功完成。

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

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

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

【问题讨论】:

  • 您使用什么参数将作业提交给 EMR?
  • 我发现特定步骤的日志记录几乎永远不会在 EMR 控制台拉到步骤旁边的控制器或标准错误日志中结束。通常我会在作业的容器日志中找到我想要的内容(通常在标准输出中)。它们通常位于s3://mybucket/logs/emr/spark/j-XXXXXX/containers/application_XXXXXXXXX/container_XXXXXXX/... 之类的路径上
  • @GregReda 我在那里找到了日志。谢谢!如果您将其发布为答案,我会接受。
  • 太棒了!很高兴我一直在调试 EMR + PySpark 并没有白费 :)

标签: python apache-spark emr


【解决方案1】:

我发现 EMR 对特定步骤的日志记录几乎永远不会出现在控制器或标准错误日志中,这些日志会与 AWS 控制台中的步骤一起被拉出。

通常我会在 job 的 容器日志中找到我想要的内容(通常在标准输出中)。

这些通常位于s3://mybucket/logs/emr/spark/j-XXXXXX/containers/application‌​_XXXXXXXXX/container‌​_XXXXXXX/... 之类的路径上。您可能需要在containers 中的各种application_...container_... 目录中四处寻找。

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

【讨论】:

  • 我在哪里定义/设置/查找日志持久化的存储桶?
  • @Dror 或其他任何想知道的人,您可以在 JSON 的 Log_URI EMR 配置属性中进行设置。
【解决方案2】:

物有所值。假设 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 的文件,其中包含您的代码发出的日志。

【讨论】:

  • 先生,您能告诉我如何将自定义日志从 EMR 集群存储到 s3 现在我可以将所有系统日志存储到 s3 存储桶,但是我有一个日志文件来存储我的所有程序我无法在 s3 存储桶中找到的日志,但我可以在存储在此路径中的 EMR 上:/mnt/var/log/hadoop/steps/N 请给我一个建议如何实现这一点...thnx提前
  • 我希望我知道答案...对不起。
【解决方案3】:

我正在使用在 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 中直接导航到日志。它们位于mybucket 中的emr/j-<cluster-id>/steps/s-<step-id>/stdout.gz

【讨论】:

    【解决方案4】:

    要捕获脚本的输出,您也可以尝试以下方法

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-13
      • 2014-11-25
      • 1970-01-01
      • 2016-10-08
      • 2019-11-15
      • 1970-01-01
      • 2015-08-10
      • 2018-04-26
      相关资源
      最近更新 更多