ApacheのプロセスがどのPHPプログラムの処理をしているか調べる方法 | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

Apacheのプロセスを見てみて、異様にCPUやメモリを食ってる処理をしているような場合、それが何のプログラムを処理しているのか調べたいという場合があります。

調べてみると幾つかの方法があるようなので、まとめてみました。



PHPプログラム側でApacheのプロセスIDを調べる方法


PHPには、getmypid というプロセスIDを取得する関数が存在します。

それをプログラムに書いてロギングすれば、どのApacheのプロセスで処理をしているのかがわかります。


<?php
$log = $_SERVER['PHP_SELF'] . " [ " . getmypid() . " ]\n";
$fp = fopen("/var/log/pid.log", "a");
fwrite($fp, $log);
fclose($fp);


結果は、下記のようにプログラム名とプロセスIDが出力されます。


/hoge.php [ 25401 ]


Apacheの設定でプロセスIDをログに残す


PHPでわざわざロギングするのは余計な処理になる上に、応急処置で対処したい際にわざわざロジックを追加したりすることは出来なかったりします。

Apache自身のログの設定で、プロセスIDを記録する方法もあります。


LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %P" combined

ログのフォーマットの最後に記載していますが「%P」を加えることで、ApacheのプロセスIDをログに残すことができます。

後は、アクセスログを覗いてみると


[14/Aug/2011:00:40:26 +0900] "GET /hoge.php HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0" 25401

最後に処理したApacheのプロセスIDが表示されています。

ただ、これも普段Apacheのログの設定でプロセスIDを取るようにしていない場合は、変更が必要になるので対処できない場合もあるかもしれません。



/procから該当プロセスが何を処理しているかを調べる


/proc以下にあるApacheのプロセスIDのディレクトリから、何のプログラムを動かしているのかある程度推測することも出来ます。

これは、psコマンドなどで処理が重くなっているプロセスを見つけ、そのプロセスIDが何の処理をしているのかを調べたいという場合に使えるかもしれません。


まず、psコマンドで異常なプロセスを見つけます。


# ps aux | grep http
root     30228  0.0  1.5 224608  8052 ?        Ss   00:56   0:00 /usr/sbin/httpd
apache   30236  0.0  3.0 234596 15724 ?        S    00:56   0:00 /usr/sbin/httpd


メモリやCPU使用量からある程度推測して、上記の場合30236のプロセスIDが怪しいかな、と推測してみます。

(上記は、実際そんなにCPUやメモリを食ってるわけではありませんけど)


で、/proc/プロセスID/cwdを覗いてみると、そのプロセスが処理しているカレントワーキングディレクトリが表示されます。


# ls /proc/30236/cwd/
hoge.php

上記から、30236のプロセスIDはhoge.phpを処理していることがわかります。

ただし、上記のようにディレクトリ内に1つのプログラムしかない場合は、簡単に見分けられますが、実際には複数のプログラムが混在しているでしょうから、さらに絞り込みは必要になるでしょう。

あくまでカレントワーキングディレクトリということなので、ドキュメントルート直下で動いているプログラムであれば、ドキュメントルートを表示します。


そのApacheプロセスがどのディレクトリで処理を行っているのかを調べたい場合に、簡単に見ることができるのでトラブルの原因を調べる1つのインプットとして使えるかもしれません。