デーモン監視ツール、PSMon

 PSMonは、プロセスを確実に動作させ、そのプロセスの実行中に使用するCPUやRAMなどのリソース量とインスタンス数を監視するユーティリティーだ。指定されたプロセスが上限を超えてリソースを使おうとするとそのプロセスは強制終了させられ、クラッシュしたプロセスは再起動される。

 PSMonは、Fedora 9、Ubuntu Hardy、OpenSUSE 11のいずれのリポジトリーにも含まれておらず、PSMonのtarballを展開してインストールする。PSMonの実行には、このほか、いくつかのPerlモジュールが必要だ。これらのモジュールはmanualページにある説明に従って手作業でCPANからインストールする。なお、PSMonのtarball内にあるsupportサブディレクトリーには、所要のインストール作業を行うスクリプトinstall.shが用意されている。

 このスクリプトでインストールすればPSMonの実行に必要なPerlモジュールもインストールされるが、お使いのディストリビューションのパッケージ・リポジトリーからこれらのモジュールあらかじめ入手しておいてもよい。この方法には、Linuxディストリビューションの通常の更新でモジュールを最新状態に保てるという利点がある。以下に、必要なモジュールをインストールしてからインストール・スクリプトを使ってPSMonプログラムをインストールする手順を示す。

# yum install perl-CPAN perl-YAML
# yum install perl-Config-General perl-Proc-ProcessTable perl-Unix-Syslog
# tar xjf psmon-1.29.tar.bz2
# cd psmon*
# ./support/install.sh
Checking for Config::General ... found
Checking for Proc::ProcessTable ... found
Checking for Unix::Syslog ... found
Checking for Getopt::Long ... found
Installing psmon ... done
Installing psmon-config ... done
Installing etc/psmon.conf ... done
Generating HTML documentation support/psmon.html ... done
Installing manual psmon.1 ... done

 このスクリプトは構成ファイルも作ってくれる。構成ファイルの構文はApacheに似せて設計されており、キーワード(ディレクティブ)と値の対という形で記述する。最上位レベルでは全般に関する設定を、Processグループでは各プロセスに関する設定を記述する。「Process *」という特別なグループを使うとすべてのプロセスに適用する設定を記述することができるが、意図しないプロセスまで多数強制終了させてしまいかねないので使わない方がよい。

 /etc/psmon.confファイルの冒頭付近には、「Disabled True」というディレクティブがあるはずだ。このディレクティブが無効にされるまで、PSMonは何もしない。

 最上位レベル、つまりProcessグループの外側で使うディレクティブをいくつか見てみよう。Frequencyディレクティブはプロセス・テーブルを調べる間隔を指定する。単位は秒で、デフォルトは60だ。これを短く5(秒)に設定すればパフォーマンスの低いプロセスを早めに強制終了し再起動させることができるが、PSMonが消費するCPU時間は増大する。AdminEmailディレクティブはプロセスを起動または強制終了させたときやそうした操作で障害が発生したときに通知を送る電子メール・アドレスを指定する(デフォルトはroot@localhost)。

 NeverKillPIDNeverKillProcessNameは強制終了の対象外とするプロセスを指定するディレクティブだ。プロセスID(PID)またはプロセス名を空白で区切って列挙する。デフォルトはそれぞれ1とカーネル・スレッドの一覧で、たとえ間違っても終了させたくないプロセスが並んでいる。

 Processグループの記述例を下に示す。この例のように、各グループはXML風のタグで挟んで記述する。記述を適用するプロセスの名前は、最初に置く開始タグProcessで指定する。このプロセス名には、パス情報やコマンドライン・オプションを指定することはできない。プロセスのフル・パス(あるいは、プロセスを特定するための正規表現)を指定できるようにしてほしいものだ。もっとも、例示のSSHデーモンの場合は、sshdとするだけでも動作中のほかのプロセスと間違うことはないだろうが。この例のように記述すると、SSHデーモンが何らかの理由で終了したりクラッシュしたりしても再起動される。

<Process sshd>
   SpawnCmd    /sbin/service sshd start
</Process>

 Processグループで使えるディレクティブをいくつか見てみよう。まず、Instancesディレクティブは、実行するプロセス数の上限を指定する。またKillCmdディレクティブは、誤動作したプロセスを終了させるための方法を指定する。このディレクティブが記述されていない場合、SIGKILLが送られる。いきなり強制力の強いSIGKILLを送るのではなく、まずSIGTERMを送って数秒間待ち、それでも終了しない場合にSIGKILLを送るようにしたい、あるいは、/etc/init.dスクリプトでサービスを停止させたいときは、KillCmdディレクティブでその方法を指定する。

 プロセスが使うリソースを制限するディレクティブには、PctCPUPctMEMTTLなどがある。それぞれ、CPUとRAMの使用量の上限(百分率で指定)、生存期間を指定する。また、PIDFileディレクティブは、強制終了の対象外とするデーモンのプロセスIDを列挙したファイルへのパスを指定する。このディレクティブは、PctCPU、PctMEM、TTLと共に使う。たとえば、ネットワークで通信を行う子プロセスを多数生成するデーモンで子プロセスが使用するシステムRAMが70%を超えないようにしたい場合、PIDFileで親のコントロール・プロセスを強制終了させないようにした上で、メモリーを過大に使い始めた子プロセスだけを強制終了するようにする。

 TTLディレクティブは、一定時間で処理を完了するように意図されたプロセスに、その上限時間を守らせたいときに便利だ。たとえば、updatedbコマンドやunisonやfindの使用を1時間に制限し、ユーザーのcronジョブから野放図に実行されないようにしたいときは、次のようにする(findの場合)。

<Process find>
   ttl          86400
   instances    30
</Process>

 PSMonが生成する情報の量を制御するディレクティブには、NoEmailNoEmailOnKillNoEmailOnSpawnなどがある。この3つのディレクティブはPSMonから送信されるメールを制御する。デフォルトはいずれもFalseで、これをTrueに設定すると、それぞれ、すべてのメール、プロセスの強制終了時のメール、プロセスの再起動時のメールを抑制することができる。

 LogLevelディレクティブとAdminEmailディレクティブはプロセスごとに設定することもできる。したがって、Apacheなどのきわめて重要なプロセスだけは、クラッシュしたときにSMSゲートウェイにメールを送るようにすることができる。LogLevelを変えると停止または起動に失敗した際のレベルも変わり、LogLevel+1になる。したがって、ApacheグループでLogLevelを高く設定すると、起動時のエラーは高い優先度でsyslogに記録されることになる。

 PSMonは--daemonコマンドライン・オプションが指定されているとデーモンとして動作するが、この場合、USR1シグナルを受信すると直ちにプロセスを調査する。

まとめ

 システムのリソースを大量に使っているからといって、やみくもに、そのプロセスを強制終了させろと言うつもりはない。プロセスが数分間CPUの95%を使うことは十分あり得るし、誰しもそのような場合にプロセスを強制終了させたくはあるまい。しかし、コマンドを適切に使った場合に想定される最長時間より十分に長い時間を上限とするなら、気づかないまま誤動作しているcronジョブからシステムを保護する効果はあるだろう。また、停止したプロセスを自動再起動する機能は絶対に有用だ。sshdやApacheがクラッシュすることはあまりないが、9時間の空の旅に出ているときにクラッシュする可能性はある。PSMonはそうした場合に威力を発揮する。システム管理用ツールキットとして揃えておきたいユーティリティーだ。

Ben Martin 10年以上にわたってファイルシステムに携わっている。博士課程を修了し、現在、libferris、ファイルシステム、検索ソリューションを中心にコンサルティングをしている。

Linux.com 原文(2008年9月2日)