From f672eb05c62a480c47c26378cd69035c65e278a0 Mon Sep 17 00:00:00 2001 From: cschantz Date: Wed, 18 Feb 2026 17:43:44 -0500 Subject: [PATCH] Fix Option 2: Batch analyzer now shows all pool settings (max_children, pm, max_requests, idle_timeout) with combined memory capacity check - Fixed 'local' keyword errors outside function scope - Added tracking for pm.mode, pm.max_requests, pm.min_spare_servers, pm.max_spare_servers, pm.process_idle_timeout - Display all pool settings per domain in batch analysis - Added combined memory capacity check (if ALL pools hit max_children) - Status indicators for memory safety: CRITICAL/WARNING/CAUTION/HEALTHY - Complete server-wide big picture analysis in one command --- modules/performance/php-fpm-batch-analyzer.sh | 75 ++++++++++++++++--- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/modules/performance/php-fpm-batch-analyzer.sh b/modules/performance/php-fpm-batch-analyzer.sh index 1f4b036..7e1daf7 100755 --- a/modules/performance/php-fpm-batch-analyzer.sh +++ b/modules/performance/php-fpm-batch-analyzer.sh @@ -83,10 +83,16 @@ declare -a recommended_max_children declare -a memory_impact declare -a needs_optimization declare -a peak_concurrent +declare -a pm_mode +declare -a pm_max_requests +declare -a pm_min_spare +declare -a pm_max_spare +declare -a pm_idle_timeout TOTAL_DOMAINS=0 TOTAL_CURRENT_MEMORY=0 TOTAL_RECOMMENDED_MEMORY=0 +TOTAL_CURRENT_MEMORY_WITH_MAX=0 while IFS= read -r username; do [ -z "$username" ] && continue @@ -115,6 +121,22 @@ while IFS= read -r username; do current=${current:-40} current_max_children[$TOTAL_DOMAINS]="$current" + # Get all pool settings + pm_mode_val=$(grep "^pm = " "$pool_config" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' ') + pm_mode[$TOTAL_DOMAINS]="${pm_mode_val:-static}" + + pm_max_req=$(grep "^pm.max_requests = " "$pool_config" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' ') + pm_max_requests[$TOTAL_DOMAINS]="${pm_max_req:-0}" + + pm_min=$(grep "^pm.min_spare_servers = " "$pool_config" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' ') + pm_min_spare[$TOTAL_DOMAINS]="${pm_min:-2}" + + pm_max=$(grep "^pm.max_spare_servers = " "$pool_config" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' ') + pm_max_spare[$TOTAL_DOMAINS]="${pm_max:-8}" + + pm_idle=$(grep "^pm.process_idle_timeout = " "$pool_config" 2>/dev/null | awk -F'=' '{print $2}' | tr -d ' ') + pm_idle_timeout[$TOTAL_DOMAINS]="${pm_idle:-10}" + # 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) @@ -128,13 +150,13 @@ while IFS= read -r username; do memory_impact[$TOTAL_DOMAINS]="$impact" # Get peak concurrent requests for this domain - local peak peak=$(get_domain_peak_concurrent "$domain" 2>/dev/null || echo "?") peak_concurrent[$TOTAL_DOMAINS]="$peak" # Track totals TOTAL_CURRENT_MEMORY=$((TOTAL_CURRENT_MEMORY + current_memory)) TOTAL_RECOMMENDED_MEMORY=$((TOTAL_RECOMMENDED_MEMORY + recommended_memory)) + TOTAL_CURRENT_MEMORY_WITH_MAX=$((TOTAL_CURRENT_MEMORY_WITH_MAX + current_memory)) # Determine if optimization needed if [ "$recommended" -lt "$current" ]; then @@ -151,10 +173,8 @@ done <<< "$users" # ============================================================================ # Build sortable list with priority (traffic-based) -echo "Building prioritized analysis..." >&2 - -declare -a sorted_indices -declare -a domain_sort_data +sorted_indices=() +domain_sort_data=() for idx in $(seq 1 $TOTAL_DOMAINS); do domain="${domain_list[$idx]}" @@ -205,7 +225,7 @@ for idx in "${sorted_indices[@]}"; do fi # Determine traffic indicator - local traffic_indicator="" + traffic_indicator="" if [[ "$peak" =~ ^[0-9]+$ ]]; then if [ "$peak" -ge 20 ]; then traffic_indicator="${RED}⚠ CRITICAL TRAFFIC (${peak})${NC}" @@ -220,12 +240,20 @@ for idx in "${sorted_indices[@]}"; do traffic_indicator="${WHITE}○ TRAFFIC UNKNOWN${NC}" fi - # Format output + # Format output with all pool settings if [ "$optimize" == "YES" ]; then cecho "${YELLOW}[$idx]${NC} $domain" cecho " Owner: $owner" cecho " Traffic: $traffic_indicator" - cecho " Current max_children: ${RED}$current${NC} → Recommended: ${GREEN}$recommended${NC}" + cecho "" + cecho " ${BOLD}Current Pool Settings:${NC}" + cecho " pm.max_children: ${RED}$current${NC} → Recommended: ${GREEN}$recommended${NC}" + cecho " pm: ${WHITE}${pm_mode[$idx]}${NC}" + cecho " pm.min_spare_servers: ${WHITE}${pm_min_spare[$idx]}${NC}" + cecho " pm.max_spare_servers: ${WHITE}${pm_max_spare[$idx]}${NC}" + cecho " pm.max_requests: ${WHITE}${pm_max_requests[$idx]}${NC}" + cecho " pm.process_idle_timeout: ${WHITE}${pm_idle_timeout[$idx]}${NC}" + cecho "" cecho " Memory impact: ${GREEN}+${impact}MB${NC} if optimized" cecho " Status: ${YELLOW}NEEDS OPTIMIZATION${NC}" OPTIMIZATION_COUNT=$((OPTIMIZATION_COUNT + 1)) @@ -233,7 +261,15 @@ for idx in "${sorted_indices[@]}"; do cecho "${GREEN}[$idx]${NC} $domain" cecho " Owner: $owner" cecho " Traffic: $traffic_indicator" - cecho " max_children: $current (already optimized)" + cecho "" + cecho " ${BOLD}Pool Settings:${NC}" + cecho " pm.max_children: $current" + cecho " pm: ${WHITE}${pm_mode[$idx]}${NC}" + cecho " pm.min_spare_servers: ${WHITE}${pm_min_spare[$idx]}${NC}" + cecho " pm.max_spare_servers: ${WHITE}${pm_max_spare[$idx]}${NC}" + cecho " pm.max_requests: ${WHITE}${pm_max_requests[$idx]}${NC}" + cecho " pm.process_idle_timeout: ${WHITE}${pm_idle_timeout[$idx]}${NC}" + cecho "" cecho " Status: ${GREEN}OK${NC}" fi @@ -272,6 +308,27 @@ cecho " ${BOLD}Optimization Potential:${NC}" cecho " Memory that could be freed: ${GREEN}${POTENTIAL_SAVINGS}MB${NC} (${POTENTIAL_SAVINGS_PERCENT}% reduction)" echo "" +# Combined Memory Capacity Check +cecho "${WHITE}${BOLD}COMBINED MEMORY CAPACITY (If ALL pools hit max_children):${NC}" +ALL_MAX_PERCENT=$((TOTAL_CURRENT_MEMORY_WITH_MAX * 100 / TOTAL_RAM_MB)) + +if [ "$ALL_MAX_PERCENT" -gt 100 ]; then + cecho " Total if all at max: ${RED}${TOTAL_CURRENT_MEMORY_WITH_MAX}MB${NC} (${RED}${ALL_MAX_PERCENT}%${NC} of ${TOTAL_RAM_MB}MB)" + cecho " Status: ${RED}${BOLD}CRITICAL - SERVER WILL RUN OUT OF MEMORY!${NC}" + cecho " ${RED}⚠ The server would exceed available RAM by $((TOTAL_CURRENT_MEMORY_WITH_MAX - TOTAL_RAM_MB))MB${NC}" +elif [ "$ALL_MAX_PERCENT" -gt 90 ]; then + cecho " Total if all at max: ${YELLOW}${TOTAL_CURRENT_MEMORY_WITH_MAX}MB${NC} (${YELLOW}${ALL_MAX_PERCENT}%${NC} of ${TOTAL_RAM_MB}MB)" + cecho " Status: ${YELLOW}${BOLD}WARNING - High memory pressure${NC}" + cecho " ${YELLOW}⚠ Only $((TOTAL_RAM_MB - TOTAL_CURRENT_MEMORY_WITH_MAX))MB headroom remaining${NC}" +elif [ "$ALL_MAX_PERCENT" -gt 75 ]; then + cecho " Total if all at max: ${CYAN}${TOTAL_CURRENT_MEMORY_WITH_MAX}MB${NC} (${CYAN}${ALL_MAX_PERCENT}%${NC} of ${TOTAL_RAM_MB}MB)" + cecho " Status: ${CYAN}CAUTION - Monitor memory usage${NC}" +else + cecho " Total if all at max: ${GREEN}${TOTAL_CURRENT_MEMORY_WITH_MAX}MB${NC} (${GREEN}${ALL_MAX_PERCENT}%${NC} of ${TOTAL_RAM_MB}MB)" + cecho " Status: ${GREEN}${BOLD}HEALTHY${NC} - Sufficient memory headroom" +fi +echo "" + if [ "$OPTIMIZATION_COUNT" -gt 0 ]; then cecho " ${BOLD}Recommendation:${NC}" cecho " ${YELLOW}⚠ $OPTIMIZATION_COUNT domain(s) could be optimized${NC}"