10 proc.memおよびproc.numアイテムでのプロセスの選択に関する注記

コマンドラインを変更するプロセス

一部のプログラムでは、現在のアクティビティを表示する方法としてコマンドラインの変更を使用しています。 ユーザーは、psおよびtopコマンドを実行することでアクティビティを確認できます。 このようなプログラムとしてはPostgreSQL,Sendmail,Zabbixが含まれます。

Linuxでの例を見てみましょう。 いくつかのZabbixエージェントプロセスを監視したいとします。

psコマンドは、対象のプロセスを次のように表示します

$ ps -fu zabbix
       UID        PID  PPID  C STIME TTY          TIME CMD
       ...
       zabbix    6318     1  0 12:01 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf
       zabbix    6319  6318  0 12:01 ?        00:00:01 sbin/zabbix_agentd: collector [idle 1 sec]                          
       zabbix    6320  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: listener #1 [waiting for connection]            
       zabbix    6321  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: listener #2 [waiting for connection]            
       zabbix    6322  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: listener #3 [waiting for connection]            
       zabbix    6323  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: active checks #1 [idle 1 sec]                   
       ...

名前とユーザーでプロセスを選択すると次のようになります。

$ zabbix_get -s localhost -k 'proc.num[zabbix_agentd,zabbix]'
       6

次にzabbix_agentd実行可能ファイルの名前をzabbix_agentd_30に変更して再起動します。

ps now shows

$ ps -fu zabbix
       UID        PID  PPID  C STIME TTY          TIME CMD
       ...
       zabbix    6715     1  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30 -c /home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf
       zabbix    6716  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: collector [idle 1 sec]                          
       zabbix    6717  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: listener #1 [waiting for connection]            
       zabbix    6718  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: listener #2 [waiting for connection]            
       zabbix    6719  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: listener #3 [waiting for connection]            
       zabbix    6720  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: active checks #1 [idle 1 sec]                   
       ...

名前とユーザーでプロセスを選択すると、誤った結果が生成されます。

$ zabbix_get -s localhost -k 'proc.num[zabbix_agentd_30,zabbix]'
       1

なぜ実行可能ファイルの名前を長い名前に変更するだけで、結果がまったく異なるのでしょう?

Zabbixエージェントはプロセス名の確認から始めます。/proc/<pid>/statusファイルが開かれ、行Nameがチェックされます。 この場合Name行は次のとおりです。

$ grep Name /proc/{6715,6716,6717,6718,6719,6720}/status
       /proc/6715/status:Name:   zabbix_agentd_3
       /proc/6716/status:Name:   zabbix_agentd_3
       /proc/6717/status:Name:   zabbix_agentd_3
       /proc/6718/status:Name:   zabbix_agentd_3
       /proc/6719/status:Name:   zabbix_agentd_3
       /proc/6720/status:Name:   zabbix_agentd_3

statusファイルのプロセス名は15文字に切り捨てられます。

同様の結果はpsコマンドで見ることができます。

$ ps -u zabbix
         PID TTY          TIME CMD
       ...
        6715 ?        00:00:00 zabbix_agentd_3
        6716 ?        00:00:01 zabbix_agentd_3
        6717 ?        00:00:00 zabbix_agentd_3
        6718 ?        00:00:00 zabbix_agentd_3
        6719 ?        00:00:00 zabbix_agentd_3
        6720 ?        00:00:00 zabbix_agentd_3
        ...

明らかにこれは proc.num[]``nameパラメータ値zabbix_agentd_30と違います。statusファイルのプロセス名と一致しなかった場合、Zabbixエージェントは/proc/<pid>/cmdlineファイルに変わります。

エージェントが"cmdline"ファイルをどのように見るかは、コマンドを実行することで確認できます。

$ for i in 6715 6716 6717 6718 6719 6720; do cat /proc/$i/cmdline | awk '{gsub(/\x0/,"<NUL>"); print};'; done
       sbin/zabbix_agentd_30<NUL>-c<NUL>/home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf<NUL>
       sbin/zabbix_agentd_30: collector [idle 1 sec]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: listener #1 [waiting for connection]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: listener #2 [waiting for connection]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: listener #3 [waiting for connection]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: active checks #1 [idle 1 sec]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...

この場合の/proc/<pid>/cmdlineファイルには、C言語の文字列を終了するために使用される非表示の出力不可能なヌルバイトが含まれています。 この例ではヌルバイトは"<NUL>"として示されています。

Zabbixエージェントはメインプロセスの"cmdline"をチェックし、'name'パラメータ値'zabbix_agentd_30'と一致する'zabbix_agentd_30'を取得します。よって、メインプロセスはアイテムproc.num[zabbix_agentd_30,zabbix]によってカウントされます。

次のプロセスをチェックするとき、エージェントはcmdlineファイルからzabbix_agentd_30: collector [idle 1 sec]を取得しようとしますが、nameパラメータがzabbix_agentd_30を満たすことができません。したがって、コマンドラインを変更しないメインプロセスのみがカウントされます。 他のエージェントプロセスはコマンドラインを変更し、無視されます。

このことから今回の例では、プロセスを選択するためにproc.mem[]proc.num[]nameパラメータを使用できないことを示しています。

適切な正規表現でcmdlineパラメータを使用すると、正しい結果が得られます。

$ zabbix_get -s localhost -k 'proc.num[,zabbix,,zabbix_agentd_30[ :]]'
       6

コマンドラインを変更するプログラムを監視するためにproc.mem[]proc.num[]の項目を使用するときは注意してください。

nameおよびcmdlineパラメータをproc.mem[]およびproc.num[]アイテムに入れる前に、proc.num[]アイテムおよびpsコマンドを使用してパラメータをテストすることをお勧めします。

Linuxカーネルスレッド

proc.mem[]およびproc.num[]項目のcmdlineパラメータでスレッドを選択することはできません

例としてカーネルスレッドの1つを上げましょう。

$ ps -ef| grep kthreadd
       root         2     0  0 09:33 ?        00:00:00 [kthreadd]

プロセスnameパラメータで選択できます。

$ zabbix_get -s localhost -k 'proc.num[kthreadd,root]'
       1

しかしプロセスcmdlineパラメータによる選択は機能しません。

$ zabbix_get -s localhost -k 'proc.num[,root,,kthreadd]'
       0

その理由は、Zabbixエージェントがcmdlineパラメータで指定された正規表現を受け取り、それをプロセス/proc/<pid>/cmdlineのコンテンツに適用するためです。 カーネルスレッドの場合、それら/proc/<pid>/cmdlineファイルは空です。 よってcmdlineパラメータが一致することはありません。

proc.mem[]およびproc.num[]アイテムのスレッドカウント

Linuxカーネルスレッドはproc.num[]アイテムによってカウントされますが、proc.mem[]アイテムのメモリは報告されません。

例:

$ ps -ef | grep kthreadd
       root         2     0  0 09:51 ?        00:00:00 [kthreadd]
       
       $ zabbix_get -s localhost -k 'proc.num[kthreadd]'
       1
       
       $ zabbix_get -s localhost -k 'proc.mem[kthreadd]'
       ZBX_NOTSUPPORTED: Cannot get amount of "VmSize" memory.

しかし、カーネルスレッドと同じ名前のユーザープロセスがある場合は次のようになります。

$ ps -ef | grep kthreadd
       root         2     0  0 09:51 ?        00:00:00 [kthreadd]
       zabbix    9611  6133  0 17:58 pts/1    00:00:00 ./kthreadd
       
       $ zabbix_get -s localhost -k 'proc.num[kthreadd]'
       2
       
       $ zabbix_get -s localhost -k 'proc.mem[kthreadd]'
       4157440

proc.num []はカーネルスレッドとユーザープロセスの両方をカウントしました。 proc.mem []はユーザープロセスのメモリのみを報告し、カーネルスレッドメモリを0であるかのようにカウントします。これはZBX_NOTSUPPORTEDが報告された上記の場合とは異なります。

プログラム名がスレッドの1つと一致する場合は、proc.mem[]およびproc.num[]アイテムを使用するときに注意してください。

パラメータをproc.mem[]およびproc.num[]アイテムに入れる前に、proc.num[]アイテムとpsコマンドを使用してパラメータをテストすることをお勧めします。