# PHP-FPM by Zabbix agent ## Overview This template is developed to monitor the FastCGI Process Manager (PHP-FPM) by Zabbix agent that works without any external scripts. Most of the metrics are collected in one go, thanks to Zabbix bulk data collection. The template `PHP-FPM by Zabbix agent` - collects metrics by polling the PHP-FPM status-page locally with Zabbix agent. Note that this template doesn't support HTTPS and redirects (limitations of `web.page.get`). It also uses Zabbix agent to collect `php-fpm` Linux process statistics, such as CPU usage, memory usage, and whether the process is running or not. ## Requirements Zabbix version: 7.0 and higher. ## Tested versions This template has been tested on: - PHP 7 - PHP 8 ## Configuration > Zabbix should be configured according to the instructions in the [Templates out of the box](https://www.zabbix.com/documentation/7.0/manual/config/templates_out_of_the_box) section. ## Setup Note that depending on your OS distribution, the PHP-FPM executable/service name can vary. RHEL-like distributions usually name both process and service as `php-fpm`, while for Debian/Ubuntu based distributions it may include the version, for example: executable name - `php-fpm8.2`, systemd service name - `php8.2-fpm`. Adjust the following instructions accordingly if needed. 1. Open the PHP-FPM configuration file and enable the status page as shown. ``` pm.status_path = /status ping.path = /ping ``` 2. Validate the syntax to ensure it is correct before you reload the service. Replace the `` in the command if needed. ``` $ php-fpm -t ``` or ``` $ php-fpm -t ``` 3. Reload the `php-fpm` service to make the change active. Replace the `` in the command if needed. ``` $ systemctl reload php-fpm ``` or ``` $ systemctl reload php-fpm ``` 4. Next, edit the configuration of your web server. If you use Nginx, edit the configuration file of your Nginx server block (virtual host) and add the location block below it. ``` # Enable php-fpm status page location ~ ^/(status|ping)$ { ## disable access logging for request if you prefer access_log off; ## Only allow trusted IPs for security, deny everyone else # allow 127.0.0.1; # allow 1.2.3.4; # your IP here # deny all; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; include fastcgi_params; ## Now the port or socket of the php-fpm pool we want the status of fastcgi_pass 127.0.0.1:9000; # fastcgi_pass unix:/run/php-fpm/your_socket.sock; } ``` If you use Apache, edit the configuration file of the virtual host and add the following location blocks. ``` Require ip 127.0.0.1 # Require ip 1.2.3.4 # Your IP here # Adjust the path to the socket if needed ProxyPass "unix:/run/php-fpm/www.sock|fcgi://localhost/status" Require ip 127.0.0.1 # Require ip 1.2.3.4 # Your IP here # Adjust the path to the socket if needed ProxyPass "unix:/run/php-fpm/www.sock|fcgi://localhost/ping" ``` 5. Check the web server configuration syntax. The command may vary depending on the OS distribution and web server. ``` $ nginx -t ``` or ``` $ httpd -t ``` or ``` $ apachectl configtest ``` 6. Reload the web server configuration. The command may vary depending on the OS distribution and web server. ``` $ systemctl reload nginx ``` or ``` $ systemctl reload httpd ``` or ``` $ systemctl reload apache2 ``` 7. Verify that the pages are available with these commands. ``` curl -L 127.0.0.1/status curl -L 127.0.0.1/ping ``` Depending on your OS distribution, the PHP-FPM process name may vary as well. Please check the actual name in the line "Name" from /proc/\/status file (https://www.zabbix.com/documentation/7.0/manual/appendix/items/proc_mem_num_notes) and change the {$PHP_FPM.PROCESS.NAME.PARAMETER} macro if needed. If you use another location of the status/ping pages, don't forget to change the `{$PHP_FPM.STATUS.PAGE}/{$PHP_FPM.PING.PAGE}` macro. If you use another web server port for the location of the PHP-FPM status/ping pages, don't forget to change the macro `{$PHP_FPM.PORT}`. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$PHP_FPM.PORT}|

The port of the PHP-FPM status host or container.

|`80`| |{$PHP_FPM.HOST}|

The hostname or IP address of the PHP-FPM status for a host or container.

|`localhost`| |{$PHP_FPM.STATUS.PAGE}|

The path of the PHP-FPM status page.

|`status`| |{$PHP_FPM.PING.PAGE}|

The path of the PHP-FPM ping page.

|`ping`| |{$PHP_FPM.PING.REPLY}|

The expected reply to the ping.

|`pong`| |{$PHP_FPM.QUEUE.WARN.MAX}|

The maximum percent of the PHP-FPM queue usage for a trigger expression.

|`80`| |{$PHP_FPM.PROCESS_NAME}|

The process name filter for the PHP-FPM process discovery. May vary depending on your OS distribution.

|`php-fpm`| |{$PHP_FPM.PROCESS.NAME.PARAMETER}|

The process name of the PHP-FPM used in the item key `proc.get`. It could be specified if the correct process name is known.

|| ### Items |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |PHP-FPM: Get processes summary|

The aggregated data of summary metrics for all processes.

|Zabbix agent|proc.get[{$PHP_FPM.PROCESS.NAME.PARAMETER},,,summary]| |PHP-FPM: php-fpm_ping||Zabbix agent|web.page.get["{$PHP_FPM.HOST}","{$PHP_FPM.PING.PAGE}","{$PHP_FPM.PORT}"]| |PHP-FPM: Get status page||Zabbix agent|web.page.get["{$PHP_FPM.HOST}","{$PHP_FPM.STATUS.PAGE}?json","{$PHP_FPM.PORT}"]

**Preprocessing**

  • Regular expression: `^[.\s\S]*({.+}) \1`

| |PHP-FPM: Ping||Dependent item|php-fpm.ping

**Preprocessing**

  • Regular expression: `{$PHP_FPM.PING.REPLY}($|\r?\n) 1`

    ⛔️Custom on fail: Set value to: `0`

| |PHP-FPM: Processes, active|

The total number of active processes.

|Dependent item|php-fpm.processes_active

**Preprocessing**

  • JSON Path: `$.['active processes']`

| |PHP-FPM: Version|

The current version of the PHP. You can get it from the HTTP-Header "X-Powered-By"; it may not work if you have changed the default HTTP-headers.

|Dependent item|php-fpm.version

**Preprocessing**

  • Regular expression: `^[.\s\S]*X-Powered-By: PHP/([.\d]{1,}) \1`

    ⛔️Custom on fail: Discard value

  • Discard unchanged with heartbeat: `3h`

| |PHP-FPM: Pool name|

The name of the current pool.

|Dependent item|php-fpm.name

**Preprocessing**

  • JSON Path: `$.pool`

  • Discard unchanged with heartbeat: `3h`

| |PHP-FPM: Uptime|

It indicates how long has this pool been running.

|Dependent item|php-fpm.uptime

**Preprocessing**

  • JSON Path: `$.['start since']`

| |PHP-FPM: Start time|

The time when this pool was started.

|Dependent item|php-fpm.start_time

**Preprocessing**

  • JSON Path: `$.['start time']`

| |PHP-FPM: Processes, total|

The total number of server processes currently running.

|Dependent item|php-fpm.processes_total

**Preprocessing**

  • JSON Path: `$.['total processes']`

| |PHP-FPM: Processes, idle|

The total number of idle processes.

|Dependent item|php-fpm.processes_idle

**Preprocessing**

  • JSON Path: `$.['idle processes']`

| |PHP-FPM: Queue usage|

The utilization of the queue.

|Calculated|php-fpm.listen_queue_usage| |PHP-FPM: Process manager|

The method used by the process manager to control the number of child processes for this pool.

|Dependent item|php-fpm.process_manager

**Preprocessing**

  • JSON Path: `$.['process manager']`

  • Discard unchanged with heartbeat: `3h`

| |PHP-FPM: Processes, max active|

The highest value of "active processes" since the PHP-FPM server was started.

|Dependent item|php-fpm.processes_max_active

**Preprocessing**

  • JSON Path: `$.['max active processes']`

| |PHP-FPM: Accepted connections per second|

The number of accepted requests per second.

|Dependent item|php-fpm.conn_accepted.rate

**Preprocessing**

  • JSON Path: `$.['accepted conn']`

  • Change per second
| |PHP-FPM: Slow requests|

The number of requests that has exceeded your `request_slowlog_timeout` value.

|Dependent item|php-fpm.slow_requests

**Preprocessing**

  • JSON Path: `$.['slow requests']`

  • Simple change
| |PHP-FPM: Listen queue|

The current number of connections that have been initiated but not yet accepted.

|Dependent item|php-fpm.listen_queue

**Preprocessing**

  • JSON Path: `$.['listen queue']`

| |PHP-FPM: Listen queue, max|

The maximum number of requests in the queue of pending connections since this FPM pool was started.

|Dependent item|php-fpm.listen_queue_max

**Preprocessing**

  • JSON Path: `$.['max listen queue']`

| |PHP-FPM: Listen queue, len|

The size of the socket queue of pending connections.

|Dependent item|php-fpm.listen_queue_len

**Preprocessing**

  • JSON Path: `$.['listen queue len']`

| |PHP-FPM: Max children reached|

The number of times that `pm.max_children` has been reached since the PHP-FPM pool was started.

|Dependent item|php-fpm.max_children

**Preprocessing**

  • JSON Path: `$.['max children reached']`

  • Simple change
| ### Triggers |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----------|--------|--------------------------------| |PHP-FPM: Version has changed|

The PHP-FPM version has changed. Acknowledge to close the problem manually.

|`last(/PHP-FPM by Zabbix agent/php-fpm.version,#1)<>last(/PHP-FPM by Zabbix agent/php-fpm.version,#2) and length(last(/PHP-FPM by Zabbix agent/php-fpm.version))>0`|Info|**Manual close**: Yes| |PHP-FPM: Pool has been restarted|

Uptime is less than 10 minutes.

|`last(/PHP-FPM by Zabbix agent/php-fpm.uptime)<10m`|Info|**Manual close**: Yes| |PHP-FPM: Queue utilization is high|

The queue for this pool has reached `{$PHP_FPM.QUEUE.WARN.MAX}%` of its maximum capacity.
Items in the queue represent the current number of connections that have been initiated on this pool but not yet accepted.

|`min(/PHP-FPM by Zabbix agent/php-fpm.listen_queue_usage,15m) > {$PHP_FPM.QUEUE.WARN.MAX}`|Warning|| |PHP-FPM: Manager changed|

The PHP-FPM manager has changed. Acknowledge to close the problem manually.

|`last(/PHP-FPM by Zabbix agent/php-fpm.process_manager,#1)<>last(/PHP-FPM by Zabbix agent/php-fpm.process_manager,#2)`|Info|**Manual close**: Yes| |PHP-FPM: Detected slow requests|

The PHP-FPM has detected a slow request.
The slow request means that it took more time to execute than expected (defined in the configuration of your pool).

|`min(/PHP-FPM by Zabbix agent/php-fpm.slow_requests,#3)>0`|Warning|| ### LLD rule PHP-FPM process discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |PHP-FPM process discovery|

The discovery of the PHP-FPM summary processes.

|Dependent item|php-fpm.proc.discovery| ### Item prototypes for PHP-FPM process discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |PHP-FPM: Get process data|

The summary metrics aggregated by a process `{#PHP_FPM.NAME}`.

|Dependent item|php-fpm.proc.get[{#PHP_FPM.NAME}]

**Preprocessing**

  • JSON Path: `$.[?(@["name"]=="{#PHP_FPM.NAME}")].first()`

    ⛔️Custom on fail: Set value to: `Failed to retrieve process {#PHP_FPM.NAME} data`

| |PHP-FPM: Memory usage (rss)|

The summary of resident set size memory used by a process `{#PHP_FPM.NAME}` expressed in bytes.

|Dependent item|php-fpm.proc.rss[{#PHP_FPM.NAME}]

**Preprocessing**

  • JSON Path: `$.rss`

    ⛔️Custom on fail: Discard value

| |PHP-FPM: Memory usage (vsize)|

The summary of virtual memory used by a process `{#PHP_FPM.NAME}` expressed in bytes.

|Dependent item|php-fpm.proc.vmem[{#PHP_FPM.NAME}]

**Preprocessing**

  • JSON Path: `$.vsize`

    ⛔️Custom on fail: Discard value

| |PHP-FPM: Memory usage, %|

The percentage of real memory used by a process `{#PHP_FPM.NAME}`.

|Dependent item|php-fpm.proc.pmem[{#PHP_FPM.NAME}]

**Preprocessing**

  • JSON Path: `$.pmem`

    ⛔️Custom on fail: Discard value

| |PHP-FPM: Number of running processes|

The number of running processes `{#PHP_FPM.NAME}`.

|Dependent item|php-fpm.proc.num[{#PHP_FPM.NAME}]

**Preprocessing**

  • JSON Path: `$.processes`

    ⛔️Custom on fail: Set value to: `0`

  • Discard unchanged with heartbeat: `1h`

| |PHP-FPM: CPU utilization|

The percentage of the CPU utilization by a process `{#PHP_FPM.NAME}`.

|Zabbix agent|proc.cpu.util[{#PHP_FPM.NAME}]| ### Trigger prototypes for PHP-FPM process discovery |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----------|--------|--------------------------------| |PHP-FPM: Process is not running||`last(/PHP-FPM by Zabbix agent/php-fpm.proc.num[{#PHP_FPM.NAME}])=0`|High|| |PHP-FPM: Failed to fetch info data|

Zabbix has not received any data for items for the last 30 minutes.

|`nodata(/PHP-FPM by Zabbix agent/php-fpm.uptime,30m)=1 and last(/PHP-FPM by Zabbix agent/php-fpm.proc.num[{#PHP_FPM.NAME}])>0`|Info|**Manual close**: Yes| |PHP-FPM: Service is down||`(last(/PHP-FPM by Zabbix agent/php-fpm.ping)=0 or nodata(/PHP-FPM by Zabbix agent/php-fpm.ping,3m)=1) and last(/PHP-FPM by Zabbix agent/php-fpm.proc.num[{#PHP_FPM.NAME}])>0`|High|**Manual close**: Yes| ## Feedback Please report any issues with the template at [`https://support.zabbix.com`](https://support.zabbix.com) You can also provide feedback, discuss the template, or ask for help at [`ZABBIX forums`](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback)