mirror of
https://github.com/rvalitov/zabbix-php-fpm.git
synced 2023-11-05 03:30:27 +01:00
488 lines
18 KiB
Markdown
488 lines
18 KiB
Markdown
# PHP-FPM Zabbix Template with Auto Discovery and Multiple Pools
|
||
|
||
![Zabbix version logo](https://img.shields.io/badge/Zabbix-v4.2+-green.svg?style=flat) ![PHP](https://img.shields.io/badge/PHP-5.6.x+-blue.svg?style=flat) ![PHP7](https://img.shields.io/badge/PHP7-supported-green.svg?style=flat) ![LLD](https://img.shields.io/badge/LLD-yes-green.svg?style=flat) ![ISPConfig](https://img.shields.io/badge/ISPConfig-supported-green.svg?style=flat)
|
||
|
||
![Banner](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/repository-open-graph-template.png)
|
||
|
||
## Main features
|
||
|
||
- Provides auto discovery of PHP-FPM pools (LLD)
|
||
- Detects pools that [listen](https://www.php.net/manual/en/install.fpm.configuration.php#listen) via socket and via TCP
|
||
- Supported types of PHP [process manager](https://www.php.net/manual/en/install.fpm.configuration.php#pm):
|
||
- [x] dynamic
|
||
- [x] static
|
||
- [ ] ondemand - has some problems, because of its working logic, see issue [#11](https://github.com/rvalitov/zabbix-php-fpm/issues/11)
|
||
- Supports multiple PHP versions, i.e. you can use PHP 7.2 and PHP 7.3 on the same server and we will detect them all
|
||
- Easy configuration
|
||
- Supports [ISPConfig](https://www.ispconfig.org/)
|
||
- Script is in pure `bash`: no need to install `Perl`, `Go` or other languages.
|
||
|
||
## Provided Items
|
||
We capture only useful data from host and PHP-FPM status page:
|
||
|
||
- Number of CPUs
|
||
- For each pool:
|
||
|
||
- **Accepted Connections Per Second** - the number of requests accepted by the pool
|
||
- **Active Processes** - the number of active processes
|
||
- **Idle Processes** - the number of idle processes
|
||
- **Max Children Reached** – the number of times, the process limit has been reached, when pm tries to start more children (works only for pm `dynamic` and `ondemand`)
|
||
- **CPU Utilization** - CPU load for all processes of the pool in %
|
||
- **CPU Average Utilization** - CPU load for all processes of the pool in % normalized by number of CPUs
|
||
- **Listen Queue** - the number of requests in the queue of pending connections
|
||
- **Max Listen Queue** - the maximum number of requests in the queue of pending connections since FPM has started
|
||
- **Listen Queue Length** - the size of the socket queue of pending connections
|
||
- **Queue Utilization** - queue usage in %
|
||
- **Memory Used** - how much RAM used by the pool in bytes
|
||
- **Memory Utilization** - how much RAM used by the pool in %
|
||
- **Process Manager** - `dynamic`, `ondemand` or `static`, see [PHP manual](https://www.php.net/manual/en/install.fpm.configuration.php#pm).
|
||
- **Slow Requests** - the number of requests that exceeded your [`request_slowlog_timeout`](https://www.php.net/manual/en/install.fpm.configuration.php#request-slowlog-timeout) value.
|
||
- **Start Since** - number of seconds since FPM has started
|
||
- **Start Time** - the date and time FPM has started
|
||
|
||
History storage period is from 1 hour to 1 day (depends on specific item), trend storage period is 365 days that's optimal for environments with multiple websites.
|
||
Data is captured every minute. These timings can be adjusted in template or per host if needed.
|
||
|
||
## Provided Triggers
|
||
|
||
- Too many connections on pool
|
||
- PHP-FPM uses too much memory
|
||
- PHP-FPM manager changed
|
||
- PHP-FPM uses queue
|
||
- PHP-FPM detected slow request
|
||
|
||
## Provided Graphs
|
||
#### Connections
|
||
![Zabbix PHP-FPM connections graph](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/demo-connections.png)
|
||
|
||
Displays the following data:
|
||
|
||
- Accepted connections per second
|
||
- CPU average utilization in %
|
||
- Memory utilization in %
|
||
- Queue utilization in %
|
||
|
||
#### CPU
|
||
![Zabbix PHP-FPM CPU utilization graph](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/demo-cpu.png)
|
||
|
||
Displays the following data:
|
||
|
||
- CPU average utilization in %
|
||
- Accepted connections per second
|
||
|
||
#### Memory
|
||
![Zabbix PHP-FPM RAM utilization graph](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/demo-memory.png)
|
||
|
||
Displays the following data:
|
||
|
||
- Memory used in bytes
|
||
- CPU average utilization in %
|
||
- Memory utilization in %
|
||
- Queue utilization in %
|
||
|
||
#### Process
|
||
![Zabbix PHP-FPM CPU utilization graph](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/demo-process.png)
|
||
|
||
Displays the following data:
|
||
|
||
- Active processes
|
||
- Idle processes
|
||
- Accepted connections per second
|
||
|
||
#### Queue
|
||
Displays the following data:
|
||
|
||
- Listen Queue
|
||
|
||
#### Max Children Reached
|
||
Displays the following data:
|
||
|
||
- Max Children Reached
|
||
- Accepted connections per second
|
||
|
||
## Provided Screens
|
||
Screens are based on the graphs above:
|
||
|
||
- Connections
|
||
- Processes
|
||
- CPU utilization
|
||
- Memory utilization
|
||
- Queue
|
||
- Max children riched
|
||
|
||
![Zabbix screens example](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/zabbix-screens.jpg)
|
||
|
||
## Installation
|
||
|
||
### 1. On Zabbix agents
|
||
Perform the following operations on all servers with Zabbix and PHP-FPM from which you want to capture the data.
|
||
|
||
#### 1.1. Install Prerequisites
|
||
Install required packages.
|
||
|
||
##### For `apt-get` based environments (Debian, Ubuntu, etc.):
|
||
|
||
```bash
|
||
apt-get update
|
||
apt-get -y install grep gawk lsof jq libfcgi0ldbl
|
||
```
|
||
Additionally, for Debian Jessie 8.x and earlier (or for equivalent Ubuntu version):
|
||
|
||
```bash
|
||
apt-get -y install libfcgi0ldbl
|
||
```
|
||
|
||
Additionally, for Debian Stretch 9.x and later (or for equivalent Ubuntu version):
|
||
|
||
```bash
|
||
apt-get -y install libfcgi-bin
|
||
```
|
||
|
||
##### For `yum` based environments (CentOS):
|
||
|
||
```bash
|
||
yum check-update
|
||
yum install grep gawk lsof jq fcgi
|
||
```
|
||
|
||
#### 1.2. Install Zabbix PHP-FPM template
|
||
Download the latest version of the template:
|
||
|
||
```console
|
||
wget https://github.com/rvalitov/zabbix-php-fpm/archive/master.zip -O /tmp/zabbix-php-fpm.zip
|
||
```
|
||
|
||
Unzip the archive:
|
||
|
||
```console
|
||
unzip /tmp/zabbix-php-fpm.zip -d /tmp
|
||
```
|
||
|
||
Copy the required files to the Zabbix agent configuration directory:
|
||
|
||
```console
|
||
cp /tmp/zabbix-php-fpm-master/zabbix/userparameter_php_fpm.conf /etc/zabbix/zabbix_agentd.d/
|
||
cp /tmp/zabbix-php-fpm-master/zabbix/zabbix_php_fpm_discovery.sh /etc/zabbix/
|
||
cp /tmp/zabbix-php-fpm-master/zabbix/zabbix_php_fpm_status.sh /etc/zabbix/
|
||
```
|
||
|
||
Configure access rights:
|
||
|
||
```console
|
||
chmod +x /etc/zabbix/zabbix_php_fpm_discovery.sh
|
||
chmod +x /etc/zabbix/zabbix_php_fpm_status.sh
|
||
```
|
||
|
||
#### 1.3. Root privileges
|
||
Automatic detection of pools requires root privileges. You can achieve it using one of the methods below.
|
||
|
||
##### 1.3.1 Root privileges for Zabbix Agent
|
||
This method sets root privileges for Zabbix Agent, i.e. the Zabbix Agent will run under `root` user, as a result all user scripts will also have the root access rights.
|
||
|
||
Edit Zabbix agent configuration file `/etc/zabbix/zabbix_agentd.conf`, find `AllowRoot` option and enable it:
|
||
|
||
```
|
||
### Option: AllowRoot
|
||
# Allow the agent to run as 'root'. If disabled and the agent is started by 'root', the agent
|
||
# will try to switch to the user specified by the User configuration option instead.
|
||
# Has no effect if started under a regular user.
|
||
# 0 - do not allow
|
||
# 1 - allow
|
||
#
|
||
# Mandatory: no
|
||
# Default:
|
||
# AllowRoot=0
|
||
AllowRoot=1
|
||
```
|
||
|
||
In the same file find option `User` and set it to `root`:
|
||
|
||
|
||
```
|
||
### Option: User
|
||
# Drop privileges to a specific, existing user on the system.
|
||
# Only has effect if run as 'root' and AllowRoot is disabled.
|
||
#
|
||
# Mandatory: no
|
||
# Default:
|
||
# User=zabbix
|
||
User=root
|
||
```
|
||
|
||
Restart the Zabbix agent service, for example:
|
||
|
||
```console
|
||
systemctl restart zabbix-agent
|
||
```
|
||
|
||
Check that the Zabbix agent runs under `root` user:
|
||
|
||
```console
|
||
user@server:~$ ps aux | grep "zabbix_agent"
|
||
user 3761 0.0 0.0 8132 928 pts/0 S+ 18:32 0:00 grep zabbix_agent
|
||
root 6026 0.0 0.0 86968 3472 ? S Dec14 0:00 /usr/sbin/zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf
|
||
root 6027 0.7 0.0 87056 5044 ? S Dec14 76:00 /usr/sbin/zabbix_agentd: collector [idle 1 sec]
|
||
root 6028 0.0 0.0 161160 11092 ? S Dec14 7:41 /usr/sbin/zabbix_agentd: listener #1 [waiting for connection]
|
||
root 6029 0.0 0.0 161244 11180 ? S Dec14 7:43 /usr/sbin/zabbix_agentd: listener #2 [waiting for connection]
|
||
root 6030 0.0 0.0 161136 11072 ? S Dec14 7:43 /usr/sbin/zabbix_agentd: listener #3 [waiting for connection]
|
||
```
|
||
|
||
You should see `root` above. Otherwise, the Zabbix agent works without `root` privileges and will not be able to discover the PHP pools.
|
||
|
||
Since some updates of Zabbix agent and in some OS the above changes are not enough and the following actions must be performed (as desribed in Zabbix manual for versions [4.0](https://www.zabbix.com/documentation/4.0/manual/appendix/install/run_agent_as_root), [4.4](https://www.zabbix.com/documentation/4.4/manual/appendix/install/run_agent_as_root)).
|
||
|
||
Create a directory for configuration file:
|
||
|
||
```console
|
||
mkdir /etc/systemd/system/zabbix-agent.service.d
|
||
|
||
```
|
||
|
||
Create file `/etc/systemd/system/zabbix-agent.service.d/override.conf` with the following content:
|
||
|
||
```console
|
||
[Service]
|
||
User=root
|
||
Group=root
|
||
```
|
||
|
||
Reload daemons and restart `zabbix-agent` service:
|
||
|
||
```console
|
||
systemctl daemon-reload
|
||
systemctl restart zabbix-agent
|
||
```
|
||
|
||
Check again that the Zabbix agent runs as `root` now.
|
||
|
||
##### 1.3.2 Grant privileges to the PHP-FPM auto discovery script only
|
||
If you don't want to run Zabbix Agent as root, then you can configure the privileges only to our script. In this case you need to have `sudo` installed:
|
||
|
||
```console
|
||
apt-get install sudo
|
||
```
|
||
|
||
Now edit the `/etc/sudoers` file by running command:
|
||
|
||
```console
|
||
visudo
|
||
```
|
||
|
||
Add the following line to this file:
|
||
|
||
```
|
||
zabbix ALL = NOPASSWD: /etc/zabbix/zabbix_php_fpm_discovery.sh
|
||
```
|
||
|
||
Here we specified `zabbix` as the user under which the Zabbix Agent is run. This is the default name, but if you have a custom installation with different name, then please, change it accordingly. Save and exit the editor. Your modifications will be applied.
|
||
|
||
Now edit the file `userparameter_php_fpm.conf`. Find the line:
|
||
|
||
```
|
||
UserParameter=php-fpm.discover,/etc/zabbix/zabbix_php_fpm_discovery.sh
|
||
```
|
||
|
||
Add `sudo` there, so the line should be:
|
||
|
||
```
|
||
UserParameter=php-fpm.discover,sudo /etc/zabbix/zabbix_php_fpm_discovery.sh
|
||
```
|
||
|
||
That's all.
|
||
|
||
#### 1.4. Linux Tuning (optional)
|
||
Usually PHP-FPM [backlog option](https://www.php.net/manual/en/install.fpm.configuration.php#listen-backlog) is limited by Linux kernel settings and equals to `128` by default.
|
||
In most cases you want to increase this value (latest PHP use `511` by default).
|
||
The main option that limits the PHP-FPM backlog option is `net.core.somaxconn`.
|
||
See the current setting, usually it's `128`:
|
||
|
||
```console
|
||
cat /proc/sys/net/core/somaxconn
|
||
128
|
||
```
|
||
|
||
Let's increase it to 1024:
|
||
|
||
```console
|
||
echo "net.core.somaxconn=1024" >> /etc/sysctl.conf
|
||
```
|
||
|
||
Now we can cause the settings to be loaded by running:
|
||
|
||
```console
|
||
sysctl -p
|
||
```
|
||
|
||
#### 1.5. Adjust ISPConfig
|
||
This step is required only if you use [ISPConfig](https://www.ispconfig.org/).
|
||
ISPConfig does not enable PHP-FPM status page by default.
|
||
We will enable it by adding a custom PHP-FPM configuration template.
|
||
This file is an original configuration file from [ISPConfig v.3.1.14p2](https://www.ispconfig.org/blog/ispconfig-3-1-14p2-released-important-security-bugfix/), it only enables the status page by adding the following line:
|
||
|
||
```
|
||
pm.status_path = /php-fpm-status
|
||
```
|
||
Copy the configuration file into ISPConfig custom configuration directory:
|
||
|
||
```console
|
||
cp /tmp/zabbix-php-fpm/ispconfig/php_fpm_pool.conf.master /usr/local/ispconfig/server/conf-custom/
|
||
```
|
||
|
||
Set correct access rights:
|
||
|
||
```console
|
||
chmod +x /usr/local/ispconfig/server/conf-custom/php_fpm_pool.conf.master
|
||
```
|
||
|
||
Now resync the websites using ISPConfig control panel: go to `"Tools"->"Sync Tools"->"Resync"`.
|
||
Check "Websites" only and click "Start":
|
||
|
||
![ISPConfig resync interface](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/ispconfig-resync.jpg)
|
||
|
||
### 1.6 Adjust PHP-FPM pools configuration
|
||
This step is required if you don't use ISPConfig.
|
||
In this case you need to enable the PHP-FPM status page for all of your pools manually.
|
||
Each pool must have the same status path, recommended value is `/php-fpm-status`.
|
||
Please, edit all the pools configuration files (for example for PHP 7.3 they are located in directory `/etc/php/7.3/fpm/pool.d`) by adding the following line:
|
||
|
||
```
|
||
pm.status_path = /php-fpm-status
|
||
```
|
||
|
||
You can set another path here if needed. Finally, restart the PHP-FPM, for example:
|
||
|
||
```console
|
||
service php7.3-fpm restart
|
||
```
|
||
|
||
#### 1.7. Clean up
|
||
Delete temporary files:
|
||
|
||
```console
|
||
rm /tmp/zabbix-php-fpm.zip
|
||
rm -rf /tmp/zabbix-php-fpm-master/
|
||
```
|
||
|
||
### 2. On Zabbix Server
|
||
#### 2.1. Import Zabbix PHP-FPM template
|
||
In Zabbix frontend go to `"Configuration"->"Templates"->"Import"`:
|
||
![Zabbix template import interface](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/zabbix-import.jpg)
|
||
|
||
Upload file `/zabbix/zabbix_php_fpm_template.xml` from the [archive](https://github.com/rvalitov/zabbix-php-fpm/archive/master.zip).
|
||
|
||
#### 2.2. Add the template to your hosts
|
||
Add template "Template App PHP-FPM" to the desired hosts.
|
||
If you use a custom status path, then configure it in the macros section of the host by adding value:
|
||
|
||
```
|
||
{$PHP_FPM_STATUS_URL}=your status path
|
||
```
|
||
|
||
The setup is finished, just wait a couple of minutes till Zabbix discovers all your pools and captures the data.
|
||
|
||
# Testing and Troubleshooting
|
||
## Check auto discovery
|
||
First test that auto discovery of PHP-FPM pools works on your machine. Run the following command:
|
||
|
||
```console
|
||
root@server:/etc/zabbix#bash /etc/zabbix/zabbix_php_fpm_discovery.sh
|
||
```
|
||
**Important:** please make sure that you use `bash` in the command above, not `sh` or other alternatives, otherwise you may get a script syntax error message.
|
||
|
||
The output should be a valid JSON with a list of pools and their sockets, something like below (you may want to use [online JSON tool](https://jsonformatter.curiousconcept.com/) for pretty formatting of the response):
|
||
|
||
```json
|
||
{
|
||
"data":[
|
||
{
|
||
"{#POOLNAME}":"web1",
|
||
"{#POOLSOCKET}":"/var/lib/php7.3-fpm/web1.sock"
|
||
},
|
||
{
|
||
"{#POOLNAME}":"web4",
|
||
"{#POOLSOCKET}":"/var/lib/php7.3-fpm/web4.sock"
|
||
},
|
||
{
|
||
"{#POOLNAME}":"www",
|
||
"{#POOLSOCKET}":"127.0.0.1:9000"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
For further investigation you can run the script above with `debug` option to get more details, example:
|
||
```console
|
||
root@server:/etc/zabbix#bash /etc/zabbix/zabbix_php_fpm_discovery.sh debug
|
||
Debug mode enabled
|
||
Success: found socket /var/lib/php7.3-fpm/web1.sock for pool web1, raw process info: php-fpm7. 5094 web1 11u unix 0x00000000dd9ea858 0t0 104495372 /var/lib/php7.3-fpm/web1.sock type=STREAM
|
||
Success: found socket /var/lib/php7.3-fpm/web4.sock for pool web4, raw process info: php-fpm7. 5096 web4 11u unix 0x00000000562748dd 0t0 104495374 /var/lib/php7.3-fpm/web4.sock type=STREAM
|
||
Success: found socket /run/php/php7.3-fpm.sock for pool www, raw process info: php-fpm7. 5098 www-data 11u unix 0x00000000ef5ef2fb 0t0 104495376 /run/php/php7.3-fpm.sock type=STREAM
|
||
Resulting JSON data for Zabbix:
|
||
{"data":[{"{#POOLNAME}":"web1","{#POOLSOCKET}":"/var/lib/php7.3-fpm/web1.sock"},{"{#POOLNAME}":"web4","{#POOLSOCKET}":"/var/lib/php7.3-fpm/web4.sock"},{"{#POOLNAME}":"www","{#POOLSOCKET}":"/run/php/php7.3-fpm.sock"}]}
|
||
```
|
||
|
||
Any warning or error messages will be displayed here.
|
||
|
||
**Note:** having a warning messages does not necessarily mean that you have a error here, because different OS may provide data about processes differently. So, if you don't see any error messages here, then the script works fine.
|
||
|
||
The script can show you the list of utilities that are missing on your system and must be installed. We require the following utilities to be installed:
|
||
|
||
- `awk`
|
||
- `ps`
|
||
- `grep`
|
||
- `sort`
|
||
- `head`
|
||
- `lsof`
|
||
- `jq`
|
||
|
||
If some pools are missing, then you can manually check that they do really exist and are running, for example, using command:
|
||
|
||
```console
|
||
ps aux | grep "php-fpm"
|
||
```
|
||
|
||
In the list you should see your pool. If it's not there, then it means it's not running (not functional).
|
||
|
||
## How to troubleshoot template import failure
|
||
To view the import errors, please click the "Details" section in the Zabbix GUI. It should be on the same import page near the error message:
|
||
|
||
![Zabbix template import error details](https://github.com/rvalitov/zabbix-php-fpm/raw/master/media/zabbix-import-error.jpg)
|
||
|
||
Then check the Zabbix server log, for Debian/Ubuntu it's located at `/var/log/zabbix/zabbix_server.log`.
|
||
|
||
## Test with `zabbix_get`
|
||
Please, use the [`zabbix_get`](https://www.zabbix.com/documentation/4.4/manual/concepts/get) utility from your Zabbix Server to test that you can get the data from the Zabbix Agent (host).
|
||
Please, install this utility first, because usually it's not installed automatically:
|
||
|
||
```console
|
||
apt-get install zabbix-get
|
||
```
|
||
|
||
Example how to use the utility:
|
||
|
||
```console
|
||
zabbix_get -s 127.0.0.1 -p 10050 -k php-fpm.discover
|
||
zabbix_get -s 127.0.0.1 -p 10050 -k php-fpm.discover.status[POOL_URL,POOL_PATH]
|
||
```
|
||
In the above example we use the following values:
|
||
|
||
- `127.0.0.1` is the IP address of the host where the Zabbix Agent is installed and where the PHP-FPM is running
|
||
- `10050` is the port of the Zabbix Agent
|
||
- `POOL_URL` is the socket of the pool or IP and port combination, example: `/var/lib/php7.3-fpm/web1.sock` or `127.0.0.1:9000`
|
||
- `POOL_PATH` is the status path of PHP-FPM that you set in [`pm.status_path`](https://github.com/rvalitov/zabbix-php-fpm#16-adjust-php-fpm-pools-configuration), the default value is `/php-fpm-status`.
|
||
|
||
The commands above should return valid JSON data. If any error happens then it will be displayed.
|
||
Most common problems of testing the `php-fpm.discover` key:
|
||
|
||
- The resulting JSON data is empty, but the discovery script started manually works. Then it's a problem of insufficient privileges of Zabbix agent. Please, check again section "Root privileges" of this document.
|
||
- Error `ZBX_NOTSUPPORTED: Unsupported item key`. It means the `userparameter_php_fpm.conf` file is ignored by the Zabbix agent. Please, make sure that you copied this file to correct location and you have restarted the Zabbix agent.
|
||
|
||
# Compatibility
|
||
Tested with:
|
||
- PHP 7.3
|
||
- Zabbix 4.2.5
|
||
- ISPConfig v.3.1.14p2
|
||
|
||
Should work with PHP 5.6.x and later, Zabbix 4.2.x and later. Currently the template does not work with Zabbix 4.0.x, see [issue](https://github.com/rvalitov/zabbix-php-fpm/issues/5).
|
||
Not tested with other versions of Zabbix: if it works, please let me know.
|