【问题标题】:How do I write messages to the output log on AWS Glue?如何将消息写入 AWS Glue 上的输出日志?
【发布时间】:2018-02-21 19:51:48
【问题描述】:

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!")

但是“你好世界!”没有出现在我运行的测试作业的任何日志中。

有谁知道如何将调试日志语句写入输出日志 (/aws-glue/jobs/output)?

TIA!

编辑:

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

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

【问题讨论】:

  • 你需要导入任何东西来使用log4jLogger吗?不知何故将这三行添加到我的脚本中,我的工作就挂在那里了。状态显示running但没有生成日志
  • 这在胶水作业中对我不起作用。我正在输出 WARN 级别的日志,但看不到 min Cloud Watch。你还需要其他什么来让它工作吗?谢谢
  • @padr 我遇到了同样的问题。查看日志时,需要在过滤事件搜索框中搜索日志文本。记录一些不会出现在任何其他日志记录中的无意义文本来测试这一点。

标签: pyspark aws-glue


【解决方案1】:

尝试使用来自logging 模块的内置python logger,默认情况下它将消息写入标准输出流。

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")

【讨论】:

  • 原来也是我最初尝试记录作品的方式。我还发现 AWS Glue pyspark 脚本不会输出低于 WARN 级别的任何内容(请参阅上面的编辑)。我会接受你的回答,因为它也有效。谢谢!
  • 我写什么“”来做 cloudwatch 看我的日志?
  • 任何你想要的有意义的字符串,例如。应用名称。此值将用于代替日志消息中的%(name)s
  • 是否可以只将自定义消息写入s3?
  • 您好,我有一个小问题,logging.basicConfig(filename='s3:///spark.logs',level=logging.INFO) 我可以将登录信息存储到 s3 存储桶中吗?通过上面的配置,它没有工作@AlexeyBakulin
【解决方案2】:

我知道这篇文章并不新鲜,但它可能对某人有所帮助: 对我来说,使用以下代码行登录胶水:

# 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 键在这里是什么意思? @Lars,是否可以将错误消息写入 s3 中的文件?
  • 需要注意的几点: 1. Glue logger 不采用 msg 格式的字符串,而是需要完整的字符串(因此您必须处理参数)。 2. Glue logger 似乎无法向工作人员广播,因此如果您尝试从 UDF 进行日志记录,则需要使用 Python logger。
  • 如果我想打印出输入数据等中间数据值以便调试?我用logger.info(input_data) 好像不行..
【解决方案3】:

我注意到上面的答案是用 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")
  }
}

您可以从官方文档here 中找到 Python 和 Scala 解决方案

【讨论】:

    【解决方案4】:

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

    在根本没有打印之前,甚至是错误级别

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

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

    更新:它仅适用于 setLevel("WARNING") 以及打印 ERROR 或 WARING 时。我没有找到如何在 INFO 级别管理它:(

    【讨论】:

    • 您检查错误日志了吗?这就是我的 stderr 日志事件结束的地方
    • ...对于使用 logging.basicConfig 的标准输出日志事件也是如此
    • 我的打印不在标准错误中
    【解决方案5】:

    以防万一这有帮助。这可以改变日志级别。

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

    【讨论】:

      【解决方案6】:

      这适用于 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-14
        相关资源
        最近更新 更多