我在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在作业运行后为我提供了两个日志文件:controller
和stderr
。这两个日志都不包含"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
答案 0 :(得分:8)
我发现EMR针对特定步骤的日志记录几乎从未在控制台或stderr日志中出现,这些日志与AWS控制台中的步骤一起被拉出。
通常我会在作业的容器日志中找到我想要的东西(通常是在stdout中)。
这些通常位于s3://mybucket/logs/emr/spark/j-XXXXXX/containers/application_XXXXXXXXX/container_XXXXXXX/...
之类的路径上。您可能需要在application_...
内的各个container_...
和containers
目录中进行搜索。
最后一个容器目录应该有stdout.log
和stderr.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上持久保存日志。如果要查找代码发出的日志,请执行以下操作:
stderr
,然后搜索application_
。记下您发现的全名,它应该类似于application_15489xx175355_0yy5
。s3://logs_bucket/j-XXX/containers
并找到文件夹application_15489xx175355_0yy5
。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
中,可以使用以下任一选项找到。
在 EMR 控制台中选择您的集群。在“摘要”选项卡上,单击“日志 URI”旁边的小文件夹图标。在弹出窗口中,导航到步骤,选择您的步骤 ID,然后打开 stdout.gz
在 S3 中直接导航到日志。它们位于 emr/j-<cluster-id>/steps/s-<step-id>/stdout.gz
的 mybucket
。