How to Monitor Nginx, MySQL, PHP‑FPM and Zabbix Server with Zabbix
This guide explains how to enable status modules for Nginx, MySQL and PHP‑FPM, write Bash monitoring scripts, configure Zabbix agent user parameters, create Zabbix templates, add items, triggers and graphs, and verify monitoring of all components including the Zabbix server itself.
Monitor Nginx
Enable the ngx_http_stub_status_module (compile Nginx with --with-http_stub_status_module) and add a location block to the Nginx configuration:
location /status {
stub_status;
}Reload Nginx: systemctl reload nginx Visit http://127.0.0.1/status to see the status page.
Parameter explanation:
Active connections: current active client connections (including waiting). accepts: total accepted connections. handled: total handled connections. requests: total client requests. Reading: connections reading request headers. Writing: connections writing responses. Waiting: idle connections waiting for a request.
Write a Bash script to extract these values:
#!/bin/bash
ping() { /sbin/pidof nginx | wc -l; }
nginx_active() { curl -s "http://127.0.0.1/status" | awk '/Active/ {print $NF}'; }
reading() { curl -s "http://127.0.0.1/status" | awk '/Reading/ {print $2}'; }
writing() { curl -s "http://127.0.0.1/status" | awk '/Writing/ {print $4}'; }
waiting() { curl -s "http://127.0.0.1/status" | awk '/Waiting/ {print $6}'; }
accepts() { curl -s "http://127.0.0.1/status" | awk 'NR==3 {print $1}'; }
handled() { curl -s "http://127.0.0.1/status" | awk 'NR==3 {print $2}'; }
requests() { curl -s "http://127.0.0.1/status" | awk 'NR==3 {print $3}'; }
$1Make the script executable:
chmod +x /usr/lib/zabbix/alertscripts/monitor_nginx.shAdd a user parameter to the Zabbix agent configuration:
UserParameter=nginx.[*],/usr/lib/zabbix/alertscripts/monitor_nginx.sh $1Restart the agent and test:
systemctl restart zabbix-agent
zabbix_get -s 192.168.179.132 -k nginx.[ping]Create Nginx Monitoring Template
Link the template to the host, add items (e.g., nginx.ping), create triggers and graphs as shown in the screenshots.
Monitor MySQL
Retrieve MySQL status with:
mysqladmin -uroot -proot extended-status
mysqladmin -uroot -proot statusTo avoid plain‑text passwords, store credentials in a MySQL option file and run:
mysqladmin --defaults-extra-file=/etc/my.cnf statusTwo script approaches are provided. Below is the first Bash script:
#!/bin/bash
MYSQL_USER='root'
MYSQL_PWD='root'
MYSQL_HOST='192.168.179.132'
MYSQL_PORT='3306'
MYSQL_CONN="/usr/local/mysql/bin/mysqladmin -u${MYSQL_USER} -p${MYSQL_PWD} -h${MYSQL_HOST} -P${MYSQL_PORT}"
if [ $# -ne 1 ]; then
echo "arg error!"
exit 1
fi
case $1 in
Uptime) result=`${MYSQL_CONN} status | cut -f2 -d":" | cut -f1 -d"T"`; echo $result;;
Com_update) result=`${MYSQL_CONN} extended-status | grep -w "Com_update" | cut -d"|" -f3`; echo $result;;
Slow_queries) result=`${MYSQL_CONN} status | cut -f5 -d":" | cut -f1 -d"O"`; echo $result;;
Com_select) result=`${MYSQL_CONN} extended-status | grep -w "Com_select" | cut -d"|" -f3`; echo $result;;
Com_rollback) result=`${MYSQL_CONN} extended-status | grep -w "Com_rollback" | cut -d"|" -f3`; echo $result;;
Questions) result=`${MYSQL_CONN} status | cut -f4 -d":" | cut -f1 -d"S"`; echo $result;;
Com_insert) result=`${MYSQL_CONN} extended-status | grep -w "Com_insert" | cut -d"|" -f3`; echo $result;;
Com_delete) result=`${MYSQL_CONN} extended-status | grep -w "Com_delete" | cut -d"|" -f3`; echo $result;;
Com_commit) result=`${MYSQL_CONN} extended-status | grep -w "Com_commit" | cut -d"|" -f3`; echo $result;;
Bytes_sent) result=`${MYSQL_CONN} extended-status | grep -w "Bytes_sent" | cut -d"|" -f3`; echo $result;;
Bytes_received) result=`${MYSQL_CONN} extended-status | grep -w "Bytes_received" | cut -d"|" -f3`; echo $result;;
Com_begin) result=`${MYSQL_CONN} extended-status | grep -w "Com_begin" | cut -d"|" -f3`; echo $result;;
*) echo "Usage:$0(Uptime|Com_update|Slow_queries|Com_select|Com_rollback|Questions|Com_insert|Com_delete|Com_commit|Bytes_sent|Bytes_received|Com_begin)";;
esacMake it executable:
chmod +x /usr/lib/zabbix/alertscripts/monitor_mysql.shAdd user parameters to /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf:
UserParameter=mysql.status[*],/usr/lib/zabbix/alertscripts/monitor_mysql.sh $1
UserParameter=mysql.ping,/usr/local/mysql/bin/mysqladmin -uroot -proot ping 2>/dev/null | grep -c alive
UserParameter=mysql.slave,mysql -uroot -proot -e 'show slave status\G' 2>/dev/null | grep -E "Slave_IO_Running|Slave_SQL_Running" | awk '{print $2}' | grep -c YesRestart the agent and test:
systemctl restart zabbix-agent
zabbix_get -s 192.168.179.132 -k mysql.ping
zabbix_get -s 192.168.179.132 -k mysql.[Uptime]Monitor PHP‑FPM
Enable status in /usr/local/php/etc/php-fpm.d/www.conf: pm.status_path = /php_status Uncomment the PID line in /usr/local/php/etc/php-fpm.conf: pid = run/php-fpm.pid Reload PHP‑FPM:
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`Add a location to Nginx for the status page:
location ~ ^/(php_status|ping)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params;
}Reload Nginx and test:
systemctl reload nginx
curl 127.0.0.1/php_status
curl 127.0.0.1/php_status?fullPHP‑FPM status parameters:
pool, process manager, start time, start since, accepted conn, listen queue, max listen queue, listen queue len, idle processes, active processes, total processes, max active processes, max children reached, slow requests.
Full detail (XML output) parameters:
pid, state, start time, start since, requests, request duration, request method, request URI, content length, user, script, last request cpu, last request memory.
Add user parameters for PHP‑FPM to /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf:
UserParameter=php-fpm.status[*],/usr/bin/curl -s "http://127.0.0.1/php_status?xml" | grep "<$1>" | cut -d '>' -f2 | cut -d '<' -f1
UserParameter=php-fpm.ping,/sbin/pidof php-fpm | wc -l
UserParameter=php-fpm.version,/usr/local/php/sbin/php-fpm -v | awk 'NR==1{print $1,$2}'Restart the agent and verify:
systemctl restart zabbix-agent
zabbix_get -s 192.168.179.132 -k php-fpm.pingMonitor Zabbix Server
Zabbix already provides a template for monitoring the server itself; simply link the Zabbix‑server template to the host. No additional Zabbix‑agent template is required because it is already linked to the OS template.
All templates and scripts referenced in this article are available on GitHub:
https://github.com/zhouhua-amei/zabbix/
Feel free to join the discussion and share your experience.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
