Esta pagina se ve mejor con JavaScript habilitado

PMM2 PHP-FPM exporter

 ·  🎃 kr0m

Continuando con la instalación de php-fpm del artículo anterior vamos a configurar php-fpm-exporter, de este modo podremos monitorizar FPM, configurar alertas y visualizar gráficas de los datos obtenidos mediante Grafana.

En la web de Prometheus  encontramos el exporter de bakins , este se encuentra alojado en GitHub, por ello compilamos e instalamos git para bajarnos el código:

emerge -av dev-vcs/git

Este está programado en Go, así que compilamos e instalamos Go:

emerge -av dev-lang/go

Clonamos el repositorio y compilamos el binario:

git clone https://github.com/bakins/php-fpm-exporter
cd php-fpm-exporter
./script/build

Comprobamos que haya compilado correctamente:

./php-fpm-exporter.linux.amd64 --help

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 /

Compilamos e instalamos php con soporte para 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

Habilitamos el status de FPM:

vi /etc/php/fpm-php7.4/fpm.d/www.conf

[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

Reiniciamos el servicio:

/etc/init.d/php-fpm restart

El exporter puede consultar el status de FPM a través de un servidor web que nos reenvie al FPM o directamente al 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

Lo mas sencillo es que el exporter acceda directamente al FPM, bindearlo a la loopback y configurar Nginx o el servidor que vayamos a utilizar para que pida credenciales de acceso:

./php-fpm-exporter.linux.amd64 --addr 127.0.0.1:8080 --fastcgi unix:///run/php-fpm.socket

NOTA: Otra opción sería insertar reglas de firewall para permitir solo la ip de PMM pero ya no podríamos consultar las métricas directamente desde nuestro navegador, no al menos sin hacer algún tipo de túnel del estilo proxy socks.

Demonizamos el servicio:

vi /etc/local.d/php-fpm-exporter.start

nohup /root/php-fpm-exporter/php-fpm-exporter.linux.amd64 --addr 127.0.0.1:8080 --fastcgi unix:///run/php-fpm.socket &

Le asignamos los permisos necesarios:

chmod 700 /etc/local.d/php-fpm-exporter.start

Lo arrancamos:

/etc/local.d/php-fpm-exporter.start

Comprobamos que haya arrancado y que esté a la escucha:

netstat -nputa|grep LISTEN|grep 8080

tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      841/php-fpm-exporte 

Comprobamos que aparezcan las métricas consultándolas desde local:

curl http://localhost:8080/metrics|grep -v ‘#’

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

Compilamos e instalamos el servidor web, en mi caso Nginx:

emerge -av www-servers/nginx

Ahora configuraremos Nginx para que sirva las métricas al exterior pero requiriendo autenticación previa, whitelisteamos la ip del PMM para que no pida password desde esa dirección ip:

vi /etc/nginx/nginx.conf

...
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;
    }
}
...

Reiniciamos el servicio para aplicar la configuración:

/etc/init.d/nginx restart

Generamos el fichero de passwords:

emerge -av app-admin/apache-tools
htpasswd -c /etc/nginx/.htpasswd admin

La configuración de Prometheus quedaría así.

vi prometheusConf/prometheus.base.yml

scrape_configs:
- job_name: fpm-status
  scrape_interval: 1m
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  static_configs:
  - targets:
    - SERVER:8080

Aplicamos la configuración nueva reiniciando PMM:

docker stop pmm-server && docker start pmm-server

Accedemos desde el exterior con las credenciales:

curl -u admin:PASSWORD http://SERVER_IP:8080/metrics|grep -v ‘#’

En Prometheus ya podremos ver el target:

Las alertas de Prometheus serían estas, recordad que en PMM las alertas se configuran desde 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

Si paramos el FPM en el servidor veremos la siguiente alarma:

Si hemos seguido la guía sobre Alertmanager  veremos en Telegram alertas como esta:

Ahora cargamos la Dashboard de Grafana:
https://grafana.com/grafana/dashboards/3901


Pegamos la url del dashboard e importamos:


Y el resultado es el siguiente:

Si te ha gustado el artículo puedes invitarme a un RedBull aquí