如何在AWS Glue中将消息写入输出日志?

39
AWS Glue作业默认将日志输出和错误记录到两个不同的CloudWatch日志中,分别为/aws-glue/jobs/error/aws-glue/jobs/output。当我在脚本中包含print()语句以进行调试时,它们会被写入错误日志(/aws-glue/jobs/error)。
我尝试使用:
log4jLogger = sparkContext._jvm.org.apache.log4j 
log = log4jLogger.LogManager.getLogger(__name__) 
log.warn("Hello World!")

但是“Hello World!”在我运行的测试作业的任何日志中都没有显示。

有人知道如何编写调试日志语句以输出日志(/aws-glue/jobs/output)吗?

TIA!

编辑:

事实证明上述方法确实可行。 发生的情况是我在AWS Glue Script编辑器窗口中运行作业,该窗口捕获Command-F键组合并仅搜索当前脚本。 因此,当我尝试在页面内搜索日志输出时,似乎好像没有被记录。

注意:通过测试第一个响应者的建议,我发现AWS Glue脚本似乎不会输出任何级别低于WARN的日志消息!


1
你需要导入任何东西来使用 log4jLogger 吗?不知怎么的,当我将这三行代码添加到我的脚本中时,我的任务就卡在那里了。状态显示为“运行中”,但没有生成日志。 - cozyss
这在我的Glue Job中不起作用。我正在输出WARN级别的日志,无法看到最小的Cloud Watch。还有其他需要让它工作的东西吗?谢谢。 - padr
@padr 我也遇到了同样的问题。当您查看日志时,需要在筛选事件搜索框中搜索日志文本。记录一些其他日志记录中不会出现的无意义文本以进行测试。 - Arran Duff
7个回答

38

我知道这篇文章不是新的,但是它可能对某些人有帮助:

对我来说,在Glue中登录的代码如下:

# create glue context
glueContext = GlueContext(sc)
# set custom logging on
logger = glueContext.get_logger()
...
#write into the log file with:
logger.info("s3_key:" + your_value)

这里的s3 key是什么意思?@Lars,将错误消息写入s3文件是否可行? - anidev711
该主题的官方文档:https://docs.aws.amazon.com/glue/latest/dg/monitor-continuous-logging-enable.html - selle
1
需要注意的几点:1. Glue记录器不接受msg格式字符串,而是期望完整的字符串(因此您必须处理参数)。2. Glue记录器似乎无法广播到工作程序,因此如果您尝试从UDF记录日志,则需要使用Python记录器。 - aiguofer
如果我想打印出中间数据值,比如输入数据,以便进行调试,该怎么办?我使用了 logger.info(input_data) 但好像不起作用。 - wawawa
@anidev711 这里的s3密钥只是日志消息内容的示例。您可以将任何内容传递给logger.info()函数来记录日志。 - falsePockets

34

尝试使用Python内置的logging模块记录器,默认情况下它会将消息写入标准输出流。

import logging

MSG_FORMAT = '%(asctime)s %(levelname)s %(name)s: %(message)s'
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(format=MSG_FORMAT, datefmt=DATETIME_FORMAT)
logger = logging.getLogger(<logger-name-here>)

logger.setLevel(logging.INFO)

...

logger.info("Test log message")

3
事实证明,我最初尝试记录的方法也可以使用。我还发现 AWS Glue Pyspark 脚本不会输出低于 WARN 级别的任何内容(请参阅上面的编辑)。既然这种方式也可行,我会接受你给出的答案。谢谢! - Jesse Clark
2
我应该写什么“<logger-name-here>”才能让CloudWatch看到我的日志? - Marcel Bezerra
任何有意义的字符串,例如应用程序名称。此值将用于日志消息中的 %(name)s 的位置。 - Alexey Bakulin
能否仅将自定义消息写入S3? - anidev711
嗨,我有一个小问题, logging.basicConfig(filename='s3://<bucketname>/spark.logs',level=logging.INFO) 我能把日志存储到S3存储桶中吗? 我尝试了上述配置,但它没有起作用@AlexeyBakulin - JP Jack
1
如果我想打印出中间数据值,比如输入数据,以便进行调试,该怎么办?我使用了 logger.info(input_data) 但好像不起作用。 - wawawa

9
我注意到上面的回答都是用Python编写的。对于Scala,您可以执行以下操作:
import com.amazonaws.services.glue.log.GlueLogger

object GlueApp {
  def main(sysArgs: Array[String]) {
    val logger = new GlueLogger
    logger.info("info message")
    logger.warn("warn message")
    logger.error("error message")
  }
}

您可以在官方文档这里找到Python和Scala的解决方案。


4

如果有帮助的话,以下内容可用于更改日志级别。

sc = SparkContext()
sc.setLogLevel('DEBUG')
glueContext = GlueContext(sc)
logger = glueContext.get_logger()
logger.info('Hello Glue')

3

以下方法可用于 Glue Python 作业中的 INFO 级别:

import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)
root.info("check")

source


1

我面临了同样的问题。我通过添加logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))来解决它。

之前根本没有任何打印输出,即使是ERROR级别。

这个想法来自于这里https://medium.com/tieto-developers/how-to-do-application-logging-in-aws-745114ac6eb7

另一个选择是记录到标准输出,并将AWS日志粘合到标准输出上(使用标准输出实际上是云日志记录的最佳实践之一)。

更新:仅适用于setLevel("WARNING"),当打印ERROR或WARING时有效。我没有找到如何管理INFO级别的方法:(


你有检查错误日志吗?那是我的标准错误日志事件的终点。 - selle
同样适用于我的标准输出日志事件,使用logging.basicConfig。 - selle
我的打印输出不在标准错误流中。 - feechka

0

如果你只是在调试,print()(Python)或println()(Scala)就可以了。


print() 能够工作,但所有的 print() 语句都会在 Glue 日志中占据同一行,这并不理想。 - Piotr L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接