Cloud FunctionsでGoogle Cloud Python Loggingライブラリを使ってみる(初心者向け)

Cloud FunctionsでGoogle Cloud Python Loggingライブラリを使ってみる(初心者向け)

Clock Icon2022.03.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データアナリティクス事業本部、池田です。
少し前にGoogle CloudのLoggingPythonライブラリに関するアップデートがありました。
Getting Started with Google Cloud Logging Python v3.0.0
記事によると、Cloud Functionsなどでログのドロップが起きにくくなったようです。

これまであまりきちんとしたログ実装をしていなかったので、この機会に使い方を調べてみました。

ライブラリをローカルから使ってみる

Google Cloud Python logging libraryは、Google Cloudのサービス上に限らず、 ローカルからでもログを送ることができるようなので、まずローカル(Python 3.7.7)で試してみました。

import google.cloud.logging
client = google.cloud.logging.Client()
client.setup_logging()

import logging
logging.warning("Hello World")

上記の内容のPythonファイルを作成し、
export GOOGLE_APPLICATION_CREDENTIALS="{credentialファイルのパス}"
のように認証情報を環境変数に設定して実行すると、↓Google Cloudプロジェクトへログが送信されていました。

warningの黄色いアイコンになっています。
Cloud Shell からであれば認証情報のexportは不要でした

Cloud FunctionsでのLogging

今回は、Pub/Subに紐づくCloud Functionsを実装し、 print()での出力とライブラリでのログ出力をやってみました。

(以降ではCloud Shell上でのコマンド発行を前提としています。)

Pub/Subトピックの作成

メッセージの送受信のために、 Pub/Sub のトピックを sample_logging_topic という名前で作成しました。

gcloud pubsub topics create sample_logging_topic

print()する関数を作成

比較用に標準のprint()関数で出力をするCloud Functionsの関数を作成してみます。

import base64
import os
import json

def sample_print_fn(event, context):
    pubsub_message = base64.b64decode(event["data"]).decode("utf-8")
    print(f"pubsub_message: {pubsub_message}")

    print(json.dumps(event))
    print(event)

    print(f"env: {os.getenv('ENV_VAR')}")

    try:
        print("print at try")
        _ = 1 / 0
    except Exception:
        print("print at except")
        raise
    finally:
        print("print at finally")

内容としては、関数のパラメータ( event["data"] )や環境変数( os.getenv('ENV_VAR') )を print()しています。最後にゼロ除算で例外を起こしています。

上記のファイルを以下のコマンドで sample_print_fn という関数名でデプロイします。

gcloud functions deploy sample_print_fn \
--region asia-northeast1 \
--runtime python39 \
--trigger-topic  sample_logging_topic \
--timeout 30 \
--memory 128MB \
--set-env-vars ENV_VAR=環境変数からの値

--entry-point を指定していないので、関数名のsample_print_fnが実行されます。)

ライブラリを利用する関数を作成

ライブラリを使用するパターンのコードが以下です。

import base64
import os
import json
from logging import getLogger, DEBUG
import google.cloud.logging

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

def sample_logging_fn(event, context):
    pubsub_message = base64.b64decode(event["data"]).decode("utf-8")
    logger.info(f"pubsub_message: {pubsub_message}")

    logger.debug(json.dumps(event))
    logger.debug(event)

    logger.warning(f"env: {os.getenv('ENV_VAR')}")

    try:
        logger.info("info at try")
        _ = 1 / 0
    except Exception:
        logger.error("error at except")
        raise
    finally:
        logger.debug("debug at finally")

Python標準のloggingライブラリと連携して使うことが推奨のようです。
ログレベルを設定しない( logger.setLevel(DEBUG) が無い)場合は、info()はログ出力されてdebug()は出力されませんでした。 コンソールのログ エクスプローラなどで参照する時にもフィルタができるので、細かいログレベルで出力してしまって良いかなと思いました。

ライブラリを利用できるように 依存関係を別ファイルに記述 します。

google.cloud.logging>=3.0.0

あとは、同様に sample_logging_fn という関数名でデプロイします。

gcloud functions deploy sample_logging_fn \
--region asia-northeast1 \
--runtime python39 \
--trigger-topic  sample_logging_topic \
--timeout 30 \
--memory 128MB \
--set-env-vars ENV_VAR=環境変数からの値

メッセージの発行~ログ確認

Pub/Subにメッセージを発行して、関数を動作させてログを確認してみます。
gcloud pubsub topics publish sample_logging_topic --message="pubsubのメッセージ"

↓print()のパターンのログ(Cloud Functionsの「ログ」タブ)。

コンソール上の「重大度」は「デフォルト」として扱われます。

↓ライブラリを使ったパターンのログ。

ログレベルが設定されていることがアイコンからも分かります。

↓ログ エクスプローラで見た場合。

ちなみに logger.debug(json.dumps(event)) でも logger.debug(event) でも、ログ上は違いは見受けられませんでした。

おわりに

ログは奥が深いので、ハンドラなどの使い方にも慣れたらブログにしたいと思います。たぶん。

関連情報/参考にさせていただいたページ

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.