AWS Glue Python Shellでloggingを使ったログ出力について

GlueのPython Shellでloggingモジュールを利用してログを取得を考えてた時のメモです。

ログ出力先

Python Shellのログの出力先ですが、以下の2つのCloudWatch Logsのストリームになります。これを使い分けることになります。

loggingモジュールのデフォルトの出力先

RootのLoggerインスタンスの出力先は以下で設定されています。

logging.getLogger().handlers             #-> [StreamHandler <stderr> (NOTSET)>]
  • フォーマットはデフォルト
  • 例外、ランタイムエラーもアプリケーションログも /aws-glue/python-jobs/error に出力される

ログ設定パターン

パターン別にLogger設定後に以下のようなログを出力して確認します。

logger.info("INFO log")
logger.warn("WARN log")
logger.error("ERROR log")

logger.aaa # エラー発生

デフォルト

デフォルトだと全てが /aws-glue/python-jobs/error に出力されます。

WARNING以上のログしか出力されないのと、ログのフォーマットを変えたいところです。

f:id:yomon8:20190730114454p:plain

全て /aws-glue/python-jobs/error に出力するパターン

/aws-glue/python-jobs/error だけに全てを出力することで、ログの集約が可能です。INFOレベルがerrorに出力されている違和感や、Python Shellの開発時にコンソールにログが出力されないという不便さもあります。

以下の2点だけ調整したパターンです。

  • ログフォーマット
  • 出力ログレベル(デフォルトはWARNING以上)
import sys
import logging

logger = logging.getLogger()
log_format = '[%(levelname)s][%(filename)s][%(funcName)s:%(lineno)d]\t%(message)s'
for handler in logger.handlers:
    handler.setFormatter(logging.Formatter(log_format))
logger.setLevel(logging.INFO)

出力は /aws-glue/python-jobs/error のみで以下のようになります。

f:id:yomon8:20190730113854p:plain

ストリームを使い分けるパターン

例えば以下のように使い分けるパターンです。

  • /aws-glue/python-jobs/output --> アプリケーション側のログ出力のみ
  • /aws-glue/python-jobs/error --> ランタイムエラー等の例外のみ出力

最初にデフォルトのhandlerを削除して、新しいhandlerを作成してLoggerにアタッチしています。

import sys
import logging

logger = logging.getLogger()
[logger.removeHandler(h) for h in logger.handlers]
log_format = '[%(levelname)s][%(filename)s][%(funcName)s:%(lineno)d]\t%(message)s'
stdout_handler = logging.StreamHandler(stream=sys.stdout)
stdout_handler.setFormatter(logging.Formatter(log_format))
logger.addHandler(stdout_handler)
logger.setLevel(logging.INFO)

/aws-glue/python-jobs/output にはアプリケーション側で出力したログが出力されます。

f:id:yomon8:20190730115150p:plain

/aws-glue/python-jobs/error には例外のみ出力されます。

f:id:yomon8:20190730115217p:plain