📡

(Python)Cloud FunctionsからCloud Loggingへのログ連携方法の比較

2022/02/02に公開

Cloud FunctionsからCloud Loggingへのログの連携方法が複数あったので簡単ですがメリデメを整理してみました。English version

TL;DR

方法 1.標準Logger 2.標準Logger+構造化ログ 3.純正Handler 4.API直利用
ライブラリ追加不要 × ×
ログレベル(Severity)反映 ×
自由度(特殊フィールドの追加等) × ×
Python 3.7対応 ×

選定フロー(雑)

  • ログレベルの運用が不要なら=>「1.標準Logger」
  • ログレベルの運用が必要で
    • labelsなどの特殊フィールドの設定をしたい=>「2.標準Logger+構造化ログ」
    • 特殊フィールドの設定が不要=>「3.純正Handler」

っていう感じになりそう。

方法1.標準Logger/printを使う

一番手軽なパターン。標準Loggerやprintを用いてもログが連携されますがログレベルは連動しません。

func1.py

import logging

import flask

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

def main(request):
    print("PRINT message")
    logger.debug("DEBUG message")
    logger.info("INFO message")
    logger.warning("WARNING message")
    logger.error("ERROR message")
    logger.critical("CRITICAL message")
    logger.exception("EXCEPTION message")
    return flask.jsonify({'result': 'ok'})

functionsのログ画面での確認結果

方法2.標準Logger+構造化ログを使う

Python3.8以降でサポートされている、JSON形式で標準出力する構造化ログ機能を用いると、ログレベルを含めた対応する特殊項目をCloud Loggingに連携することができます。

https://cloud.google.com/functions/docs/monitoring/logging#writing_structured_logs

https://cloud.google.com/logging/docs/agent/logging/configuration#special-fields

func2.py

import json

import flask

def log(severity, message):
    print(json.dumps(dict(severity=severity, message=message)))

def main(request):
    print("PRINT message")
    log("DEFAULT", "DEFAULT message")
    log("DEBUG", "DEBUG message")
    log("INFO", "INFO message")
    log("NOTICE", "NOTICE message")
    log("WARNING", "WARNING message")
    log("ERROR", "ERROR message")
    log("CRITICAL", "CRITICAL message")
    log("ALERT", "ALERT message")
    log("EMERGENCY", "EMERGENCY message")
    return flask.jsonify({'result': 'ok'})

functionsのログ画面での確認結果

※ Python 3.7 で実行した場合は以下のようになり、ログレベルが反映されません。

方法3.純正のHandlerを使う

公式のLoggingクライアントライブラリが提供しているロギング ハンドラが提供されています。
https://cloud.google.com/logging/docs/setup/python

func3.py

import logging

import flask
import google.cloud.logging

client = google.cloud.logging.Client()
client.setup_logging()
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

def main(request):
    print("PRINT message")
    logger.debug("DEBUG message")
    logger.info("INFO message")
    logger.warning("WARNING message")
    logger.error("ERROR message")
    logger.critical("CRITICAL message")
    logger.exception("EXCEPTION message")
    return flask.jsonify({'result': 'ok'})

※ google-cloud-logging の利用バージョン 2.7.0

functionsのログ画面での確認結果

方法4.Cloud Logging APIを直接使う

Cloud Logging APIクライアントを用いて直接APIを実行する方法も公式Docで案内されています。
https://cloud.google.com/logging/docs/setup/python#use_the_cloud_client_library_directly

func4.py

import flask
from google.cloud import logging
logging_client = logging.Client()
log_name = "hello-logging-func4"
logger = logging_client.logger(log_name)

def main(request):
    print("PRINT message")
    logger.log_text("DEFAULT message", severity="DEFAULT")
    logger.log_text("DEBUG message", severity="DEBUG")
    logger.log_text("INFO message", severity="INFO")
    logger.log_text("NOTICE message", severity="NOTICE")
    logger.log_text("WARNING message", severity="WARNING")
    logger.log_text("ERROR message", severity="ERROR")
    logger.log_text("CRITICAL message", severity="CRITICAL")
    logger.log_text("ALERT message", severity="ALERT")
    logger.log_text("EMERGENCY message", severity="EMERGENCY")
    return flask.jsonify({'result': 'ok'})

※ google-cloud-logging の利用バージョン 2.7.0

functionsのログ画面での確認結果 ※ API経由で連携したログはここには表示されません。(おそらくtags等の情報がないから?)

CloudLoggingの画面での確認結果

参考

https://zenn.dev/glassonion1/articles/c58505bf594868
https://www.ai-shift.co.jp/techblog/1217

Discussion