Glue job Python shellのログ出力を1つのログストリームにまとめてみた

/aws-glue/python-jobs/outputと/aws-glue/python-jobs/errorの2つに出力されるログを1つのログストリームにまとめてみました。
2023.12.15

DA事業本部の横山です。

loggingのdictConfig()を用いてGlue jobのPython shellにおけるログ出力を1つのログストリームにまとめてみました。

前提条件

本記事で利用しているPythonのバージョンは以下になります。

  • Python: 3.8.13

Glue Jobのログ出力について

GlueのPython Shell Jobのログ出力ではCloudWatch logsのロググループが二つに分かれています。

  • /aws-glue/python-jobs/output
    • sys.stdout
  • /aws-glue/python-jobs/error
    • sys.stderr

そのため、これらは標準出力と標準エラー出力の違いによるもので、例えばprint()を利用したログ出力を行っていた場合は基本的なログ内容は /aws-glue/python-jobs/outputに出力され、エラー発生時のログのみ/aws-glue/python-jobs/errorに出力されます。

この場合、Glue jobがエラーで失敗していた場合に/aws-glue/python-jobs/output/aws-glue/python-jobs/errorをそれぞれ見ることになり非常にエラー解析が面倒になる場合があります。

そこで、Pythonのloggingを用いて出力streamをハンドリングして/aws-glue/python-jobs/outputにすべてのログが流れるようにしたいと思います。

  • DEBUG, INFO, WARNING, ERROR, CRITICAL
    • sys.stdout
    • /aws-glue/python-jobs/outputに、すべてのログが流れてくる
  • WARNING, ERROR, CRITICAL
    • sys.stderr
    • /aws-glue/python-jobs/errorには、WARNINGログ以上だけが流れてくる

AWS Glueでの Python シェルジョブ

実装例

ポイントとしては、handlersを2つ用意して、INFO以上を標準出力にWARNING以上を標準エラー出力に流している点です。 これによって、AWSコンソールからGlue jobのログを確認する際に1つのログストリームを確認するだけですべてのログが参照できるようになりました。WARNING以上のログだけを確認したい場合は、 /aws-glue/python-jobs/errorで確認できます。

import logging
import logging.config
import logging.handlers

# Glue jobのLogging Config
# Glue job の Python Shell Jobのログ出力では、sys.stdoutとsys.stderrが異なるロググループに出力されてしまうため、
# /aws-glue/python-jobs/output にDEBUG以上のすべてのログが出力されるように設定
# /aws-glue/python-jobs/error  にWARNING以上が出力されるように設定
LOGGING_GLUE_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,
    "root": {
        "level": "DEBUG",
        "handlers": ["consoleHandler", "consoleErrorHandler"],
    },
    "handlers": {
        "consoleHandler": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "consoleFormatter",
            "stream": "ext://sys.stdout",
        },
        "consoleErrorHandler": {
            "class": "logging.StreamHandler",
            "level": "WARNING",
            "formatter": "consoleFormatter",
            "stream": "ext://sys.stderr",
        },
    },
    "formatters": {
        "consoleFormatter": {
            "format": "%(asctime)s %(name)s %(funcName)s %(lineno)-3d [%(levelname)s] %(message)s"
        },
    },
}


def get_logger(module_name):
    logging.config.dictConfig(LOGGING_GLUE_CONFIG)

    logger = logging.getLogger(
        module_name,
    )

    return logger

おわりに

loggingのdictConfig()を用いてGlue jobのPython shellにおけるログ出力を1つのログストリームにまとめてみました。 Glue job Python shellを利用していてログの確認に困っている人がいれば一度試してみてください。

以上になります。この記事がどなたかの助けになれば幸いです。