Bluemixのnode.js開発でデバッグ環境(コンソール、inspector)を導入する

Bluemix上でアプリケーションを開発する際にデバッグ環境がほしいと思ったことはありませんか?
最近こうした環境が少しずつ強化されてきています。たとえばnode.jsであれば実行中のアプリケーションホストにリモートシェルで接続したり、node inspectorを使ったデバッグが可能になりました(*1)。この記事では、このようなデバッグ環境の設定と使い方についてまとめます。

*1: Vennam, S. (2015) [Advanced debugging for Node.js apps in Bluemix.](https://developer.ibm.com/bluemix/2015/10/05/advanced-debugging-node-apps-bluemix/) IBM developerWorks blog.

# 準備

以下のそれぞれについて、準備されているものとします。

1. IBM ID (Bluemix ID)の設定
2. ダッシュボードへのログイン、またはCloud Foundry (cf)によるログイン(`cf api`および`cf login`)ができることの確認
3. デバッグ対象のnode.jsアプリケーションの作成(cfを使用している場合は1回以上`cf push`済みで`cf apps`で参照できる状態)
4. アプリケーションのメモリー割り当て量を1GB程度増加させる(デバッグ環境ツールがメモリを大量に消費するため)

なお、以下ではデバッグ対象のアプリケーションの名前をdevconsoletestとしています。

# デバッグ環境導入のための設定

それでは、まずはデバッグ環境を作るための設定をしましょう。この設定は、アプリケーションの環境変数で行います。

## ダッシュボードの場合

ダッシュボードを使っている場合は、対象となるアプリケーションを選択し、左側のメニューから「環境変数」を選びます。

![devconsoletest-dashboard-menu.png](https://qiita-image-store.s3.amazonaws.com/0/21963/49e65c3f-f16d-e7ab-cc91-4d504fdb734e.png)

そうすると、環境変数が表示されますが、当初は「VCAP_SERVICES」に設定されている値(json)が表示されていますので、「ユーザー定義」タブを選択してユーザ定義環境変数を表示させます。ここで、「名前」に`BLUEMIX_APP_MGMT_ENABLE`、「値」に`devconsole+shell+inspector+proxy+hc`を入力し、「追加」ボタンをクリックします。

![devconsoletest-environment-variable.png](https://qiita-image-store.s3.amazonaws.com/0/21963/41d2b8c4-fe2e-0428-e72a-4abb854a3a39.png)

この設定を反映するために、アプリケーションを再始動します。

アプリケーションにデバッグ環境を導入できたかどうかは、デプロイのログで確認することができます。アプリケーションダッシュボードのメニューから「ファイルとログ」を選択し、ファイルツリーからlogs/staging_task.logを選択して中身を表示します。(アプリケーションの起動に失敗するとファイルを見ることはできません)

下図のように、ログの途中に"**-----> Installing App Management**"で始まる行があれば、デバッグ環境の導入は成功しています。

![devconsoletest-staging_task-log.png](https://qiita-image-store.s3.amazonaws.com/0/21963/c2f0e3ab-b6cf-3d17-d84d-f44adface868.png)

## cfコマンドを使う場合

cfコマンドの場合は、`cf set-env`でアプリケーション環境変数を設定した後に、設定を反映するために`cf restage`を行います。

```shell
cf set-env devconsoletest BLUEMIX_APP_MGMT_ENABLE devconsole+shell+inspector+proxy+hc
cf restage devconsoletest
```

`cf restage`コマンドのログで管理ツールのインストールを確認することができれば、導入は成功しています。

```console
-----> Installing App Management
       The following utilities are configured to be enabled and will be installed now: devconsole, shell, inspector, proxy, hc
         Installing utility: devconsole
         Installing utility: hc
         Installing utility: inspector
         Installing utility: proxy
         Installing utility: shell
```

# 開発コンソールを使ってみる

## デバッグ環境管理画面

デバッグ環境の導入を終えたところで、早速管理画面を開いてみましょう。管理画面のURIはアプリケーションのルート(ホスト)の`/bluemix-debug/manage`です。

![devconsoletest-manage-login.png](https://qiita-image-store.s3.amazonaws.com/0/21963/3ae03cb6-0fbb-0b6c-2de7-f9bc4b480c9d.png)

初回は認証を要求されますので、Bluemixのアカウント(IBM IDとパスワード)を入力すると、管理画面に入ることができます。

管理画面からは以下のことができます。

* アプリケーションの一時停止・再起動
* リモートシェルを開く
* デバッガ(node inspector)を開く

![devconsoletest-manage.png](https://qiita-image-store.s3.amazonaws.com/0/21963/58b4dffe-fd97-774f-383c-b3ead3afec3f.png)

## シェル

デバッグ環境の管理画面の「Open Shell」ボタンを押して、リモートシェルに接続してみましょう。

![devconsoletest-shell-new-window.png](https://qiita-image-store.s3.amazonaws.com/0/21963/e957df55-0158-f553-78b5-760a18ce5ed4.png)

「+ NEW WINDOW」をクリックすると、リモートシェルの画面が開きます。シェルプロンプトが表示されれば無事に接続されています。いくつかコマンドを打ってみましょう。

![devconsoletest-shell.png](https://qiita-image-store.s3.amazonaws.com/0/21963/6ca77ee2-4173-a7a6-bf3b-478df30ce7dd.png)

## デバッガ

次にnode inspectorを使ったデバッグです。デバッグ環境の管理画面の「Open Debugger」ボタンをクリックすると、node inspectorが開きます。

![devconsoletest-inspector.png](https://qiita-image-store.s3.amazonaws.com/0/21963/6696dec1-6ca3-ebe5-3cac-0b052ddb0ed7.png)

この記事を読んでいる人であればだいたい何ができるかわかると思いますが、たとえば行番号をクリックするとブレークポイントを設定することができます。次の画面はブレークポイントを設定後、アプリケーションのPOSTを行ってブレークした状態です。右側にコールスタックや変数の内容が表示されています。

![devconsoletest-inspector-breaking.png](https://qiita-image-store.s3.amazonaws.com/0/21963/18185e25-59e0-2cdf-ece9-a9d57a84e4cf.png)

## プロファイラ

最後にプロファイラです。Node inspectorの左上のほうにある「Profiles」をクリックすると、プロファイラの画面に切り替わります。

![devconsoletest-profiling.png](https://qiita-image-store.s3.amazonaws.com/0/21963/f915c44c-4c2a-23a8-921f-7939b3bc0d19.png)

ここでおもむろに「Start」を押すとプロファイルをとりはじめますので、「Stop」を押してください。

![devconsoletest-profile-result.png](https://qiita-image-store.s3.amazonaws.com/0/21963/8ae5e617-620e-9107-94de-ecca58e9ac09.png)

プロファイルの結果が表示されます。

# トラブルシューティング

最後に、デバッグ環境が動作しないいくつかのケースを記載します。

## 1. デバッグ環境管理画面に接続できない

デバッグ環境管理画面(`/bluemix-debug/manage`)に接続しようとした時に404エラーが出る場合は、ツールの導入に失敗している可能性があります。

デバッグ環境を導入すると、アプリケーション起動コマンドが自動的に./vendor/initial_startup.rbに切り替わります。この切り替えを行うためには、もとのアプリケーションのスタートアップスクリプトが以下のいずれかに記述されている必要があります。(ともに記述がない場合もエラーになります)

* package.jsonのscripts.start
* Procfile

Package.jsonではたとえば以下のように"start"を指定してください。"main"でスクリプトを指定する方法ではエラーとなるようです。(Thanks to @Godai_Aoki )

```json
    "scripts": {
      "start": "node app.js"
    }
```

Bluemix(CloudFoundry)では、上記以外にもmanifest.ymlでスタートアップコマンドを記述することができますが、事前に削除しておいてください。なお、ローカルのmanifest.ymlをした後、少なくとも1回の`cf push`を行うことでファイルをアップロードしなおすことが必要です。

この現象がおきているときには、インストールログに以下のように警告が出ます。

```console
-----> Installing App Management
        WARN: App Management cannot be installed because the start script cannot be found.
        To install App Management utilities, specify your 'node' start script in 'package.json' or 'Procfile'
```

## 2. Node.jsのバージョン

Node inspectorはnode.jsのv0.11.13以上にしか対応していません。これより前のバージョンで起動するとConsoleに以下のようなエラーが出ます。

![devconsoletest-error-node-version.png](https://qiita-image-store.s3.amazonaws.com/0/21963/adbfa635-b9e9-f9b1-4ff7-e5a206922680.png)

この場合は、アプリケーションのnode.jsのバージョンを上げる必要があります。具体的にはpackage.jsonに記述されているnode.jsのバージョンを変更してください。

## 3. メモリ不足(その1)

リモートシェルやデバッガを開く際に404エラーとなることがあります。このときはメモリ不足でアプリケーションが異常終了している場合があります。アプリケーションのダッシュボードで「アクティビティー・ログ」に次のようなログが出ている場合は、メモリを増やす必要があります。

![devconsoletest-error-out-of-memory.png](https://qiita-image-store.s3.amazonaws.com/0/21963/fa9045cd-a980-cac1-2284-7b6ba1e0418b.png)

メモリを増やすには、アプリケーションのダッシュボードで「メモリー割り当て量」を増やしましょう。(cfの場合はmanifest.ymlに記載して`cf push`するか、もしくは`cf push`のオプション`-m`で直接指定)

## 4. メモリ不足(その2)

リモートシェルの「+ NEW WINDOW」をクリックしてシェルウィンドウが表示された後、いつまで待ってもシェルのプロンプトが出ない場合があります。この場合もメモリを増やすことが対策になるようです。

## 5. メモリ不足(その3)

デバッガとのアプリケーションとの通信ができないというエラーが出ることがあります。

![devconsoletest-error-websocket-closed.png](https://qiita-image-store.s3.amazonaws.com/0/21963/9027e831-d860-88c2-0c95-0382112db589.png)

この場合もメモリを増やすことが対策になるようです。

# まとめ

* アプリケーションの環境変数`BLUEMIX_APP_MGMT_ENABLE`を設定するだけで、`/bluemix-debug/`以下にnode.jsのデバッグ環境を導入することができます。
* デバッグ環境ではリモートシェルやデバッガ、プロファイラを使うことができます。
* メモリは通常アプリケーションが使用しているよりも1GB程度増加してみることを推奨します。メモリが不足しているとさまざまなエラーが起こります。

快適な環境でBluemixアプリケーション開発を行いましょう！