前回の「inotifyを使ってファイルやディレクトリに起きたイベントを簡単に監視する 」にてinotifyの機能を使ってみましたが、PHPのプログラムからも利用できるようなので、試しにログを監視するスクリプトを作ってみました。
inotifyの機能を使って独自のPHPスクリプトを書けば、何かのファイルを監視したり、ディレクトリにおきた変化をトリガーにして何か処理をするというようなスクリプトも簡単に書くことができます。
PECLのinotifyパッケージをインストールする
PHPからinotifyの機能を利用するにはPECLの拡張モジュールとして組み込む必要があります。
PECLで提供されている拡張モジュールのインストール方法 は色々用意されているようですが、今回はphpizeコマンドを使ってモジュールをコンパイルし、PHPに組み込むようにしました。
1. PECLのinotifyパッケージをダウンロードする
まずは、PECLの公式サイトからinotifyパッケージ をダウンロードします。
ダウンロード後はサーバーに転送し、下記のようにモジュールをコンパイルします。
# tar -xvzf inotify-0.1.3.tgz # cd inotify-0.1.3 # phpize # ./configure # make # make install
make install実行時の最後に拡張モジュールのインストール先が示されますので、その場所をメモしておきます。
Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20060613/
上記ディレクトリ内に、inotify.soという動的ライブラリファイルが作られています。
2. inotify拡張モジュールをPHPに組み込む
先ほど作られたinotifyの動的ライブラリファイル(inotify.so)をPHPの設定ファイル(php.ini)にセットして読み込まれるようにします。
extension_dir = "/usr/local/lib/php/extensions"
拡張モジュール用のディレクトリは、環境に合わせて適当に編集してください。
このままでは、extensionsディレクトリ以下にはinotify.soファイルは存在しないので、シンボリックリンクを作成しておきます。
# cd /usr/local/lib/php/extensions/ # ln -s ./no-debug-non-zts-20060613/inotify.so inotify.so
最後に、Apacheを再起動しておきましょう。
3. inotify拡張モジュールが有効になっているかテストしてみる
PECLのinotifyパッケージ内にはサンプルプログラム(tail.php)付属しています。
これを実行してうまく動作するか試してみましょう。
# tail.php /home/hoge/test.txt
引数に監視するファイルのパスを指定します。
上記を実行中に、test.txtファイルに文字を書き込んでみます。
# echo "xyz" >> /home/hoge/test.txt
すると・・・
# php tail.php /home/sakaiya/test.txt Event received ! xyz
ターミナル上にイベントをキャッチしたメッセージが表示されました。
どうやらうまく動作してくれているようです。
ログファイルに何か書き込まれたらアラートメールを発砲する監視スクリプト
よくあるログ監視用のスクリプトを書いてみたいと思います。
監視ツールを導入するとなるとかなりの費用がかかってしまうため、このような簡易スクリプトで代替できる場合もあると思います。
先ほどのサンプルスクリプトをベースに作ってみました。
<?php // 監視対象のログファイル define("LOG_FILE_PATH", "/var/log/error.log"); // 通知先 define("MAIL_TO", itboy@hogehoge.com">itboy@hogehoge.com); // ログファイルが存在するか、オープンできるかチェック if (!file_exists(LOG_FILE_PATH) || ($fp = fopen(LOG_FILE_PATH, "r")) === FALSE) { echo "ログファイルの読み込みに失敗しました"; exit; } // ファイルポインタを最後に持っていく(ログファイルに出力された内容を取得するため) fseek($fp, 0, SEEK_END); // inotifyのインスタンスを初期化 $fd = inotify_init (); // inotifyの監視対象ファイルをセット // ログファイルに内容が書き込まれた(変更があった)イベントを取得する
if (($watch_descriptor = inotify_add_watch ($fd, LOG_FILE_PATH, IN_MODIFY)) === FALSE) { echo "ログファイルの読み込みに失敗しました"; exit; } // イベントが発生するまでループ while (($events = inotify_read ($fd)) !== false) { // ログファイルに何か書き込まれたときはアラートのメールを発砲 foreach($events as $event) { if (!($event['mask'] & IN_MODIFY)) continue; // ログファイルに書き込まれた内容を取得 $log = stream_get_contents($fp); // メールを送信 mb_send_mail(MAIL_TO, "WARNING", $log); break; } } inotify_rm_watch ($fd, $watch_descriptor); fclose($fp); ?>
inotifyでは、イベントの種類をキャッチすることはできますが、何が書き込まれたのかなんかはわからないため、別でファイルを開いておいてその内容を取り込むようになっています。
テストをしたければ、上記スクリプトの実行中に
echo "DBが停止しました" >> /var/log/error.log
見たいな事をしてみれば、その内容がメールで送信されるはずです。
なお、実運用に耐えうるスクリプトにはなっていないのであしからず。
例えば、ログファイルに続けざまに書き込みが行われたら大量のメールが送信されることになります。
障害時には、そのように大量のメッセージを出力するということがよくあったりします。
あと、ログファイルにlogrotateなどをセットしておくと、そのローテーション実行時に場合によってはログファイルを見失うことになります。
(昔のログファイルを削除して、新規に作り直すような設定をしておいた場合)
注意)
現在のPECLのinotifyパッケージは、1つのイベントしか監視できないようです。
監視するイベントは、inotify_add_watch 関数で追加していきますが、複数追加しても最後にセットした監視イベントしか拾わなくなります。
[PR]面倒な事はおまかせ!@YMCの「マネージドサーバー」月額4,095円~
[PR]格安固定IPが【5分で発行】+【初期無料】+【2ヶ月無料体験】
[PR]SSLはグローバルサイン(最短2分で発行、年額36,540円)
関連記事
ApacheのプロセスがどのPHPプログラムの処理をしているか調べる方法
inotifyを使ってファイルやディレクトリに起きたイベントを簡単に監視する
BOM付きUTF-8のPHPファイルからBOMだけを一度に削除するスクリプト
NFSマウントした領域内でPHPのsession_startを実行すると異様に重い件
PHPのプログラムをデーモンとして動かしてくれるPEAR::System_Daemon
簡単にファイル検索をするためのlocateコマンドオリジナル活用法
不要なファイルやディレクトリを削除できる「tmpwatch」コマンド