以前、pynotifyというpythonの検知プログラムを書きましたが、元々はinotifyというLinux上のパッケージのライブラリが元になっています。
以前調べたリンク
実務で「inotifyでログの状態を監視→新しく書き込まれたログを読み込み→特定の条件下でDBに登録」という処理があり、PHPでこれを実装したのでメモ。
Contents
inotifyのインストール
拡張モジュールとしてpeclからダウンロードしてphpのなかに組み込みます。
以前やったメールパーサーのインストールと近いです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
tar -xvzf inotify-最新バージョン.tar.gz //http://pecl.php.net/package/inotifyで最新バージョンを cd inotify-最新バージョン phpize ./configure make make install #下記メッセージが出ます #installing shared extensions: /usr/lib64/php/modules/ vim /etc/php.ini #下記のコメントアウトを外す extenshion_dir="/usr/lib64/php/modules" #モジュールのディレクトリはこことは限らないので各自の環境で echo "extension=inotify.so" > /etc/php.d/30-inotify.ini #apache再起動 service httpd restart #拡張モジュールが入っているかの確認 php -i | grep inotify or php -m | grep inotify |
検知スクリプト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$logpath = 'ここにログのパスを入力'; //ファイルポインタを開く $fp = fopen($logpath, "r"); if ($fp === false) { return null; } //fpをファイルの末端に持っていく(新規に書き込まれたデータのみ見たいため) fseek($fp, 0, SEEK_END); $fd = inotify_init(); $watch_descriptor = inotify_add_watch($fd, $logpath, IN_MODIFY); if ($watch_descriptor == false) { return null; } while (($events = inotify_read($fd)) !== false) { foreach ($events as $event) { if (!empty($event['mask']) && $event['mask'] == IN_MODIFY) { $logstr = stream_get_contents($fp); //ここにログを抽出するプログラムをかく } } sleep(5); } |
検知の直前でfseekをする意義ですが、読み込みかつ、ファイルの最終点を検知するために、fopenでポインタを開いた後、fseek($fp, 0, SEEK_END)
で最終点に移動します。
あとはこのプログラムをsupervisorなどでデーモン化しておくと常駐したプログラムとなります。
参考リンク
[PHP] inotify関数を使ってログを監視するスクリプトを作ろう
http://php.net/manual/ja/book.inotify.php
phpの拡張モジュールに関して