{"id":709,"date":"2023-06-14T18:05:35","date_gmt":"2023-06-14T10:05:35","guid":{"rendered":"https:\/\/play.datalude.com\/blog\/?p=709"},"modified":"2023-06-14T18:05:37","modified_gmt":"2023-06-14T10:05:37","slug":"php-fpm-monitoring-for-single-domain","status":"publish","type":"post","link":"https:\/\/play.datalude.com\/blog\/2023\/06\/php-fpm-monitoring-for-single-domain\/","title":{"rendered":"php-fpm monitoring for single domain"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ran into this one recently and the solution came out of left field, so I thought I'd throw it out to the internet at large. I've got a server which is running php-fpm and nginx. However it has several websites running on it, each of which has its own php-fpm\/pool.d\/ profile. We were having a problem with one of the websites, which got a lot more traffic than the others, so we needed a way to monitor its php-fpm performance.<br><br>Setting up php monitoring is not hard. There are many guides around the internet. You put the line <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pm.status_path = \/status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">in your fpm pool file, then add a block to your nginx config so that it can only be accessed by certain IP addresses. <\/p>\n\n\n\n<!--more-->\n\n\n\n<pre class=\"wp-block-code\"><code>        location ~ ^\/status {\n         access_log off;\n         allow 127.0.0.1;    # localhost\n         allow 12.23.34.45;   # my remote IP\n         deny all;  \n         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n         fastcgi_index index.php;\n         include fastcgi_params;\n         fastcgi_pass unix:\/run\/php\/php-fpm-mysite.sock;\n        }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You access the URL mysite.com\/status and all is good. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Things get more complicated when you have a server where each domain has its own fpm pool file. The \/status line in this case is just referring to that domain. If you access the mydomain.com\/status URL from an external browser, the domain name resolves and nginx picks the correct php-fpm pool file, and you see the stats. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now consider using curl from localhost. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> # On a server where there's only one pool file, this works. But when there are multiple pool files it doesn't know which one to use\ncurl http:\/\/127.0.0.1\/status\n# Can we resolve it with a Host header? No\n curl -H \"Host: mysite.com\" http:\/\/127.0.0.1\/status\n# Resolve looks hopeful, but actually it doesn't work with SSL\n curl --resolve 'mysite.com:443:127.0.0.1' https:\/\/127.0.0.1\/status\n# Maybe --insecure will help? No\n curl --resolve 'mysite.com:443:127.0.0.1' https:\/\/127.0.0.1\/status --insecure\n# Wait, maybe we can connect directly to the socket, and target the website that way! Nope.\ncurl --unix-socket \/var\/run\/php\/php-fpm-mysite.sock http:\/\/status\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After exhausting the Internet's wisdom on this, there didn't seem to be a way to get curl to fetch the information. It was needed locally so that it could be incorporated into a monitoring script, so allowing a remote IP to gather the info was not a desirable solution, although rapidly looking like the only option. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Salvation came in the form of a program called cgi-fcgi which talks pure cgi-ese to the fpm socket. Or something like that. (apt install libfcgi-bin or yum install fcgi). Once installed, we can ask it for the information like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SCRIPT_NAME=\/status SCRIPT_FILENAME=\/status REQUEST_METHOD=GET cgi-fcgi -bind -connect \/var\/run\/php\/php-fpm-mysite.sock<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So, incorporating that into a script we can monitor our website's fpm usage. I guess this could also be used in telegraf, zabbix and other monitoring solutions. And you can have a different status URL for each site\/pool on the server. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ran into this one recently and the solution came out of left field, so I thought I'd throw it out to the internet at large. I've got a server which is running php-fpm and nginx. However it has several websites running on it, each of which has its own php-fpm\/pool.d\/ profile. We were having a &#8230; <a title=\"php-fpm monitoring for single domain\" class=\"read-more\" href=\"https:\/\/play.datalude.com\/blog\/2023\/06\/php-fpm-monitoring-for-single-domain\/\" aria-label=\"Read more about php-fpm monitoring for single domain\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[4,137],"tags":[134,85],"class_list":["post-709","post","type-post","status-publish","format-standard","hentry","category-linux","category-wordpress","tag-linux","tag-script"],"_links":{"self":[{"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/posts\/709","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/comments?post=709"}],"version-history":[{"count":0,"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/posts\/709\/revisions"}],"wp:attachment":[{"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/media?parent=709"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/categories?post=709"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/play.datalude.com\/blog\/wp-json\/wp\/v2\/tags?post=709"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}