Windows Azure + PHPな環境でDiagnosticsを使ってログを記録する
前回はとりあえずエラーの情報を画面に表示する設定をしてみましたが、今回はエラーの情報を記録できるように設定してみます。インスタンスの再起動の際にディスクの内容が初期化されるAzureではログの情報はAzure Storageに記録する事になります。
Azure 運用時の考慮点 | Tech Fielders コラム
Windows Azure のインスタンスにはローカルディスクが用意されていますが、ここに保存されたデータは再起動時にクリアされてしまいます。つまり、永続的なデータについては Azure ストレージの使用を検討し、コンピューティングに関してはあくまで計算やサービスの提供窓口としての機能しか持たせないようにすることをお勧めします。
Azure StorageにアクセスするAPIを使ってログを書く事もできますが、Azure StorageはRESTでアクセスするサービスになっているのでログを一行出力する度にAPIをコールするというような使い方は現実的ではありません。そこでAzureではログなどの情報をトラッキングする為のDiagnostics(診断)という機能を持っています。この機能を有効にする事で任意のログをローカル側で貯めながら随時同期するという仕組みを実現できます。このログの仕組みそのものについてはwaritohutsuさんのブログの記事が詳しいです。
Windows Azure ログ講座第一弾 ~Windows Azure logs~
上記の記事はC#での実装方法になっていますが、同様の挙動をPHPで試してみます。
Diagnosticsの設定と動作確認
Diagnosticsの設定を行うには新規にプロジェクトを作る際のウィザードの中で設定をするのが最も手軽です。ウィザードで設定した内容を元に各種設定が記述されています。既存のプロジェクトに設定を行う場合は、設定ファイルに該当の記述を追加する事でDiagnosticsを有効にすることができます。
まずはServiceDefinition.csdefのImport設定からDiagnosticsを読み込みます。何もImportしていない場合は開始タグと終了タグが存在していないので該当部分を置き換えてください。
次にServiceConfiguration.cscfg(関係する部分だけ抜粋しています)にログの転送設定などを記述します。今回は開発用ストレージを対象にした設定を記述していますが、クラウド環境のストレージを利用する場合は適切なアカウント情報などに置き換えてください。ログの転送頻度を表すScheduledTransferPeriodInSecondsに有効な値が設定されていないと記録されたログがストレージに転送されなくなるので特に注意が必要です。
設定に文法エラーが無ければプロジェクトをパッケージして開発ファブリックにデプロイできるはずです。
PHPのエラーをDiagnosticsへ流し込む
では次にPHPからDiagnosticsに対してログ情報を送ってみます。PHPからAzure Logを記録するにはphp_azure.dllが提供するazure_log関数を使います。
azure_log(AZURE_LOG_CRITICAL,"This is error log.");
実行後にしばらく待つとログがWADLogsTableに記録されます。ログの情報の確認はAzure Storage Explorerが便利です。
次にこの関数を使ってPHPのエラーログをAzure Logに記録してみたいと思います。この為にはPHPのエラーハンドリング機構を使って自作したエラーハンドラーからazure_log関数を呼び出す形になります。これによりPHPから発せられた警告や任意にトリガーしたエラーを記録できるようになります。
function azure_log_handler($errno, $errstr, $errfile, $errline){
$string = sprintf("%s %s %s %s", $errno, $errstr, $errfile, $errline);
azure_log(AZURE_LOG_CRITICAL, $string);
return false;
}
set_error_handler("azure_log_handler",E_ALL);
trigger_error("PHP ERROR");
ログのフォーマットはのちに検索する事なども考慮して使いやすそうなフォーマットにするとよいでしょう。
現存するライブラリについて
上記の方法では自前の実装でDiagnosticsを使っていますが、Azure向けの関数を活用するライブラリとしてWindows Azure SDK for PHPがあり、このライブラリにもDiagnosticsのクライアントが含まれています。このクライアントを使う事でパフォーマンスログなどをBlobオブジェクトで記録できます。このライブラリの活用方法については別の機会に紹介しようと思います。
Diagnosticsは設定を行ってもそれだけでは何も記録しません。ウィザードからとりあえず設定をしてみても何も起きていないので機能の存在に気がついていないケースもあるような気がします。なんらかの形でログを記録する処理を実装する必要があるとう点を留意する必要があります。