はじめに
本番環境にデプロイしたらバグが出て、デバッグしたいけど本番環境のソースコードにログを仕込んで再起動を繰り返さなきゃみたいなこと、経験したことないでしょうか。
本番環境にブレークポイントや変数を見るためにログを仕込む、そんなことを簡単に行えるのが Stackdriver Debugger です。
今回は Node.js を使って、Google Compute Engine(GCE)にデプロイして Stackdriver Debugger がどんな風に使えるか試してみます。
本記事の執筆時点(2019/03)では、Node.js の Stackdriver Debugger エージェントがベータ版です。
変更になる可能性があることに注意してください。
環境
- macOS High Sierra Version 10.13.6
- Node.js v10.15.3
- npm 6.9.0
- Google Cloud SDK 240.0.0
- express 4.16.4
- @google-cloud/debug-agent 3.1.0
Stackdriver Debugger とは
Stackdriver Debugger は、実行中のアプリケーションに対して現時点のアプリケーションの状態を確認できるサービスです。
アプリケーションの処理速度は低下せず、ユーザーに影響しないと言われています。
用途としては、本番でしか再現しないコードを調査したい場合などに大きな威力を発揮します。
Google Cloud SDK をインストールする
以下のドキュメントを参考に Google Cloud SDK をインストールし、プロジェクトの設定をしてください。
Google Cloud SDK documentation
サンプルアプリケーションの作成
Node.js が事前にインストールされている前提で話を進めます。
インストールされていない場合は、事前に Node.js のインストールを実施してください。
まずは、作成するサンプルアプリケーションを Git で管理します。
今回は、GCP で完結させるために Cloud Source Repositories を利用します。
バージョン管理システムとしては、Cloud Source Repositories の他に GitHub や Bitbucket、GitLab などに対応しています。
それではリポジトリを作成してローカルに clone します。
サンプルとして stackdriver-debugger-sample
という名前で作成しています。
$ gcloud source repos create stackdriver-debugger-sample
$ gcloud source repos clone stackdriver-debugger-sample
まずは express を利用した Node.js のアプリケーションを作成します。
プロジェクトを作成して express をインストールします。
$ cd stackdriver-debugger-sample
$ npm init -y
$ npm install --save express
以下のような 0 から 10 までの数値をランダム生成して、5 より大きい、または小さいを判断する index.js を作成します。
const express = require('express');
const PORT = 80;
const HOST = '0.0.0.0';
const app = express();
const getRandomNumber = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;
app.get('/', (req, res) => {
const num = getRandomNumber(0, 10);
if (num > 5) {
res.send('5 より大きい');
} else {
res.send('5 より小さい');
}
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
サンプルアプリケーションの確認をしましょう。
index.js を起動します。
$ sudo node index.js
別の shell でリクエストすると以下のようなレスポンスであることを確認します。
$ curl http://127.0.0.1
5 より小さい
サンプルアプリケーションを Git で管理していきましょう。
不要なファイルをコミットしないように、.gitignore
ファイルを作成します。
gitignore.io というサイトから Node.js 用の .gitignore
ファイルの設定を利用します。
$ curl https://www.gitignore.io/api/node > .gitignore
最初のコミットをしましょう。
$ git add .
$ git commit -m 'initial commit'
次に Node.js 用の Stackdriver Debugger のパッケージをインストールします。
$ npm install --save @google-cloud/debug-agent
インストールしたパッケージを利用するために、アプリケーションのエントリポイントである index.js の先頭で Stackdriver Debugger のエージェントを有効にします。
+require('@google-cloud/debug-agent').start({
+ allowExpressions: true,
+ serviceContext: {
+ service: process.env.SERVICE,
+ version: process.env.VERSION,
+ }
+});
+
const express = require('express');
const PORT = 80;
const HOST = '0.0.0.0';
allowExpressions
は、後述するログポイントでメッセージ形式を指定するに当たって必要なため有効にします。
service
には、アプリケーションの名前、version
には、アプリケーションのバージョンを設定します。
これらの値をデプロイするたびに変えられるように環境変数から設定できるようにしておきます。
再度コミットしてプッシュします。
$ git commit -am 'Add Stackdriver Debugger agent'
$ git push origin master
GCE へデプロイ
それでは GCE のインスタンスにソースコードを配置しデバッグを行うため、GCE のインスタンスを作成します。
スコープに Cloud Source Repositories の読み取り権限と Stackdriver Debugger の権限を付与しておきます。
サンプルとして example-instance
という名前で作成しています。
作成すると以下のような情報が表示されます。
$ gcloud compute instances create example-instance \
--zone asia-northeast1-a \
--machine-type g1-small \
--image-family ubuntu-1804-lts \
--image-project ubuntu-os-cloud \
--scopes https://www.googleapis.com/auth/source.read_only,https://www.googleapis.com/auth/cloud_debugger \
--tags http-server
Created [https://www.googleapis.com/compute/v1/projects/stackdriver-debugger-235505/zones/asia-northeast1-a/instances/example-instance].
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
example-instance asia-northeast1-a g1-small 10.146.0.7 34.85.116.83 RUNNING
作成した GCE のインスタンスに SSH 接続します。
$ gcloud compute ssh example-instance
Node.js のアプリケーションなので、Node.js と npm をインストールします。
$ sudo apt update && sudo apt install -y nodejs npm
Cloud Source Repositories のリポジトリから作成したアプリケーションをインスタンス内に clone して、npm module のインストールを行います。
$ gcloud source repos clone stackdriver-debugger-sample
$ cd stackdriver-debugger-sample
$ npm install
ソースコードが自動で選択されるようにソースコンテキスト情報を含んだファイル source-context.json
を生成します。
アプリケーションと一緒にバージョン管理する必要はありませんが、このファイルを含めた状態でデプロイする必要があります。
今回はサンプルのためインスタンス内で生成します。
$ gcloud debug source gen-repo-info-file
サンプルアプリケーションを起動します。
起動時に、環境変数から設定できるようにした Stackdriver Debugger エージェントの変数を指定します。
$ sudo SERVICE=sample VERSION=1.0.0 node index.js
試しに別の shell でリクエストすると正常にレスポンスされることが分かります。
$ curl 34.85.116.83
5 より小さい
デバッガを設定する
Google Cloud Console の左メニューから「デバッグ」メニューを開きます。
すると以下のようにデバッグ画面が開きます。
デバッグ画面が表示されたところで、スナップショットの表示から 22 行目をクリックしてブレークポイントを設定します。
この時点で変数 num
にどんな値が入っているか確認できることを期待します。
再びリクエストを行うとブレークポイントの時点の変数やコールスタックが確認できます。
そして変数 num
は 4 であることが分かりました。
ログポイントを設定する
ログポイントはデプロイしたアプリケーションのままログ出力を設定できる機能です。
これによって、本番で確認したいがために本番へログインしてソースコードを書き換え再起動するという手間が無くなります。
先ほどの画面からログポイントの画面に切り替えます。
再び 22 行目をクリックすると、ログポイントの設定が表示されます。
ログポイントにはログが出力される条件とログのメッセージ形式が指定できます。
true
の部分が出力条件、var = {var}
の部分がメーセージ形式を指定する項目です。
またログレベルも指定でき、「情報」・「警告」・「エラー」の 3 種類から選択できます。
今回は、メッセージ形式に num = {num}
を指定し追加をクリックしましょう。
追加をすると 22 行目に num = {num}
が追加されたことが分かります。
追加後、サンプルアプリケーションに何度かリクエストすると、サンプルアプリケーションを起動した標準出力にログポイントのログが出力されていることが分かります。
GCE の場合は、ログの出力先がアプリケーションの標準出力になります。
ログビューア上で見る場合は、別途ロギングエージェントなどを利用した転送が必要です。
GAE や GKE であれば、標準で Stackdriver Logging に対応しているため Stackdriver Logging のリクエストログから確認できます。
$ sudo SERVICE=sample VERSION=1.0.0 node index.js
Running on http://0.0.0.0:80
LOGPOINT: num = 8
LOGPOINT: num = 7
LOGPOINT: num = 10
LOGPOINT: num = 8
LOGPOINT: num = 4
次にログポイントの条件を指定してみましょう。
先ほど作成したログポイントを編集して、条件に num > 5
と入力し適用をクリックすると編集完了です。
再びサンプルアプリケーションに何度かリクエストすると、 num > 5
の条件の場合にのみログ出力されることが分かります。
$ sudo SERVICE=sample VERSION=1.0.0 node index.js
Running on http://0.0.0.0:80
LOGPOINT: num = 10
LOGPOINT: num = 9
LOGPOINT: num = 8
LOGPOINT: num = 8
LOGPOINT: num = 6
お掃除
以下のコマンドを実行し、y
でリポジトリを削除します。
$ gcloud source repos delete stackdriver-debugger-sample
以下のコマンドを実行し、y
でインスタンスを削除します。
$ gcloud compute instances delete example-instance
さいごに
ここまで Stackdriver Debugger を実際に使ってアプリケーションのデバッグを試しました。
Stackdriver Debugger を使えば簡単かつ便利に本番環境でもデバッグできることがお分かりいただけたのではないでしょうか。
是非有効にして、アプリケーションの調査に役立てましょう。
参考
【GCP 入門編・第 24 回】 Stackdriver Debugger で本番環境のデバッグを行おう! | 株式会社トップゲート
Stackdriver Debugger documentation | Stackdriver Debugger