File: //usr/local/sbin/phpfpm-watchdog.sh
#!/bin/bash
# PHP-FPM Watchdog - kills runaway PHP-FPM workers
# Thresholds: CPU > 80% for > 90 seconds runtime
CPU_THRESHOLD=80
MIN_RUNTIME=90
LOG="/var/log/phpfpm-watchdog.log"
KILLED=0
while IFS= read -r line; do
PID=$(echo "$line" | awk '{print $2}')
CPU=$(echo "$line" | awk '{print $3}' | cut -d. -f1)
# Get elapsed time in seconds
ELAPSED=$(ps -o etimes= -p "$PID" 2>/dev/null | tr -d ' ')
[ -z "$ELAPSED" ] && continue
if [ "$CPU" -ge "$CPU_THRESHOLD" ] && [ "$ELAPSED" -ge "$MIN_RUNTIME" ]; then
PROC=$(echo "$line" | awk '{for(i=11;i<=NF;i++) printf $i" "; print ""}')
echo "[$(date '+%Y-%m-%d %H:%M:%S')] KILL PID=$PID CPU=${CPU}% ELAPSED=${ELAPSED}s PROC=$PROC" >> "$LOG"
kill -9 "$PID" 2>/dev/null
KILLED=$((KILLED+1))
fi
done < <(ps aux --no-headers | grep 'php-fpm: pool\|php-cgi' | grep -v grep)
if [ "$KILLED" -gt 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Total killed: $KILLED" >> "$LOG"
fi