【GCP入門編・第24回】 Stackdriver Debugger で本番環境のデバッグを行おう!

【GCP入門編・第24回】 Stackdriver Debugger で本番環境のデバッグを行おう!

GCP

投稿日:2018/10/05

本番環境にデプロイした直後にバグが発覚、なぜか開発環境では再現しなくて困った、そんな経験は誰しもがあるのではないでしょうか。そんな時に、本番環境で動いているコードの変数を見ることができたら、と思うこともあるかと思います。そんな夢のような話を実現するのが、本記事で紹介する Stackdriver Debugger です。

この記事では、 Stackdriver Debugger についての紹介と、実際に App Engine にデプロイしたコードのデバッグを行うデモを行います。

この記事の目的

  • Stackdriver Debugger を使えるようになろう。
  • ログポイントを使えるようになろう。
  • App Engine にデプロイしたコードをデバッグしてみよう。

Stackdriver Debugger とは

Stackdriver Debugger は2016年の10月に GA (Generally Available) 版がリリースされた、 Stackdriver のサービスの中で最も新しいサービスです。その機能は、実際に動いている本番環境のコードにデバッガをアタッチすることです。

Web 上のデバッガでソースコードを参照しながら、変数を確認することもできます。また、 URL でデバッガを共有することもできるため、共同でバグの原因を調査するといったケースにも使うことが可能です。

本記事執筆時点では、プログラミング言語として Java 、 Node.js 、 Python 、 Go がサポートされており、実行環境としては App Engine Standard ( Java 、 Python のみ)、 App Engine Flexible ( Java 、 Python 、 Node.js のみ)、 Compute Engine 、 Kubernetes Engine がサポートされています。

まだ言語のサポートも実行環境のサポートも限定的ですが、本番環境のコードをデバッグできるという強力な機能は、一度試してみるべき価値のあるものでしょう。

Stackdriver Debugger を使ってみる

それでは、実際に Stackdriver Debugger を使って App Engine にデプロイした Python のサンプルアプリケーションのデバッグを行なってみます。今回使うサンプルコードは 【GCP入門編・第5回】App Engine でのアプリケーション起動法!で使用した hello-world アプリケーションです。

まず、記事に従って hello-world アプリケーションのディレクトリを作成します。ディレクトリ構成は以下の通りになっています。

hello_world +
  ├ README.md
  ├ app.yaml
  ├ appengine_config.py
  ├ main.py
  ├ main_test.py
  ├ requirements.txt
  └ lib/

次に、このディレクトリを git で管理し、リモートのリポジトリにコードをアップロードします。以下のコマンドで git のリポジトリを作成します。

cd hello_world
git init .
git add .
git commit -m "Initial commit"

次に、リモートリポジトリを作成します。リポジトリは GCP の Cloud Source Repositories を使用します。コンソールを開き、左側のメニューから [Development] をクリックし、表示される [Source Code] をクリックします。

[Create Repository] をクリックし、 hello-world という名前でリポジトリを作成します。
以下のような画面になるかと思います。

リポジトリの作成

[Push code from a local Git repository to your Cloud Repository] をクリックし、表示されるコマンドに従い、ターミナルから以下の通りにリモートリポジトリにコードを push します。

gcloud init && git config credential.helper gcloud.sh
git remote add google https://source.developers.google.com/p/プロジェクトID/r/hello-world
git push --all google

次に、アプリケーションのコードを変更します。 main.py を以下の通りに書き換えます。

# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START app]
import logging
import random

from flask import Flask


app = Flask(__name__)


@app.route('/')
def hello():
    number = random.random()
    if number < 0.5:
        raise "Number is less than 0.5"
    else:
        return 'Hello World!'


@app.errorhandler(500)
def server_error(e):
    # Log the error and stacktrace.
    logging.exception('An error occurred during a request.')
    return 'An internal error occurred.', 500
# [END app]

変更が完了したら、コミットしてリモートリポジトリに push します。

git commit -a -m "Fail if random number is less than 0.5."
git push --all google

デプロイ前に、依存ライブラリのインストールを行います。

pip install -t lib -r requirements.txt

pip install

ここまでが完了したら、コードをデプロイします。

gcloud app deploy

デプロイが完了したら、アプリケーションを何回かリロードしてみましょう。

そして、 GCP のコンソールを開き、左側のメニューから Debugger をクリックします。すると、デバッガ画面が開きます。

デバッガー画面

ここで、29行目にブレークポイントを設定します。29行目は raise している箇所となっていますので、アプリケーションで 500 エラーが出た際に number にどのような値が入っていたのかを調べます。

29行目にブレークポイントを設定

ブレークポイントを設定し、何度かアプリケーションをリロードすると、上の図のようにブレークポイントが灰色になります。この状態は本番環境で設定されたブレークポイントを通った時のスナップショットを表しており、右側のパネルに変数が、その下にコールスタックが表示されています。

ご覧の通り、本番環境のコードに対してデバッガを設定することができました。

ログポイントを使用してみる

次に、ログポイントについて説明し、実際にデモを操作してみましょう。

ログポイントとは、Stackdriver Debugger の機能のひとつで、サービスを再起動したりデプロイし直さなくても、実行中のサービスにロギングを挿入することができる機能です。

これを使うことで、プリントデバッグを行う場合に何度もデプロイし直す必要がなくなるため、非常に便利な機能となっています。ログの出力は、 App Engine の場合は Stackdriver Logging のリクエストログに出力されます。
また、ログを出力する条件文をサポートしているため、変数が特定の条件に当てはまる場合にのみログを出力する、ということも可能です。

それでは、早速使ってみましょう。
先ほどまで開いていたデバッガの画面を開き、右側のパネルで [Logpoint] タブをクリックします。

ログポイントのパネル

すると、ログポイントのパネルが表示されます。この状態で、ブレークポイントを挿入した時と同じように、28行目の行番号をクリックします。すると下図のようにログポイントを編集するためのフィールドが表示されます。

ログポイントを編集するためのフィールド

このフィールドには、 if (true) logpoint("var = {var}") と表示されています。 if文の条件式部分がログを出力する条件、 logpoint() の中身が出力されるメッセージです。 Python の場合、 条件式とメッセージにはほとんどの Python 式が使用可能です。詳しくは公式ドキュメントを参照して下さい。

var = {var} と表示されている部分をクリックし、 number = {number} と入力し、 [Add] をクリックします。これでログポイントの登録は完了です。アプリケーションを何回かリロードしてみましょう。

次に、コンソールの左上のメニューを開き、 [Logging] をクリックして Stackdriver Logging の画面を開きます。すると、図の赤枠で示した箇所に、先ほど挿入したログが出力されていることがわかるかと思います。

ログ出力の確認

ログポイントを使うことで、アプリケーションに手を加えてデプロイするという手順を踏まなくともログを出力することができました。非常に便利な機能ですね。

おわりに

いかがでしたか。今回は単純なデモでしたが、本番環境にデバッガを仕込むことが可能になっていることはお見せできたのではないでしょうか。

このように、 Stackdriver Debugger は App Engine にデプロイしたコードの変数の様子を直接観察することが可能です。この機能を使えば、本番環境で稀に起こるエラーのスナップショットをとったり、特定のエラーが発生した場合に変数の状態がどのようになっていたか、といった調査が行えます。

Stackdriver Debugger は簡単に本番環境の様子が観察できるツールです。 App Engine でアプリケーションの運用を行なっている方は、是非お試しください。

同じシリーズの記事

GCP のメリットを最大限に活用しよう!

GCP・G Suite のご相談・
お見積り依頼はお気軽に
TEL.03-5840-8815
お問合せフォーム TEL.03-5840-8815