Files
Linux-Server-Management-Too…/modules/performance/php-fpm-batch-analyzer.sh
T
cschantz 13d7054aa1 Fix critical bugs and add domain-by-domain batch analyzer
- Fix line 63 in php-analyzer.sh: Add default value for count variable (integer comparison error)
- Fix line 655 in php-analyzer.sh: Add default value for memory_error_count (integer comparison error)
- Fix line 396 in php-scanner.sh: Replace unsafe eval with safe getent passwd lookup
- Add php-ui.sh: User interface and menu system (18KB, 25+ functions)
- Add php-scanner.sh: Server enumeration system (17KB, 18 functions)
- Add php-action-executor.sh: Optimization execution system (17KB, 20 functions)
- Add php-server-manager.sh: Orchestration framework (21KB, 7 functions)
- Add php-fpm-batch-analyzer.sh: One-shot diagnostic script showing current vs recommended max_children, memory impact, and optimization potential
- Add comprehensive test suite (24 tests)

These fixes resolve "integer expression expected" errors during domain analysis.
Batch analyzer enables users to see domain-by-domain optimization opportunities before applying changes.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-17 22:43:49 -05:00

274 lines
11 KiB
Bash
Executable File

#!/bin/bash
# PHP-FPM Batch Analyzer - One-Shot Diagnostic Script
# Analyzes all domains on server, shows current vs recommended max_children
# Shows memory impact and optimization opportunities
# Drop in, run once, then delete
set -e
PHP_TOOLKIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)"
# Source required libraries
source "$PHP_TOOLKIT_DIR/lib/common-functions.sh" 2>/dev/null || { echo "ERROR: common-functions.sh not found"; exit 1; }
source "$PHP_TOOLKIT_DIR/lib/system-detect.sh" 2>/dev/null || { echo "ERROR: system-detect.sh not found"; exit 1; }
source "$PHP_TOOLKIT_DIR/lib/user-manager.sh" 2>/dev/null || { echo "ERROR: user-manager.sh not found"; exit 1; }
source "$PHP_TOOLKIT_DIR/lib/php-detector.sh" 2>/dev/null || { echo "ERROR: php-detector.sh not found"; exit 1; }
source "$PHP_TOOLKIT_DIR/lib/php-analyzer.sh" 2>/dev/null || { echo "ERROR: php-analyzer.sh not found"; exit 1; }
source "$PHP_TOOLKIT_DIR/lib/php-calculator-improved.sh" 2>/dev/null || { echo "ERROR: php-calculator-improved.sh not found"; exit 1; }
source "$PHP_TOOLKIT_DIR/lib/php-scanner.sh" 2>/dev/null || { echo "ERROR: php-scanner.sh not found"; exit 1; }
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
BOLD='\033[1m'
NC='\033[0m'
cecho() {
echo -e "$@"
}
# ============================================================================
# INITIALIZATION
# ============================================================================
initialize_system_detection
if [ "$EUID" -ne 0 ]; then
cecho "${RED}ERROR: This script must be run as root${NC}"
exit 1
fi
# ============================================================================
# MAIN ANALYSIS
# ============================================================================
cecho "${CYAN}╔════════════════════════════════════════════════════════════════════════╗${NC}"
cecho "${CYAN}${WHITE} PHP-FPM BATCH ANALYZER - DIAGNOSTIC REPORT ${CYAN}${NC}"
cecho "${CYAN}╚════════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
# Get server info
cecho "${WHITE}${BOLD}SERVER INFORMATION${NC}"
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
TOTAL_RAM_MB=$(free -m | awk '/^Mem:/ {print $2}')
CPU_CORES=$(nproc)
CONTROL_PANEL="$SYS_CONTROL_PANEL"
cecho " Total RAM: ${WHITE}${TOTAL_RAM_MB}MB${NC}"
cecho " CPU Cores: ${WHITE}${CPU_CORES}${NC}"
cecho " Control Panel: ${WHITE}${CONTROL_PANEL}${NC}"
cecho " Scan Date: ${WHITE}$(date)${NC}"
echo ""
# ============================================================================
# DOMAIN ENUMERATION & ANALYSIS
# ============================================================================
cecho "${WHITE}${BOLD}DOMAIN-BY-DOMAIN ANALYSIS${NC}"
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
echo ""
# Get all users and domains
users=$(list_all_users)
# Initialize tracking arrays
declare -a domain_list
declare -a domain_owner
declare -a current_max_children
declare -a recommended_max_children
declare -a memory_impact
declare -a needs_optimization
TOTAL_DOMAINS=0
TOTAL_CURRENT_MEMORY=0
TOTAL_RECOMMENDED_MEMORY=0
while IFS= read -r username; do
[ -z "$username" ] && continue
user_domains=$(get_user_domains "$username")
while IFS= read -r domain; do
[ -z "$domain" ] && continue
TOTAL_DOMAINS=$((TOTAL_DOMAINS + 1))
domain_list[$TOTAL_DOMAINS]="$domain"
domain_owner[$TOTAL_DOMAINS]="$username"
# Find pool config
pool_config=$(find_fpm_pool_config "$username" "$domain" 2>/dev/null)
if [ -z "$pool_config" ] || [ ! -f "$pool_config" ]; then
current_max_children[$TOTAL_DOMAINS]="ERROR"
recommended_max_children[$TOTAL_DOMAINS]="ERROR"
memory_impact[$TOTAL_DOMAINS]="?"
continue
fi
# Get current max_children
current=$(grep "^pm.max_children" "$pool_config" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' ')
current=${current:-40}
current_max_children[$TOTAL_DOMAINS]="$current"
# Calculate recommended using improved algorithm
recommended_result=$(calculate_optimal_php_settings "$username" "$TOTAL_RAM_MB" 2>/dev/null || echo "20||")
recommended=$(echo "$recommended_result" | cut -d'|' -f1)
recommended=${recommended:-20}
recommended_max_children[$TOTAL_DOMAINS]="$recommended"
# Calculate memory impact (assuming 20MB per process on average)
current_memory=$((current * 20))
recommended_memory=$((recommended * 20))
impact=$((current_memory - recommended_memory))
memory_impact[$TOTAL_DOMAINS]="$impact"
# Track totals
TOTAL_CURRENT_MEMORY=$((TOTAL_CURRENT_MEMORY + current_memory))
TOTAL_RECOMMENDED_MEMORY=$((TOTAL_RECOMMENDED_MEMORY + recommended_memory))
# Determine if optimization needed
if [ "$recommended" -lt "$current" ]; then
needs_optimization[$TOTAL_DOMAINS]="YES"
else
needs_optimization[$TOTAL_DOMAINS]="NO"
fi
done <<< "$user_domains"
done <<< "$users"
# ============================================================================
# DISPLAY RESULTS
# ============================================================================
# Sort and display domains
OPTIMIZATION_COUNT=0
for idx in $(seq 1 $TOTAL_DOMAINS); do
domain="${domain_list[$idx]}"
owner="${domain_owner[$idx]}"
current="${current_max_children[$idx]}"
recommended="${recommended_max_children[$idx]}"
impact="${memory_impact[$idx]}"
optimize="${needs_optimization[$idx]}"
if [ "$current" == "ERROR" ]; then
continue
fi
# Format output
if [ "$optimize" == "YES" ]; then
cecho "${YELLOW}[$idx]${NC} $domain"
cecho " Owner: $owner"
cecho " Current max_children: ${RED}$current${NC} → Recommended: ${GREEN}$recommended${NC}"
cecho " Memory impact: ${GREEN}+${impact}MB${NC} if optimized"
cecho " Status: ${YELLOW}NEEDS OPTIMIZATION${NC}"
OPTIMIZATION_COUNT=$((OPTIMIZATION_COUNT + 1))
else
cecho "${GREEN}[$idx]${NC} $domain"
cecho " Owner: $owner"
cecho " max_children: $current (already optimized)"
cecho " Status: ${GREEN}OK${NC}"
fi
echo ""
done
# ============================================================================
# SERVER-WIDE SUMMARY
# ============================================================================
echo ""
cecho "${WHITE}${BOLD}SERVER-WIDE SUMMARY${NC}"
cecho "${CYAN}═════════════════════════════════════════════════════════════════════${NC}"
echo ""
# Calculate percentages
CURRENT_PERCENT=$((TOTAL_CURRENT_MEMORY * 100 / TOTAL_RAM_MB))
RECOMMENDED_PERCENT=$((TOTAL_RECOMMENDED_MEMORY * 100 / TOTAL_RAM_MB))
POTENTIAL_SAVINGS=$((TOTAL_CURRENT_MEMORY - TOTAL_RECOMMENDED_MEMORY))
POTENTIAL_SAVINGS_PERCENT=$((POTENTIAL_SAVINGS * 100 / TOTAL_CURRENT_MEMORY))
cecho " Total domains analyzed: ${WHITE}$TOTAL_DOMAINS${NC}"
cecho " Domains needing optimization: ${YELLOW}$OPTIMIZATION_COUNT${NC}"
cecho " Domains already optimized: ${GREEN}$((TOTAL_DOMAINS - OPTIMIZATION_COUNT))${NC}"
echo ""
cecho " ${BOLD}Current Memory Allocation:${NC}"
cecho " Total: ${WHITE}${TOTAL_CURRENT_MEMORY}MB${NC} (${RED}${CURRENT_PERCENT}%${NC} of ${TOTAL_RAM_MB}MB RAM)"
echo ""
cecho " ${BOLD}Recommended Memory Allocation:${NC}"
cecho " Total: ${WHITE}${TOTAL_RECOMMENDED_MEMORY}MB${NC} (${GREEN}${RECOMMENDED_PERCENT}%${NC} of ${TOTAL_RAM_MB}MB RAM)"
echo ""
cecho " ${BOLD}Optimization Potential:${NC}"
cecho " Memory that could be freed: ${GREEN}${POTENTIAL_SAVINGS}MB${NC} (${POTENTIAL_SAVINGS_PERCENT}% reduction)"
echo ""
if [ "$OPTIMIZATION_COUNT" -gt 0 ]; then
cecho " ${BOLD}Recommendation:${NC}"
cecho " ${YELLOW}$OPTIMIZATION_COUNT domain(s) could be optimized${NC}"
cecho " Run: ${WHITE}php-optimizer.sh${NC}${CYAN}Option 5${NC} (Optimize Server-Wide)"
else
cecho " ${BOLD}Status:${NC}"
cecho " ${GREEN}✓ All domains are already optimized${NC}"
fi
echo ""
cecho "${CYAN}═════════════════════════════════════════════════════════════════════${NC}"
echo ""
# ============================================================================
# SAFETY WARNINGS
# ============================================================================
# Check memory headroom
AVAILABLE_AFTER_RECOMMENDED=$((TOTAL_RAM_MB - TOTAL_RECOMMENDED_MEMORY))
if [ "$AVAILABLE_AFTER_RECOMMENDED" -lt 2048 ]; then
cecho "${RED}${BOLD}⚠ WARNING: Limited memory headroom${NC}"
cecho " After applying recommended settings, only ${AVAILABLE_AFTER_RECOMMENDED}MB would be available"
echo ""
fi
# Check if already optimized
if [ "$OPTIMIZATION_COUNT" -eq 0 ]; then
cecho "${GREEN}${BOLD}✓ All domains are already optimized${NC}"
echo ""
fi
# ============================================================================
# CLEANUP
# ============================================================================
cecho "${WHITE}${BOLD}Report complete${NC}"
cecho " Generated: $(date '+%Y-%m-%d %H:%M:%S')"
echo ""
# Optional: save to file
REPORT_FILE="/tmp/php-fpm-analysis-$(date +%Y%m%d-%H%M%S).txt"
if [ -w /tmp ]; then
{
echo "PHP-FPM BATCH ANALYSIS REPORT"
echo "Generated: $(date)"
echo ""
echo "SERVER INFORMATION"
echo "Total RAM: ${TOTAL_RAM_MB}MB"
echo "CPU Cores: ${CPU_CORES}"
echo "Control Panel: ${CONTROL_PANEL}"
echo ""
echo "SUMMARY"
echo "Total domains: $TOTAL_DOMAINS"
echo "Domains needing optimization: $OPTIMIZATION_COUNT"
echo "Current memory allocation: ${TOTAL_CURRENT_MEMORY}MB (${CURRENT_PERCENT}%)"
echo "Recommended memory allocation: ${TOTAL_RECOMMENDED_MEMORY}MB (${RECOMMENDED_PERCENT}%)"
echo "Potential savings: ${POTENTIAL_SAVINGS}MB (${POTENTIAL_SAVINGS_PERCENT}%)"
} > "$REPORT_FILE"
cecho "Report saved to: ${CYAN}$REPORT_FILE${NC}"
fi
echo ""