Continuing with the installation of php-fpm from the previous article, we will configure php-fpm-exporter. This way, we can monitor FPM, configure alerts, and visualize graphs of the data obtained through Grafana.
On the
Prometheus
website, we find the exporter from
bakins
, which is hosted on GitHub. Therefore, we compile and install git to download the code:
It is programmed in Go, so we compile and install Go:
We clone the repository and compile the binary:
We check that it has compiled correctly:
usage: php-fpm-exporter.linux.amd64 [<flags>]
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--addr="127.0.0.1:8080" listen address for metrics handler
--endpoint="http://127.0.0.1:9000/status"
url for php-fpm status
--fastcgi=FASTCGI fastcgi url. If this is set, fastcgi will be used instead of HTTP
--web.telemetry-path="/metrics"
Path under which to expose metrics. Cannot be /
We compile and install php with support for FPM:
echo “dev-lang/php acl berkdb bzip2 cli ctype fileinfo filter flatfile gdbm iconv ipv6 json nls opcache phar posix readline session simplexml ssl tokenizer unicode xml zlib -apache2 -argon2 -bcmath -calendar -cdb -cgi -cjk -coverage -curl -debug -embed -enchant -exif -ffi -firebird fpm -ftp -gd -gmp -imap -inifile -intl -iodbc -kerberos -ldap -ldap-sasl -libedit -libressl -lmdb -mhash -mssql -mysql -mysqli -oci8-instant-client -odbc -pcntl -pdo -phpdbg -postgres -qdbm -selinux -session-mm -sharedmem -snmp -soap -sockets -sodium -spell -sqlite -systemd -sysvipc -test -threads -tidy -tokyocabinet -truetype -webp -xmlreader -xmlrpc -xmlwriter -xpm -xslt -zip” > /etc/portage/package.use/php
echo “app-eselect/eselect-php fpm” » /etc/portage/package.use/php
emerge -av dev-lang/php
Enable FPM status:
[www]
user = nobody
group = nobody
listen = /run/php-fpm.socket
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.status_path = /status
ping.path = /ping
ping.response = pong
Restart the service:
The exporter can query the FPM status through a web server that redirects us to FPM or directly to FPM:
--endpoint string url for php-fpm status (default "http://127.0.0.1:9000/status")
--fastcgi string fastcgi url. If this is set, fastcgi will be used instead of HTTP
The easiest way is for the exporter to access FPM directly, bind it to the loopback, and configure Nginx or the server we are going to use to request access credentials:
NOTE: Another option would be to insert firewall rules to allow only the PMM IP, but then we could no longer directly query the metrics from our browser, at least not without some kind of tunnel like a SOCKS proxy.
Daemonize the service:
nohup /root/php-fpm-exporter/php-fpm-exporter.linux.amd64 --addr 127.0.0.1:8080 --fastcgi unix:///run/php-fpm.socket &
Assign the necessary permissions:
Start it:
Check that it has started and is listening:
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 841/php-fpm-exporte
Check that the metrics appear by querying them locally:
phpfpm_accepted_connections_total 6
phpfpm_active_max_processes 1
phpfpm_listen_queue_connections 0
phpfpm_listen_queue_length_connections 0
phpfpm_listen_queue_max_connections 0
phpfpm_max_children_reached_total 0
phpfpm_processes_total{state="active"} 1
phpfpm_processes_total{state="idle"} 1
phpfpm_scrape_failures_total 0
phpfpm_slow_requests_total 0
phpfpm_up 1
Compile and install the web server, in my case Nginx:
Now we will configure Nginx to serve metrics to the outside but requiring prior authentication. We will whitelist the PMM IP so that it does not require a password from that IP address:
...
server {
listen SERVER_IP:8080;
server_name _;
location / {
satisfy any;
allow PMM_SERVER_IP/32;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
deny all;
proxy_pass http://localhost:8080;
}
}
...
Restart the service to apply the configuration:
Generate the password file:
htpasswd -c /etc/nginx/.htpasswd admin
The Prometheus configuration would be as follows:
scrape_configs:
- job_name: fpm-status
scrape_interval: 1m
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets:
- SERVER:8080
Apply the new configuration by restarting PMM:
Access from the outside with the credentials:
In Prometheus, we can now see the target:
The Prometheus alerts would be as follows. Remember that in PMM, alerts are configured from Grafana ( http://pmm.alfaexploit.com/graph/d/pmm-settings/) :
- name: fpmRules
rules:
- alert: fpmExporterDown
expr: up{job="fpm-status"} == 0
for: 5m
labels:
severity: critical
- alert: fpmDown
expr: phpfpm_up == 0
for: 5m
labels:
severity: critical
- alert: fpmMaxChildrenReached
expr: phpfpm_max_children_reached_total{job="fpm-status"} == 1
for: 5m
labels:
severity: critical
If we stop the FPM on the server, we will see the following alarm:
If we have followed the guide on
Alertmanager
, we will see alerts in Telegram like this:
Now we load the Grafana Dashboard:
https://grafana.com/grafana/dashboards/3901
Paste the dashboard URL and import it:
And the result is as follows: