PHP for Windows でイベントログを出力する

Windows 版の PHP を使うことがあり、アプリケーションからイベントログに出力するのに手こずったので、ポイントをメモ書きしておきます。 環境は IIS 7.5 (Windows Server 2008 R2) と PHP 5.4 です。

インストール

インストールについても簡単に触れておきます。 Microsoft より PHP on IIS というページで PHP を Windows 上で動かすための情報が公開されています。 この中に「PHP on Windows ガイドライン」が提供されているのでこれに従って進めれば PHP が稼働する IIS サイトを構築することができます。

それなりのボリュームになっていますが、メインはインストール関連の第2章とベストプラクティスの第5章です。 FastCGI と Non Thread Safe 版 PHP の組み合わせというのがポイントです。 5章の「PHP 実行プロセスのリサイクル設定」はちゃんとやっておきましょう。

実行権限

さて、本題に入って行きます。 Windows 版 PHP の syslog 関数の出力先はイベントログになっていますが、そのままでは IIS 上の PHP アプリケーションからは出力できませんでした。 以下のパラメータが php.ini で指定されていると IIS 上の PHP は仮想ユーザーの権限で実行されます。

fastcgi.impersonate=1

先のガイドラインには上のように 1に設定するよう書かれていますが、これを 0に設定してアプリケーションプールにイベントログ出力可能なユーザーを割り当てるのも一つの方法です。 しかし、今回は fastcgi.impersonate=1のまま仮想ユーザーにイベントログ出力の権限を与えることにしました。

「仮想」ユーザーなので実体となるユーザーはないのですが、代わりに相当するグループ IIS-IUSR にイベントログ出力権限を与えます。 この方法も結構面倒なのですが、詳細は Microsoft の Technet に書かれているのでここでは簡単に触れるにとどめます。 リンク先の手順を参考にして IIS-IUSR (S-1-5-17) に 0x3 (読み取り+書き込み) を設定します。

まず以下のコマンドで現在の設定が出力されるので、これを保存しておきます。 ファイルにリダイレクトすると良いでしょう。

wevtutil.exe gl application /f:xml

続いて権限設定変更のコマンドを入力します。 これで IIS-IUSR グループにもイベントログを出力する権限が追加されます。

wevtutil.exe sl application /ca:O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573)(A;;0x3;;;S-1-5-17)

ここまでで以下のようなコードを使ってイベントログを出力できるようになります。

  openlog("My Message", LOG_PID, LOG_USER);
  syslog(LOG_INFO, "Hello, World");
  closelog();

「説明が見つかりません」エラーをなくす

これでイベントログには出力されるようになりましたが、イベントビューアーで確認したときに説明欄に以下のようなメッセージが表示されてしまいます。 ちなみに ID 2 は LOG_INFO を指定した場合で、priority を変えると変化します。

ソース “PHP-5.4.8” からのイベント ID 2 の説明が見つかりません。このイベントを発生させるコンポーネントがローカル コンピューターにインストールされていないか、インストールが壊れています。ローカル コンピューターにコンポーネントをインストールするか、コンポーネントを修復してください。

これを避けるためにはレジストリエディターで以下のように EventMessageFile と TypesSupported というキーを作成します。 この例では PHP 5.4.8 を想定しています。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\PHP-5.4.8]
"EventMessageFile"=hex(2):43,00,3a,00,5c,00,70,00,68,00,70,00,35,00,5c,00,70,\
  00,68,00,70,00,35,00,2e,00,64,00,6c,00,6c,00,00,00
"TypesSupported"=dword:00000007

EventMessageFile は php5.dll のフルパスを示す REG_EXPAND_SZ (展開可能な文字列値) です。 上の例では C:\php5\php5.dll になっているのですが、適宜変更して設定します。 TypesSupported は REG_DWORD の 7です。 これはサポートされているタイプを表すフラグですが、詳しくはMicrosoft のリファレンスを参照してください。

これで「説明が見つかりません」エラーが消えると思います。

イベントビューアー上で PHP のログを確認しやすくする

イベントビューアーを使ってログを確認する時に、PHP のログのみ拾うためのカスタムビューを作っておくと便利です。 以下のようにイベントソースに PHP-5.4.8 のような PHP バージョン文字列を設定します。 イベントソースはカンマ区切りで複数設定できます。 これを設定すると左のツリーの「カスタムビュー」の下から簡単に保存したビューが選べるようになり便利です。

カスタムビューの設定