понедельник, 30 января 2012 г.

php-fpm status polling

Just a brief note...
If you wish to monitor php-fpm pool, it provides status page determined by status_path configuration parameter in pool config file.

pm.status_path = /statusfpm

Status page usually looks like this:

X-Powered-By: PHP/5.3.3-1ubuntu9.7
text/plain
Content-type: text/html

accepted conn: 253745
pool: mhouse
process manager: static
idle processes: 50
active processes: 0
total processes: 50

The problem is that it is not usually accessible by HTTP, and you should usually use web-server to communcate with php-fpm by FastCGI protocol. Now let's imagine that you have 10 php-fpm nodes and one nginx server. It seems justified to get status from each php-fpm node, you should talk directly to php-fpm. And you can use php FCGIClient (big thanks to its author, Pierrick Charron) for this task.
Using this library is straightforward. The only difficulty is to send necessary headers to php-fpm. These headers we can find out with tcpdump, monitoring nginx and php-fpm communications. So, the following script can be used to retrieve distinct php-fpm statistics:

<?php
require('fastcgi.php');

$client = new FCGIClient('192.168.0.1', '9000');
$answer=$client->request(
array(
'GATEWAY_INTERFACE' => 'FastCGI/1.0',
'REQUEST_METHOD' => 'GET',
'SCRIPT_FILENAME' => '/usr/local/nginx/html/statusfpm', //Nginx document root
'SCRIPT_NAME' => '/statusfpm', //our pm.status_path
),''
);
?>


Recieved file can be analyzed further and result may be fed to your monitoring system:

$lines=split("\n",$answer);
//Line 0 (4 - with headers) - Accepted connections
$cnum=strpos($lines[4],':');
$accepted=trim(substr($lines[4],$cnum+1));

//Line 3(7) - idle processes
$cnum=strpos($lines[7],':',1);
$idle=trim(substr($lines[7],$cnum+1));

//Line 4(8) - active processes
$cnum=strpos($lines[8],":");
$active=trim(substr($lines[8],$cnum+1));

//Line 5(9) - total processes
$cnum=strpos($lines[9],":");
$total=trim(substr($lines[9],$cnum+1));



The latest part depends on monitoring system you using. We have some service php functions to interact with zabbix (in particular, slightly modified zabbix_sender function).