投稿者:中根 洋平

Stackdriver DebuggerはStackdriverファミリーの一つであるデバッガーサービスです。
おもにGAEで利用されている方が多いと思いますがPython Standard 3.7ランタイムではまだアルファ版です。

今回Cloud Source Repositoriesでもデバッグが動くようになったので試してみましょう。

準備

google-python-cloud-debuggerの導入

Python3.7環境でStackdriver Debuggerを使用するためにgoogle-python-cloud-debuggerパッケージを導入しましょう。
blog掲載時点ではPython3環境は3.6と3.7に対応しています。requirements.txtgoogle-python-cloud-debuggerを追加しましょう。

デバッグを有効にする

デバッグを有効にする方法として大きく2つあります。

  1. ソースコード内でデバッガ エージェントを宣言
  2. デバッガエージェントをモジュールとして実行

ソースコード内でデバッガ エージェントを宣言

この方法はシンプルにソースコード内でgoogle-python-cloud-debuggerを宣言します。
GAEでデバッグを有効にする場合はこちらになります。

from flask import Flask
# Import debugger
try:
    import googleclouddebugger
    googleclouddebugger.enable()
except ImportError:
    pass

app = Flask(__name__)

@app.route('/')
def hello():
    """Return a friendly HTTP greeting."""
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True)

上記ソースをGAEにデプロイできたらCloud Source Repositoriesに移動しましょう。
アプリケーションをデバッグを押しデプロイし、アプリケーションの選択ができれば有効になっています。

image_001.gif

またGAEではサービス名とバージョンを自動で取得していましたがそれ以外の環境ではmoduleversionの指定が必要です。
ここで指定した値がデバッグ時のアプリケーション名とバージョンになります。
先程のコードを以下のように変更してGCEで実行してみましょう。
このときGCEでは以下のいずれかのアクセススコープを許可している必要があります。

  • https://www.googleapis.com/auth/cloud-platform
  • https://www.googleapis.com/auth/cloud_debugger
# Import debugger
try:
    import googleclouddebugger
    service = "MyHelloApp"
    version = "v0.0.1"
    googleclouddebugger.enable(module=service, version=version)
except ImportError:
    pass

image_002.gif

指定したサービス名とバージョンがアプリケーションとして表示されているのがわかります。

デバッガエージェントをモジュールとして実行

次の方法ではソースコード内でDebuggerをimportせず実行時のコマンドでDebuggerを起動させます。

python3 -m googleclouddebugger \
        --module="MyHelloApp" \
        --version="v0.0.2" \
        -- \
        main.py

image_003.gif

引数で指定したアプリケーション名とバージョンでデバッグできているのがわかります。

どちらの方式を採用するべきか

GAEで使用する場合はソースコードでデバッガ エージェントを宣言するパターンが良いかと思います。
しかしローカル環境ではIDEのデバッガーを使用する場合がほとんどかと思います。
そのためgoogleclouddebugger.enableの引数としてGAEの環境変数を指定してローカル環境なのか、GAE環境なのかを判別するといった工夫が必要となります。
下記の例ではos.environでGAEの環境変数を取得しています。
ローカルで環境変数をセットしていない場合、KeyErrorとなりエージェントは実行されません。

# Import debugger
try:
    import os
    import googleclouddebugger
    service = os.environ["GAE_SERVICE"]
    version = os.environ["GAE_VERSION"]
    googleclouddebugger.enable(module=service, version=version)
except ImportError:
    pass
except KeyError:
    pass

一方GAE以外ではどちらのパターンを利用しても良いでしょう。
ソースコードで宣言する場合でも上記のように環境変数を使用することで対応が可能となります。
CI/CDパイプラインで適切な環境変数を渡し環境全体を考慮し適切なパターンを選択しましょう。

Stackdriver DebuggerとCloud Source Repositories上でのデバッガーどちらを使用するべきか

今回Cloud Source RepositoriesでStackdriver Debuggerを使用してみましたが、Stackdriver Debuggerで利用する場合もエージェントの実行方法、操作感は同じです。
Stackdriver DebuggerではCloud Source Repositories以外にもGithubやGitlabといった外部のサービスとの連携も可能です。
ソース管理に上記サービスを使用している場合は従来同様Stackdriver Debuggerの画面からデバッグを行いましょう。

まとめ

Stackdriver Debuggerを使用することで実際に動いている環境でのデバッグが可能となります。
GAEではWSGIを経由するためHeader情報等確認しづらい箇所があるかと思いますが。Debuggerを使用することで実際の値を素早く確認できます。
またログポイントやスナップショットを有効活用することで問題発生時に素早い対応が可能となります。

参考

Python 用 Stackdriver Debugger の設定
Production debugging comes to Cloud Source Repositories
Python Cloud Debugger Agent