こんにちは、 @mshibuya です。
GCE上で動いているPHPアプリケーションにおいて適切にエラーの収集・解決ができるようにStackdriver Error Reporting for PHPを導入しようとしているのですが、はまりどころがいくつかあったので共有します。。
なおこの記事はオプトテクノロジーズアドベントカレンダー11日目の代打エントリーです…(←遅刻ではないという主張)。
Stackdriver Error Reportingとは
GCPが提供するモニタリングシステムStackdriverの機能のひとつで、アプリケーションレベルのエラーや例外を一元管理しわかりやすくリアルタイム表示できるエラー通知ツールです。この手のツールではAirbrakeやSentryあたりが有名ですね。
公式サイトはこちら。
Stackdriver Error Reporting for PHP
この手のサービスのご多分にもれず、各種言語向けのSDKが用意されていて簡単にアプリケーションに統合できるようになっており、PHP版も存在します。が、公式サイトに記載のある通りベータ版のステータスであり(2018/12/24現在)、あんまりドキュメント等充実していません。。
はまりポイント1:必要な権限に注意
ローカルで試そうとしていて、自分自身に Error Reporting
→ エラー書き込み
の権限をつけ、エラーになるPHPコードを実行させるも一向にエラーとして検知されず…。
で、なんでかと思いSDKのソースコードを追いかけて調べました。
結論、こちらに記載
次のいずれかの方法で、エラーを Google Compute Engine アプリケーションから Stackdriver Error Reporting に送信できます。
Stackdriver Logging にロギングする。すでに Stackdriver Logging を使用している場合、追加設定は不要です。フォーマット設定の要件について詳しくは、例外のロギングをご覧ください。
Stackdriver Error Reporting API を使用する。アプリケーションでは、REST API を使用して HTTP リクエストを送信したり、試験運用中のライブラリを複数の言語で使用したりできます。
のある通り通知経路は2パターンあるわけですが、
- 通知経路によって異なる権限が必要(Stackdriver Logging経由の場合は
Logging
→ログ書き込み
、Stackdriver Error Reporting API経由の場合はError Reporting
→エラー書き込み
) - PHP SDKの場合、例外ハンドラにひっかけてエラー通知される時は必ずStackdriver Logging経由となる。Error Reporting API経由で送られるのはアプリケーションから明示的に呼び出した場合のみ
ということで、ログ書き込みがないと書けないのでした。
えー、「Stackdriver Error Reportingを使うからエラー書き込みの権限があればいいよね!」って思うじゃないですか普通…。
はまりポイント2:GCE上で使うときの罠
で、権限の謎は解けたものの、ローカルでやってもGCE上でやっても一向に出ず…。GAEで動いてる別アプリでは問題なく出てるので、条件を近づけようとしてあれこれ試して判明したことは
- service名が空だとLoggingには流れるものの、Error Reportingに拾われない
ということ。
でmetadata providerからserviceIdを取得しているわけですが、GAE上ではちゃんとサービス名が返るのに対しGCE上やローカルでは値が取れず、結果Error Reporting側に拾われないのでした…。
解決策としては、vendor
ディレクトリの直上に ErrorReportingBootstrap
の名前で
<?php
use Google\Cloud\Logging\LoggingClient;
return (new LoggingClient())->psrLogger('app-error', [
'batchEnabled' => true,
'debugOutput' => true,
'batchOptions' => ['numWorkers' => 2],
'metadataProvider' => new Google\Cloud\Core\Report\SimpleMetadataProvider(
[], '', 'my-service'
)
]);
のようなファイルを作っておくとOKです( my-service
のところは適切に名前を入れてあげてください)。こうすることで
の処理がファイルを読んでくれて、ちゃんとservice名の入ったmetadata providerを持つloggerを使えるようになります。
まとめ
Stackdriverはシステムに必要ないろんなモニタリングツールが揃っていて便利なのですが、もうちょっと親切さが増してくれるとより活用しやすいのになーといった感想です。
アプリケーションエラーの適切な収集・解決はシステムの安定稼働にとって重要なので、こういったツールを活用していい感じの運用体制を作っていけるとよいですねー