syslog を使って PHP アプリケーションを改善し、デバッグする

古めかしい UNIX の syslog の PHP 版が単純で効果的なデバッグ・ツールを提供

実行中のプログラムの様子を調べるための古い手法では、変数の現在の値を「表示する」コードを重要なポイントに置きます。しかしこれを、プログラムの標準出力を妨害せずに行うにはどのようにすればよいのでしょう。PHP の syslog() 機能を使うと、こうした値を簡単に検証することができます。この記事ではその方法について調べてみましょう。

William B. Zimmerly (bill@zimmerly.com), Freelance Writer and Knowledge Engineer, Author

Photo of Bill ZimmerlyBill Zimmerly はさまざまなバージョンの UNIX と Microsoft® Windows® に経験を積んだナレッジ・エンジニアであり、下位レベルのシステム・プログラマーであり、また Logic の祭壇で礼拝する自由な考えの持ち主です。彼は非常識な人としても知られています。ここで言う非常識は「常識的な人は自身を世界に適応させ、非常識な人は世界を自身に適応させようと試みる。従って、すべての進歩は非常識な人に依存する」という George Bernard Shaw の言葉で言う非常識な人です。新しい技術を作成し、それらについて書くことが彼の情熱です。彼はミズーリ州の片田舎 Hillsboro に住んでいます。空気は新鮮で景色は霊感を与えるほど美しく、そして素晴らしいワインが年中手に入ります。完璧に透明なワイン・グラスで Stone Hill Blush をすすりながら UNIX シェル・スクリプトに関する記事を執筆すること以上に素晴らしいことはありません。彼の連絡先は bill@zimmerly.comです。



2007年 10月 16日

コンピューターのプログラミングは退屈な仕事ですが、楽しい仕事でもあります。プログラミングの楽しさの 1 つは、古いツールの新たな使い方を学ぶことです。私は最近、ある大規模で複雑な LAMP (Linux®, Apache, MySQL, and PHP/Perl) ベースの CMS (content-management system) の数々のバグを修正する契約を請け負いました。この CMS のアーキテクチャーは標準的な LAMP モデルであり、Enterprise Red Hat Linux で Apache V2.0 を実行しています。Web サイトを構成するコードは数百の PHP ソース・モジュールからなっており、これらのモジュールが Apache のドキュメント・ルート・ディレクトリーの 30 以上のサブディレクトリーに分散されています。システムの Apache 部分と MySQL 部分には変更が必要ないため、バグをつぶすための作業はすべて PHP のワークスペースで行う必要がありました。

この CMS の動作を学ぶためにしばらく時間をかけてみると、私はこのシステムのスマートな設計を次第に好きになりました。そしてこのシステムが、成熟したプログラミング環境の大部分によく見られるように、ごく少数の PHP 関数のみに依存していることに気付きました。(作業の 80% は用意されている関数のうちの 20% で達成される、という昔からの 80/20 ルールをここで思い出します。) この記事では、そうしたほとんど使われていない関数について学ぶ上で、未知の複雑なシステムをデバッグするプロセスがどのように役立つかを説明し、さらに syslog() 関数の豊富な機能を使用することで、新たに得た知識を適用する例を紹介します。

詳細に調べる

PHP プログラミング言語には文字通り何百という関数がありますが、一部の関数 (大部分の関数と言うべきでしょうか) は、この記事のようにそれらの関数を紹介しているものでも読まない限り、使われることがありません。この言語を詳しく学ぶためのもう 1 つの方法は、他の人が PHP で作成したプログラムをデバッグしてみることです。私は、プログラマー達がいかに創造的な方法でツールを使っているか、いつも感銘を受けます。

コンピューターのプログラミングと同様、デバッグは科学でもあり、芸術でもあります。自分が作成したものではないシステムの、わけのわからないバグを追跡する際には、コードのどこでそうしたバグが姿を現すかについて、適切な感覚を持つ必要があります。何百ものコード・モジュールを相手にすることを考えると、バグを示している出力が見つかった所から始めるのが適切です。そしてそこから逆にたどり、問題を切り分けるのです。

例えば、出力されている計算値が不正であることがわかっている場合には、問題につながる中間的な値を見るために、何らかの方法を考えなければなりません。重要なデータベース・クエリーを実行した結果得られる不適切なデータによって、別の問題が表面化するような場合には、SQL 文が生成されるかどうか (そしてそのコードによって MySQL エンジンに送信されるかどうか) を調べ、そこに問題があるかどうかを調べることができる必要があります。

こうしたことを行うための昔ながらの方法の 1 つが、デバッグに必要なストリングや値を単に出力するだけのコードを挿入する方法です。しかし、PHP のようなツールや、どのような Web ベースのアプリケーションであっても、システムの本来の出力 (つまりブラウザーに送信される HTML コード) をデバッグ情報で乱したくはありません。特に検証対象のシステムが実動サーバーであれば、なおさらです。

カスタムのログ・ファイルを作成し、それにログ・メッセージを書き込むこともできますが、既に提供されているツールを使ってみてはいかがでしょう。常に覚えておく必要のあることは、ツールを葬り去ってはいけないとういことです。一般的に必要と思われる機能について、それを実現するライブラリー・ルーチンや関数を言語の作成者が既に提供していないかどうか調べることは、有意義なことです。実際、ある機能が、明らかにプログラミング・パッケージの一部として存在するのではないかと思われるときは、おそらくその通りなのです。

私は、私に必要なものが UNIX® の syslog 機能に似ていることに気付きました。私は PHP には syslog 機能へのフックがありそうだと考え、PHP のドキュメンテーションをちょっと調べてみました。そして、それを見つけたのです。PHP の syslog() 関数は、このプロジェクトの契約を請け負うまで私が長年見過ごしてきた機能です。syslog() を使えば実動システムの大部分のバグを追跡して修正することができ、しかもそれぞれの関数を実行するために要したわずかな時間以外、何も副作用を生ずることがありませんでした。

知識が増え、仕事のスキルが向上してくると、何かをするためにはさまざまな方法があることが明らかになり、それがやがて、必要な作業を行うための当然の方法となるものです。そうした場合に常に念頭に置いておく必要があることは、自分にとって明白なことが他の人にとっては明白ではない、ということです。自分にとって簡単なものが、他の人にとっては途方もなく複雑なものかもしれません。

syslog() 関数のようなツールを利用すると、複雑さをコントロールすることができ、また構成ファイル (syslog.conf など) によってカスタマイズが容易になるという追加の利点もあります。例えば、コードを挿入して SQL 文の書式を作成し、それを syslog() でログに記録するようにし、さらにそれを MySQL に渡して実行することができます。後で syslog.conf ファイルを少し変更するだけで、そのテキストを別のログ・ファイルに送信したり、あるいは単にビット・バケットに送信したりすることもできます。何週間、あるいは何ヶ月か後に、何が起きているのかを再度調べる必要が出てきたら、もう 1 度 syslog.conf ファイルに単純な変更を加えることで、その機能を復元することができます。


syslog

syslog は UNIX の世界で、豊富で多彩な歴史を持っています。syslog は元々 Sendmail プロジェクトの一環として開発されましたが、syslog が非常に便利なことが実証されたため、その他の多くのツールの機能の中に取り入れられています。これは、単純な概念が時には最も強力なことを示しています。

要するに syslog を利用することで、アプリケーションは一連の共通システム・ログ・ファイルにタグ付きメッセージを書き込むことができ、またこのファイルはプログラマーとネットワーク管理者がアクセスしやすい場所に置くことができるのです。これはつまり、例えば Web サーバー上に syslog を構成し、別のサーバーのシステム・メッセージをログに記録できる、ということを意味します (別のサーバーとして、例えばセキュリティー・ファイアーウォールの背後の数階層深い所にある、前述の管理者がアクセスしやすいサーバーを考えることができます)。しかし私の目的には、ファイルが /var/log ディレクトリーに書き込まれるというデフォルトの動作で十分です。

syslog の機構はブート時に起動し、その初期動作は syslog.conf ファイルの中のルールで定義されます。これらのルールによって、syslog の機構で何をログに記録し、何を記録しないかを細かく調整することができます。これは大量の処理を行う稼働率の高いサーバーでは、管理可能なサイズのログ・ファイルを作成できるということです。

各ルールは、セレクター (selector) とアクション (action) という 2 つのフィールドで構成されています。基本的に、セレクター・フィールドはどの機能 (facility) (例えば kern や user、mail、lpr など) をログに記録するのかを選択し、またその機能の優先度を選択します。優先度 (priority) フィールドには debug や info、notice、warning などのキーワードが含まれます。そしてルールのアクション・フィールドは、セレクター・フィールドと一致する種類のメッセージに対して何をするのかを定義します。ルールは、どのファイルにメッセージをログとして記録するか、どのマシン宛にログ・メッセージを送信するか、どのユーザー宛に (コンソール・メッセージの形式で) メッセージを送信するか、などを指定します。


ロギング

syslog 機能に関連する info ページと man ページを調べることで、必要に応じた syslog のシステムを構成するための方法を学ぶことができます。私の場合は、実動の CMS システムが実行している間のさまざまな時点で、PHP の各変数がどんな値を取るのかを知る必要がありました。また、あるモジュールがいつ起動し、終了するのか、そしてさまざまな中間変数がどんな値なのかも知る必要がありました。何をログするかの詳細に入る前に、ロギングのための基本を設定しましょう。

好みのエディターを使ってリスト 1 に示すファイルを作成し、それに test.php という名前を付け、そしてそれを Apache のドキュメント・ルートがある場所に置きます (私のシステムでは /var/www です)。

リスト 1. test.php
<html>
  <head>
    <title>PHP Test Page</title>
  </head>
  <body>
    <?php
	syslog(LOG_NOTICE, "{$_SERVER['REMOTE_ADDR']}: test.php - PHP Index page accessed.");
	echo '<p>PHP Test Page</p>';
    ?>
  </body>
</html>

また、PHP がインストールされ、構成されている必要があります。もしそうでない場合には、その方法へのリンクを「参考文献」に挙げてあります。すべてが適切に構成されていれば、http://localhost/test.php という URL のページにアクセスすると、ブラウザーに以下のテキストが表示されるはずです。

PHP Test Page

次に、X 端末ウィンドウを開いて以下のコマンドを入力し、/var/log/messages ファイルに何がログとして記録されたかを調べます。

tail /var/log/messages

すべてが順調に行けば、リストの最後の方に次のような行が表示されているはずです。

Jul 23 14:43:42 localhost apache2: 127.0.0.1: test.php - PHP Index page accessed.

表示されていれば成功です。これで、対象とする複雑なシステムの、詳細なデバッグを始めるために必要なことをすべて検証できました。

私は、すべての PHP/MySQL コールに syslog() を使った方が良いことに気付きました。そうすれば、Web サイトと対話動作する時にはいつも、返されるページを構築するためにどの SQL クエリーが生成されているのかをリアルタイムで調べることができます。これを手軽に行うためには、別の X 端末ウィンドウを開き、-f オプションを付けた tail コマンドを使ってメッセージ・ログを「ライブ」で表示させます。

tail -f /var/log/messages

何をログに記録するか

これでロギングが動作することを検証でき、またロギングの仕組みを使って結果を見ることができたので、これらのツールを使って外部システムを学ぶプロセスを可能な限り短縮するための、いくつかのヒントを挙げておきます。

どのモジュールが、ドキュメンテーションに書かれている以外の、どんなことをするのかを知ることが重要です。私はこの理由から、モジュールの最初と最後をマーキングするログ・メッセージを含めるようにしています。そうすれば、tail -f /var/log/messages コマンドを別の X 端末ウィンドウで実行し、そこに表示されるログ・メッセージを見ながら Web サイトのページをいじることができます。こうすることで、ブラウザーが新しいページを要求するごとに、どのモジュールが、どの順序で実行されるかを見ることができます。

また私は、PHP コードの実行中に呼び出されて動作を開始する、さまざまなプログラム同士が切り替わる箇所もログを記録するようにしています。例としては、データベースに対してクエリーを実行するために MySQL が呼び出された時、あるいはデータのフォーマットを変更するために外部プログラム (例えば XSLT (Extensible Stylesheet Language Transformation) エンジンなど) が呼び出された時などがあります。各 PHP コード・モジュールにこうしたチェックポイントを体系的にに挿入するという作業そのものが、さまざまなモジュールの名前や場所に慣れるために役立ちます。さまざまなページをブラウズする一方でコードから送られて、別の X 端末に表示されたメッセージを見ていると、そのシステムに関する知識を強化し、高めるための重要なフィードバックを得ることになります。


まとめ

syslog 機能は、誰か他の人が作成したアプリケーションをデバッグするための強力なツールです。syslog を使うことで、どのモジュールが実行されているのか、どの SQL 文が実行されているのか、また Web サイトをナビゲートする間にどの変数の値が変化するのかを見ることができます。これによって、問題のありそうなモジュールを正確に見つけやすくなります。

参考文献

学ぶために

  • syslog() 関数について詳しく学んでください。
  • Wikipedia で syslog の歴史を調べてください。
  • PHP.net は PHP 開発者のための中心的なリソースです。
  • Recommended PHP reading list」を調べてみてください。
  • developerWorks には他にも PHP に関する資料が豊富に用意されています。
  • IBM developerWorks の PHP project resources を利用して PHP のスキルを磨いてください。
  • developerWorks podcasts では、ソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。
  • PHP でデータベースを使うのであれば、Zend Core for IBM を調べてみてください。これはシームレスでそのまま使用でき、インストールも容易な、IBM DB2 9 をサポートする PHP の開発環境であり実動環境です。
  • developerWorks の Technical events and webcasts で最新情報を入手してください。
  • IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
  • developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
  • IBM とオープンソース技術、そして製品機能を調べ、学ぶために、無料の developerWorks On demand demos をご覧ください。

製品や技術を入手するために

  • 皆さんの次期オープンソース開発プロジェクトを IBM trial software を使って革新してください。ダウンロード、あるいは DVD で入手することができます。
  • IBM 製品の評価版をダウンロードし、DB2® や Lotus®、Rational®、Tivoli®、WebSphere® などのアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source
ArticleID=269428
ArticleTitle=syslog を使って PHP アプリケーションを改善し、デバッグする
publish-date=10162007