mirror of
https://github.com/rvalitov/zabbix-php-fpm.git
synced 2023-11-05 03:30:27 +01:00
## Fix (all problems specified in issue #12) - **More robust method to discover sockets** (when PHP pool uses sockets). Script performs automatic checks of socket files (the file exists and is really a socket). - **More robust method to discover host and port** (when PHP pool uses TCP connection). - **Support of pools when PHP daemon listens on any network interface**. This mode is activated when in PHP pool configuration the `listen` command specifies only a port, without a host IP, for example: ``` listen = 9000 ``` - **Correct discovery of pools in some cases.** The script performs analysis of all processes that belong to the pool. Previously, we checked only the first process, as a result if a pool somehow had multiple processes (for example Memcached, Redis, PostgreSQL) then discovery could capture wrong data. Now this problem is fixed. - **Improved detection of pools**. We use better expressions in `grep` now. Previously special characters in pool names could lead to script failures. Besides such approach is a more robust method to fix #10. ## New functionality - **Debug mode** of the discovery script helps to investigate problems that may happen
This commit is contained in:
parent
805ef87655
commit
2210d3bbd5
49
README.md
49
README.md
@ -157,11 +157,11 @@ chmod +x /etc/zabbix/zabbix_php_fpm_discovery.sh
|
||||
chmod +x /etc/zabbix/zabbix_php_fpm_status.sh
|
||||
```
|
||||
|
||||
#### 1.3. Root previliges
|
||||
Automatic detection of pools requires root previliges. You can achieve it using one of the methods below.
|
||||
#### 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 previliges for Zabbix Agent
|
||||
This method sets root previliges 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.
|
||||
##### 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:
|
||||
|
||||
@ -179,8 +179,8 @@ Edit Zabbix agent configuration file `/etc/zabbix/zabbix_agentd.conf`, find `All
|
||||
AllowRoot=1
|
||||
```
|
||||
|
||||
##### 1.3.2 Grant previliges to the PHP-FPM autodiscovery script only
|
||||
If you don't want to run Zabbix Agent as root, then you can configure the previliges only to our script. In this case you need to have `sudo` installed:
|
||||
##### 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
|
||||
@ -309,11 +309,11 @@ The setup is finished, just wait a couple of minutes till Zabbix discovers all y
|
||||
First test that auto discovery of PHP-FPM pools works on your machine. Run the following command:
|
||||
|
||||
```console
|
||||
bash /etc/zabbix/zabbix_php_fpm_discovery.sh
|
||||
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:
|
||||
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
|
||||
{
|
||||
@ -334,17 +334,32 @@ The output should be a valid JSON with a list of pools and their sockets, someth
|
||||
}
|
||||
```
|
||||
|
||||
If this script does not display the list, then it will show you the list of utilities that are missing on your system and must be installed. We require the following utilities to be installed:
|
||||
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"}]}
|
||||
```
|
||||
|
||||
- awk
|
||||
- ps
|
||||
- grep
|
||||
- sort
|
||||
- head
|
||||
- lsof
|
||||
- jq
|
||||
Any warning or error messages will be displayed here.
|
||||
|
||||
If some pools are missing, then check that they do really exist and are running, for example, using command:
|
||||
**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"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
#Ramil Valitov ramilvalitov@gmail.com
|
||||
#https://github.com/rvalitov/zabbix-php-fpm
|
||||
#This script scans local machine for active PHP-FPM pools and returns them as a list in JSON format
|
||||
|
||||
S_PS=`type -P ps`
|
||||
S_GREP=`type -P grep`
|
||||
@ -39,31 +40,107 @@ if [[ ! -f $S_JQ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mapfile -t PS_LIST < <( $S_PS ax | $S_GREP "php-fpm: pool " | $S_GREP -v grep )
|
||||
DEBUG_MODE=""
|
||||
if [[ ! -z $1 ]] && [[ $1 == "debug" ]]; then
|
||||
DEBUG_MODE="1"
|
||||
echo "Debug mode enabled"
|
||||
fi
|
||||
|
||||
# Prints a string on screen. Works only if debug mode is enabled.
|
||||
function PrintDebug(){
|
||||
if [[ ! -z $DEBUG_MODE ]] && [[ ! -z $1 ]]; then
|
||||
echo $1
|
||||
fi
|
||||
}
|
||||
|
||||
mapfile -t PS_LIST < <( $S_PS ax | $S_GREP -F "php-fpm: pool " | $S_GREP -F -v "grep" )
|
||||
POOL_LIST=`printf '%s\n' "${PS_LIST[@]}" | $S_AWK '{print $NF}' | $S_SORT -u`
|
||||
POOL_FIRST=0
|
||||
echo -n "{\"data\":["
|
||||
#We store the resulting JSON data for Zabbix in the following var:
|
||||
RESULT_DATA="{\"data\":["
|
||||
while IFS= read -r line
|
||||
do
|
||||
POOL_PID=`printf '%s\n' "${PS_LIST[@]}" | $S_GREP "php-fpm: pool $line$" | $S_HEAD -1 | $S_AWK '{print $1}'`
|
||||
POOL_PID=`printf '%s\n' "${PS_LIST[@]}" | $S_GREP -F -w "php-fpm: pool $line" | $S_HEAD -1 | $S_AWK '{print $1}'`
|
||||
if [[ ! -z $POOL_PID ]]; then
|
||||
POOL_SOCKET=`$S_LSOF -p $POOL_PID 2>/dev/null | $S_GREP -e unix -e TCP | $S_HEAD -1 | $S_AWK '{print $9}'`
|
||||
#We search for socket or IP address and port
|
||||
#Socket example:
|
||||
#php-fpm7. 25897 root 9u unix 0x000000006509e31f 0t0 58381847 /run/php/php7.3-fpm.sock type=STREAM
|
||||
#IP example:
|
||||
#php-fpm7. 1110 defualt 0u IPv4 15760 0t0 TCP localhost:8002 (LISTEN)
|
||||
if [[ ! -z $POOL_SOCKET ]]; then
|
||||
#php-fpm7. 1110 default 0u IPv4 15760 0t0 TCP localhost:8002 (LISTEN)
|
||||
|
||||
#Check all matching processes, because we may face a redirect (or a symlink?), examples:
|
||||
#php-fpm7. 1203 www-data 5u unix 0x000000006509e31f 0t0 15068771 type=STREAM
|
||||
#php-fpm7. 6086 www-data 11u IPv6 21771 0t0 TCP *:9000 (LISTEN)
|
||||
#php-fpm7. 1203 www-data 8u IPv4 15070917 0t0 TCP localhost.localdomain:23054->localhost.localdomain:postgresql (ESTABLISHED)
|
||||
#More info at https://github.com/rvalitov/zabbix-php-fpm/issues/12
|
||||
|
||||
PrintDebug "Started analysis of pool $line, PID $POOL_PID"
|
||||
#Extract only important information:
|
||||
POOL_PARAMS_LIST=`$S_LSOF -p $POOL_PID 2>/dev/null | $S_GREP -w -e "unix" -e "TCP"`
|
||||
FOUND_POOL=""
|
||||
while IFS= read -r pool
|
||||
do
|
||||
if [[ ! -z $pool ]]; then
|
||||
if [[ -z $FOUND_POOL ]]; then
|
||||
PrintDebug "Checking process: $pool"
|
||||
POOL_TYPE=`echo "${pool}" | $S_AWK '{print $5}'`
|
||||
POOL_SOCKET=`echo "${pool}" | $S_AWK '{print $9}'`
|
||||
if [[ ! -z $POOL_TYPE ]] && [[ ! -z $POOL_SOCKET ]]; then
|
||||
if [[ $POOL_TYPE == "unix" ]]; then
|
||||
#We have a socket here, test if it's actually a socket:
|
||||
if [[ -S $POOL_SOCKET ]]; then
|
||||
FOUND_POOL="1"
|
||||
PrintDebug "Success: found socket $POOL_SOCKET"
|
||||
else
|
||||
PrintDebug "Error: specified socket $POOL_SOCKET is not valid"
|
||||
fi
|
||||
elif [[ $POOL_TYPE == "IPv4" ]] || [[ $POOL_TYPE == "IPv6" ]]; then
|
||||
#We have a TCP connection here, check it:
|
||||
CONNECTION_TYPE=`echo "${pool}" | $S_AWK '{print $8}'`
|
||||
if [[ $CONNECTION_TYPE == "TCP" ]]; then
|
||||
#The connection must have state LISTEN:
|
||||
LISTEN=`echo ${pool} | $S_GREP -F -w "(LISTEN)"`
|
||||
if [[ ! -z $LISTEN ]]; then
|
||||
#Check and replace * to localhost if it's found. Asterisk means that the PHP listens on
|
||||
#all interfaces.
|
||||
POOL_SOCKET=`echo -n ${POOL_SOCKET/*:/localhost:}`
|
||||
FOUND_POOL="1"
|
||||
PrintDebug "Success: found TCP connection $POOL_SOCKET"
|
||||
else
|
||||
PrintDebug "Warning: expected connection state must be LISTEN, but it was not detected"
|
||||
fi
|
||||
else
|
||||
PrintDebug "Warning: expected connection type is TCP, but found $CONNECTION_TYPE"
|
||||
fi
|
||||
else
|
||||
PrintDebug "Unsupported type $POOL_TYPE, skipping"
|
||||
fi
|
||||
else
|
||||
PrintDebug "Warning: pool type or socket is empty"
|
||||
fi
|
||||
else
|
||||
PrintDebug "Pool already found, skipping process: $pool"
|
||||
fi
|
||||
else
|
||||
PrintDebug "Error: failed to get process information. Probably insufficient privileges. Use sudo or run this script under root."
|
||||
fi
|
||||
done <<< "$POOL_PARAMS_LIST"
|
||||
|
||||
if [[ ! -z $FOUND_POOL ]]; then
|
||||
JSON_POOL=`echo -n "$line" | $S_JQ -aR .`
|
||||
JSON_SOCKET=`echo -n "$POOL_SOCKET" | $S_JQ -aR .`
|
||||
if [[ $POOL_FIRST == 1 ]]; then
|
||||
echo -n ","
|
||||
RESULT_DATA="$RESULT_DATA,"
|
||||
fi
|
||||
echo -n "{\"{#POOLNAME}\":"
|
||||
echo -n "$line" | $S_JQ -aR .
|
||||
echo -n ",\"{#POOLSOCKET}\":"
|
||||
echo -n "$POOL_SOCKET" | $S_JQ -aR .
|
||||
echo -n "}"
|
||||
RESULT_DATA="$RESULT_DATA{\"{#POOLNAME}\":$JSON_POOL,\"{#POOLSOCKET}\":$JSON_SOCKET}"
|
||||
POOL_FIRST=1
|
||||
else
|
||||
PrintDebug "Error: failed to discover information for pool $line"
|
||||
fi
|
||||
else
|
||||
PrintDebug "Error: failed to find PID for pool $line"
|
||||
fi
|
||||
done <<< "$POOL_LIST"
|
||||
echo -n "]}"
|
||||
RESULT_DATA="$RESULT_DATA]}"
|
||||
PrintDebug "Resulting JSON data for Zabbix:"
|
||||
echo -n $RESULT_DATA
|
||||
|
@ -1,13 +1,13 @@
|
||||
#!/bin/bash
|
||||
#Ramil Valitov ramilvalitov@gmail.com
|
||||
#https://github.com/rvalitov/zabbix-php-fpm
|
||||
#Script gets status of PHP-FPM pool
|
||||
|
||||
S_FCGI=`type -P cgi-fcgi`
|
||||
S_GREP=`type -P grep`
|
||||
|
||||
if [[ ! -f $S_FCGI ]]; then
|
||||
echo "Utility 'cgi-fcgi' not found. Please, install it first."
|
||||
echo "In Debian you should install a package libfcgi0ldbl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user