Phase 3: Add interactive PHP Performance Optimizer (modules/performance/php-optimizer.sh)
COMPLETE INTERACTIVE MENU SYSTEM: - 8 main menu options for comprehensive PHP optimization - Domain selection with PHP version display - Real-time analysis and recommendations - Color-coded severity levels (CRITICAL/HIGH/MEDIUM/LOW) - Safe implementation with cecho() helper MENU OPTIONS: 1. Analyze Single Domain - Complete PHP analysis report 2. Analyze All Domains - Server-wide analysis with issue detection 3. Quick Health Check - Overall health score based on issues 4. Optimize Domain - Detect issues + show recommendations 5. Optimize Server-Wide - (Placeholder for future) 6. View OPcache Statistics - Hit rates, memory usage, cache efficiency 7. View PHP-FPM Process Stats - Memory usage, process counts, pool config 8. Check Configuration Issues - Grouped by severity with recommendations FEATURES IMPLEMENTED: - Domain selection with user/PHP version context - Comprehensive analysis using lib/php-analyzer.sh - Issue detection with 4 severity levels - OPcache statistics with hit rate analysis - PHP-FPM resource usage tracking - Optimal max_children calculations - Health scoring system (0-100) - Color-coded output for readability ANALYSIS CAPABILITIES: - PHP version detection per domain - Configuration hierarchy display (4 priority levels) - Effective settings resolution - PHP-FPM pool configuration parsing - Resource usage statistics (processes, memory) - OPcache performance metrics - Traffic analysis (requests/min, peak concurrent) - Error analysis (7-day history) ISSUE DETECTION: - Config mismatches (post_max_size < upload_max_filesize) - Security risks (display_errors = On) - Performance issues (low memory_limit, OPcache disabled) - Capacity issues (max_children errors) - Memory leaks (pm.max_requests = 0) - Resource waste (pm=static on low traffic) RECOMMENDATIONS ENGINE: - Calculates optimal pm.max_children based on: * System memory (total - reserved) * Average memory per process * 20% safety buffer - OPcache optimization suggestions - Memory limit adjustments - Process manager mode recommendations SAFETY FEATURES: - Read-only analysis (no modifications yet) - Root user check - PHP-FPM detection with warnings - Graceful handling of missing data - Clear "not yet implemented" placeholders for future features DISPLAY FEATURES: - Formatted banners and section separators - Color-coded severity (RED=critical, YELLOW=high, BLUE=medium, GREEN=low) - Progress indicators for multi-domain analysis - Summary statistics and health scores - Grouped issue display by severity INTEGRATION: - Uses lib/php-detector.sh for detection (Phase 1) - Uses lib/php-analyzer.sh for analysis (Phase 2) - Uses lib/system-detect.sh for system detection - Uses lib/user-manager.sh for user/domain management NOT YET IMPLEMENTED (Future): - Automatic configuration changes (backup/apply/restore) - Server-wide optimization in single action - Backup/restore functionality - Integration with live-attack-monitor (NOT requested by user) USAGE: bash /root/server-toolkit/modules/performance/php-optimizer.sh All 3 phases complete! PHP optimizer ready for testing and refinement. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Executable
+799
@@ -0,0 +1,799 @@
|
||||
#!/bin/bash
|
||||
# PHP & Server Performance Optimizer
|
||||
# Interactive tool for analyzing and optimizing PHP-FPM configurations
|
||||
# Part of Server Toolkit - Phase 3: Main Interactive Script
|
||||
|
||||
# Source required libraries
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)"
|
||||
source "$SCRIPT_DIR/lib/php-detector.sh" 2>/dev/null || { echo "ERROR: php-detector.sh not found"; exit 1; }
|
||||
source "$SCRIPT_DIR/lib/php-analyzer.sh" 2>/dev/null || { echo "ERROR: php-analyzer.sh not found"; exit 1; }
|
||||
source "$SCRIPT_DIR/lib/system-detect.sh" 2>/dev/null || { echo "ERROR: system-detect.sh not found"; exit 1; }
|
||||
source "$SCRIPT_DIR/lib/user-manager.sh" 2>/dev/null || { echo "ERROR: user-manager.sh not found"; exit 1; }
|
||||
|
||||
# Color codes (using safe echo -e)
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
MAGENTA='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
WHITE='\033[1;37m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Safe color echo function
|
||||
cecho() {
|
||||
echo -e "$@"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# BANNER & DISPLAY FUNCTIONS
|
||||
# ============================================================================
|
||||
|
||||
show_banner() {
|
||||
clear
|
||||
cecho "${CYAN}╔══════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
cecho "${CYAN}║${WHITE} PHP & SERVER PERFORMANCE OPTIMIZER ${CYAN}║${NC}"
|
||||
cecho "${CYAN}╚══════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_main_menu() {
|
||||
cecho "${WHITE}${BOLD}MAIN MENU${NC}"
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
cecho " ${GREEN}1${NC}) Analyze Single Domain"
|
||||
cecho " ${GREEN}2${NC}) Analyze All Domains (Server-Wide)"
|
||||
cecho " ${GREEN}3${NC}) Quick Health Check (All Domains)"
|
||||
cecho " ${GREEN}4${NC}) Optimize Domain PHP Settings"
|
||||
cecho " ${GREEN}5${NC}) Optimize Server-Wide PHP Settings"
|
||||
cecho " ${GREEN}6${NC}) View OPcache Statistics"
|
||||
cecho " ${GREEN}7${NC}) View PHP-FPM Process Stats"
|
||||
cecho " ${GREEN}8${NC}) Check for Configuration Issues"
|
||||
echo ""
|
||||
cecho " ${YELLOW}b${NC}) Backup Current Configurations"
|
||||
cecho " ${YELLOW}r${NC}) Restore from Backup"
|
||||
echo ""
|
||||
cecho " ${RED}q${NC}) Quit"
|
||||
echo ""
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# DOMAIN SELECTION
|
||||
# ============================================================================
|
||||
|
||||
select_domain() {
|
||||
local action="${1:-analyze}"
|
||||
|
||||
cecho "${WHITE}${BOLD}SELECT DOMAIN${NC}"
|
||||
echo ""
|
||||
|
||||
# Get all users with domains
|
||||
local users
|
||||
users=$(list_all_users)
|
||||
|
||||
if [ -z "$users" ]; then
|
||||
cecho "${RED}ERROR: No users found on system${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Build domain list
|
||||
declare -a domains
|
||||
declare -A domain_to_user
|
||||
|
||||
while IFS= read -r username; do
|
||||
local user_domains
|
||||
user_domains=$(get_user_domains "$username")
|
||||
|
||||
while IFS= read -r domain; do
|
||||
[ -z "$domain" ] && continue
|
||||
domains+=("$domain")
|
||||
domain_to_user["$domain"]="$username"
|
||||
done <<< "$user_domains"
|
||||
done <<< "$users"
|
||||
|
||||
if [ ${#domains[@]} -eq 0 ]; then
|
||||
cecho "${RED}ERROR: No domains found on system${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Display numbered list
|
||||
cecho "${CYAN}Available domains:${NC}"
|
||||
echo ""
|
||||
|
||||
local index=1
|
||||
for domain in "${domains[@]}"; do
|
||||
local username="${domain_to_user[$domain]}"
|
||||
local php_version
|
||||
php_version=$(detect_php_version_for_domain "$domain" 2>/dev/null || echo "unknown")
|
||||
|
||||
printf " ${GREEN}%-3d${NC}) %-40s ${CYAN}[${username}]${NC} ${YELLOW}(${php_version})${NC}\n" "$index" "$domain"
|
||||
index=$((index + 1))
|
||||
done
|
||||
|
||||
echo ""
|
||||
read -p "Select domain number (or 'q' to cancel): " selection
|
||||
|
||||
if [[ "$selection" == "q" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! [[ "$selection" =~ ^[0-9]+$ ]] || [ "$selection" -lt 1 ] || [ "$selection" -gt ${#domains[@]} ]; then
|
||||
cecho "${RED}Invalid selection${NC}"
|
||||
sleep 2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Return selected domain and username
|
||||
local selected_domain="${domains[$((selection - 1))]}"
|
||||
local selected_user="${domain_to_user[$selected_domain]}"
|
||||
|
||||
echo "$selected_domain|$selected_user"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 1: ANALYZE SINGLE DOMAIN
|
||||
# ============================================================================
|
||||
|
||||
analyze_single_domain() {
|
||||
show_banner
|
||||
|
||||
local selection
|
||||
selection=$(select_domain "analyze")
|
||||
|
||||
if [ $? -ne 0 ] || [ -z "$selection" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local domain username
|
||||
domain=$(echo "$selection" | cut -d'|' -f1)
|
||||
username=$(echo "$selection" | cut -d'|' -f2)
|
||||
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}Analyzing: ${GREEN}$domain${WHITE} (user: ${CYAN}$username${WHITE})${NC}"
|
||||
echo ""
|
||||
|
||||
# Run comprehensive analysis
|
||||
analyze_domain_php "$username" "$domain"
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 2: ANALYZE ALL DOMAINS
|
||||
# ============================================================================
|
||||
|
||||
analyze_all_domains() {
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}SERVER-WIDE ANALYSIS${NC}"
|
||||
echo ""
|
||||
cecho "${YELLOW}This will analyze PHP configuration for ALL domains...${NC}"
|
||||
echo ""
|
||||
read -p "Continue? (y/n): " confirm
|
||||
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}Analyzing all domains...${NC}"
|
||||
echo ""
|
||||
|
||||
# Get all users
|
||||
local users
|
||||
users=$(list_all_users)
|
||||
|
||||
local total_domains=0
|
||||
local domains_with_issues=0
|
||||
|
||||
while IFS= read -r username; do
|
||||
local user_domains
|
||||
user_domains=$(get_user_domains "$username")
|
||||
|
||||
while IFS= read -r domain; do
|
||||
[ -z "$domain" ] && continue
|
||||
|
||||
total_domains=$((total_domains + 1))
|
||||
|
||||
cecho "${CYAN}[$total_domains] Analyzing: ${WHITE}$domain${NC}"
|
||||
|
||||
# Detect issues
|
||||
local issues
|
||||
issues=$(detect_php_config_issues "$username" "$domain")
|
||||
|
||||
# Count critical/high severity issues
|
||||
local critical_count
|
||||
critical_count=$(echo "$issues" | grep -c "CRITICAL\|HIGH" || echo "0")
|
||||
|
||||
if [ "$critical_count" -gt 0 ]; then
|
||||
domains_with_issues=$((domains_with_issues + 1))
|
||||
cecho " ${RED}✗ $critical_count critical/high severity issues detected${NC}"
|
||||
|
||||
# Show issues
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ -z "$issue_type" ] && continue
|
||||
|
||||
if [[ "$severity" == "CRITICAL" ]] || [[ "$severity" == "HIGH" ]]; then
|
||||
cecho " ${RED}[$severity]${NC} $issue_type: $message"
|
||||
fi
|
||||
done <<< "$issues"
|
||||
else
|
||||
cecho " ${GREEN}✓ No critical issues${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done <<< "$user_domains"
|
||||
done <<< "$users"
|
||||
|
||||
# Summary
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
cecho "${WHITE}${BOLD}SUMMARY${NC}"
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
cecho " Total domains analyzed: ${WHITE}$total_domains${NC}"
|
||||
cecho " Domains with issues: ${RED}$domains_with_issues${NC}"
|
||||
cecho " Domains healthy: ${GREEN}$((total_domains - domains_with_issues))${NC}"
|
||||
echo ""
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 3: QUICK HEALTH CHECK
|
||||
# ============================================================================
|
||||
|
||||
quick_health_check() {
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}QUICK HEALTH CHECK${NC}"
|
||||
echo ""
|
||||
|
||||
# Get all users
|
||||
local users
|
||||
users=$(list_all_users)
|
||||
|
||||
declare -A issue_counts
|
||||
issue_counts["CRITICAL"]=0
|
||||
issue_counts["HIGH"]=0
|
||||
issue_counts["MEDIUM"]=0
|
||||
issue_counts["LOW"]=0
|
||||
|
||||
local total_domains=0
|
||||
|
||||
while IFS= read -r username; do
|
||||
local user_domains
|
||||
user_domains=$(get_user_domains "$username")
|
||||
|
||||
while IFS= read -r domain; do
|
||||
[ -z "$domain" ] && continue
|
||||
|
||||
total_domains=$((total_domains + 1))
|
||||
|
||||
# Detect issues
|
||||
local issues
|
||||
issues=$(detect_php_config_issues "$username" "$domain")
|
||||
|
||||
# Count by severity
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ -z "$severity" ] && continue
|
||||
|
||||
issue_counts["$severity"]=$((issue_counts["$severity"] + 1))
|
||||
done <<< "$issues"
|
||||
done <<< "$user_domains"
|
||||
done <<< "$users"
|
||||
|
||||
# Display results
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
cecho "${WHITE}${BOLD}HEALTH CHECK RESULTS${NC}"
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
cecho " Total Domains: ${WHITE}$total_domains${NC}"
|
||||
echo ""
|
||||
cecho " ${RED}CRITICAL${NC} issues: ${issue_counts["CRITICAL"]}"
|
||||
cecho " ${YELLOW}HIGH${NC} issues: ${issue_counts["HIGH"]}"
|
||||
cecho " ${BLUE}MEDIUM${NC} issues: ${issue_counts["MEDIUM"]}"
|
||||
cecho " ${GREEN}LOW${NC} issues: ${issue_counts["LOW"]}"
|
||||
echo ""
|
||||
|
||||
# Overall health score
|
||||
local health_score
|
||||
health_score=$((100 - (issue_counts["CRITICAL"] * 20) - (issue_counts["HIGH"] * 10) - (issue_counts["MEDIUM"] * 5) - (issue_counts["LOW"] * 2)))
|
||||
[ "$health_score" -lt 0 ] && health_score=0
|
||||
|
||||
if [ "$health_score" -ge 90 ]; then
|
||||
cecho " Overall Health: ${GREEN}${BOLD}$health_score/100 - EXCELLENT${NC}"
|
||||
elif [ "$health_score" -ge 70 ]; then
|
||||
cecho " Overall Health: ${YELLOW}${BOLD}$health_score/100 - GOOD${NC}"
|
||||
elif [ "$health_score" -ge 50 ]; then
|
||||
cecho " Overall Health: ${YELLOW}${BOLD}$health_score/100 - FAIR${NC}"
|
||||
else
|
||||
cecho " Overall Health: ${RED}${BOLD}$health_score/100 - POOR${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 4: OPTIMIZE DOMAIN
|
||||
# ============================================================================
|
||||
|
||||
optimize_domain() {
|
||||
show_banner
|
||||
|
||||
local selection
|
||||
selection=$(select_domain "optimize")
|
||||
|
||||
if [ $? -ne 0 ] || [ -z "$selection" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local domain username
|
||||
domain=$(echo "$selection" | cut -d'|' -f1)
|
||||
username=$(echo "$selection" | cut -d'|' -f2)
|
||||
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}OPTIMIZE: ${GREEN}$domain${NC}"
|
||||
echo ""
|
||||
|
||||
# Detect issues
|
||||
cecho "${YELLOW}Detecting issues...${NC}"
|
||||
local issues
|
||||
issues=$(detect_php_config_issues "$username" "$domain")
|
||||
|
||||
# Display issues
|
||||
local has_issues=false
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ -z "$issue_type" ] && continue
|
||||
|
||||
if [ "$issue_type" != "NONE" ]; then
|
||||
has_issues=true
|
||||
|
||||
case "$severity" in
|
||||
CRITICAL)
|
||||
cecho "${RED}[CRITICAL]${NC} $message"
|
||||
;;
|
||||
HIGH)
|
||||
cecho "${YELLOW}[HIGH]${NC} $message"
|
||||
;;
|
||||
MEDIUM)
|
||||
cecho "${BLUE}[MEDIUM]${NC} $message"
|
||||
;;
|
||||
LOW)
|
||||
cecho "${GREEN}[LOW]${NC} $message"
|
||||
;;
|
||||
esac
|
||||
|
||||
cecho " ${CYAN}→${NC} $recommendation"
|
||||
echo ""
|
||||
fi
|
||||
done <<< "$issues"
|
||||
|
||||
if [ "$has_issues" = false ]; then
|
||||
cecho "${GREEN}${BOLD}✓ No issues detected - configuration is optimal!${NC}"
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
# Get optimization recommendations
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
cecho "${WHITE}${BOLD}RECOMMENDED OPTIMIZATIONS${NC}"
|
||||
echo ""
|
||||
|
||||
# Calculate optimal max_children
|
||||
local optimal_result
|
||||
optimal_result=$(calculate_optimal_max_children "$username" 1024)
|
||||
local recommended_max_children reason
|
||||
recommended_max_children=$(echo "$optimal_result" | cut -d'|' -f1)
|
||||
reason=$(echo "$optimal_result" | cut -d'|' -f2)
|
||||
|
||||
# Get current max_children
|
||||
local pool_config
|
||||
pool_config=$(find_fpm_pool_config "$username")
|
||||
|
||||
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
|
||||
local current_max_children
|
||||
current_max_children=$(grep "^pm.max_children" "$pool_config" | awk -F'=' '{print $2}' | tr -d ' ')
|
||||
|
||||
if [ -n "$current_max_children" ] && [ "$recommended_max_children" -ne "$current_max_children" ]; then
|
||||
cecho "${GREEN}1.${NC} Adjust ${BOLD}pm.max_children${NC} from ${RED}$current_max_children${NC} to ${GREEN}$recommended_max_children${NC}"
|
||||
cecho " Reason: $reason"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check OPcache
|
||||
local opcache_status
|
||||
opcache_status=$(analyze_opcache_effectiveness "$username")
|
||||
local status hit_rate opcache_rec
|
||||
status=$(echo "$opcache_status" | cut -d'|' -f1)
|
||||
hit_rate=$(echo "$opcache_status" | cut -d'|' -f2)
|
||||
opcache_rec=$(echo "$opcache_status" | cut -d'|' -f5)
|
||||
|
||||
if [ "$status" = "DISABLED" ]; then
|
||||
cecho "${GREEN}2.${NC} ${BOLD}Enable OPcache${NC} for 40-70% performance boost"
|
||||
echo ""
|
||||
elif (( $(echo "$hit_rate < 90" | bc -l 2>/dev/null || echo "0") )); then
|
||||
cecho "${GREEN}2.${NC} ${BOLD}Increase opcache.memory_consumption${NC} (current hit rate: ${hit_rate}%)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
cecho "${YELLOW}${BOLD}WARNING:${NC} ${YELLOW}Automatic optimization not yet implemented${NC}"
|
||||
cecho "${YELLOW}Please apply the above recommendations manually${NC}"
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 6: VIEW OPCACHE STATISTICS
|
||||
# ============================================================================
|
||||
|
||||
view_opcache_stats() {
|
||||
show_banner
|
||||
|
||||
local selection
|
||||
selection=$(select_domain "opcache")
|
||||
|
||||
if [ $? -ne 0 ] || [ -z "$selection" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local domain username
|
||||
domain=$(echo "$selection" | cut -d'|' -f1)
|
||||
username=$(echo "$selection" | cut -d'|' -f2)
|
||||
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}OPCACHE STATISTICS: ${GREEN}$domain${NC}"
|
||||
echo ""
|
||||
|
||||
# Get OPcache stats
|
||||
local stats
|
||||
stats=$(get_opcache_stats "$username")
|
||||
|
||||
if [ -z "$stats" ]; then
|
||||
cecho "${RED}Unable to retrieve OPcache statistics${NC}"
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
# Parse and display
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
cecho "${WHITE}${BOLD}OPCACHE STATUS${NC}"
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
local enabled
|
||||
enabled=$(check_opcache_enabled "$username")
|
||||
|
||||
if [ "$enabled" = "1" ]; then
|
||||
cecho " Status: ${GREEN}ENABLED${NC}"
|
||||
else
|
||||
cecho " Status: ${RED}DISABLED${NC}"
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
# Display stats
|
||||
while IFS='=' read -r key value; do
|
||||
[ -z "$key" ] && continue
|
||||
|
||||
case "$key" in
|
||||
memory_usage_mb)
|
||||
cecho " Memory Used: ${WHITE}${value}MB${NC}"
|
||||
;;
|
||||
hits)
|
||||
cecho " Cache Hits: ${GREEN}$value${NC}"
|
||||
;;
|
||||
misses)
|
||||
cecho " Cache Misses: ${YELLOW}$value${NC}"
|
||||
;;
|
||||
num_cached_scripts)
|
||||
cecho " Cached Scripts: ${WHITE}$value${NC}"
|
||||
;;
|
||||
max_cached_keys)
|
||||
cecho " Max Cached Keys: ${WHITE}$value${NC}"
|
||||
;;
|
||||
wasted_memory_mb)
|
||||
cecho " Wasted Memory: ${RED}${value}MB${NC}"
|
||||
;;
|
||||
esac
|
||||
done <<< "$stats"
|
||||
|
||||
# Calculate and display hit rate
|
||||
local hit_rate
|
||||
hit_rate=$(calculate_opcache_hit_rate "$username")
|
||||
echo ""
|
||||
cecho " Hit Rate: ${GREEN}${BOLD}${hit_rate}%${NC}"
|
||||
|
||||
# Recommendation
|
||||
echo ""
|
||||
if (( $(echo "$hit_rate < 90" | bc -l 2>/dev/null || echo "0") )); then
|
||||
cecho " ${YELLOW}⚠ Hit rate below 90% - Consider increasing opcache.memory_consumption${NC}"
|
||||
else
|
||||
cecho " ${GREEN}✓ Hit rate is excellent${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 7: VIEW PHP-FPM PROCESS STATS
|
||||
# ============================================================================
|
||||
|
||||
view_fpm_stats() {
|
||||
show_banner
|
||||
|
||||
local selection
|
||||
selection=$(select_domain "fpm")
|
||||
|
||||
if [ $? -ne 0 ] || [ -z "$selection" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local domain username
|
||||
domain=$(echo "$selection" | cut -d'|' -f1)
|
||||
username=$(echo "$selection" | cut -d'|' -f2)
|
||||
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}PHP-FPM PROCESS STATISTICS: ${GREEN}$domain${NC}"
|
||||
echo ""
|
||||
|
||||
# Get process stats
|
||||
local memory_stats
|
||||
memory_stats=$(calculate_memory_per_process "$username")
|
||||
|
||||
local avg_kb process_count total_mb
|
||||
avg_kb=$(echo "$memory_stats" | cut -d'|' -f1)
|
||||
process_count=$(echo "$memory_stats" | cut -d'|' -f2)
|
||||
total_mb=$(echo "$memory_stats" | cut -d'|' -f3)
|
||||
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
cecho "${WHITE}${BOLD}CURRENT RESOURCE USAGE${NC}"
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
if [ "$process_count" -eq 0 ]; then
|
||||
cecho "${YELLOW}No active PHP-FPM processes found${NC}"
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
return
|
||||
fi
|
||||
|
||||
cecho " Active Processes: ${WHITE}$process_count${NC}"
|
||||
cecho " Avg Memory/Process: ${WHITE}$((avg_kb / 1024))MB${NC} (${avg_kb}KB)"
|
||||
cecho " Total Memory: ${WHITE}${total_mb}MB${NC}"
|
||||
echo ""
|
||||
|
||||
# Get pool config
|
||||
local pool_config
|
||||
pool_config=$(find_fpm_pool_config "$username")
|
||||
|
||||
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
cecho "${WHITE}${BOLD}POOL CONFIGURATION${NC}"
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
|
||||
local pool_settings
|
||||
pool_settings=$(parse_fpm_pool_config "$pool_config")
|
||||
|
||||
# Display key settings
|
||||
while IFS='=' read -r key value; do
|
||||
[ -z "$key" ] && continue
|
||||
cecho " $key: ${WHITE}$value${NC}"
|
||||
done <<< "$pool_settings"
|
||||
fi
|
||||
|
||||
# Calculate optimal max_children
|
||||
echo ""
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
cecho "${WHITE}${BOLD}RECOMMENDATION${NC}"
|
||||
cecho "${CYAN}─────────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
|
||||
local optimal_result
|
||||
optimal_result=$(calculate_optimal_max_children "$username" 1024)
|
||||
local recommended reason
|
||||
recommended=$(echo "$optimal_result" | cut -d'|' -f1)
|
||||
reason=$(echo "$optimal_result" | cut -d'|' -f2)
|
||||
|
||||
cecho " Optimal pm.max_children: ${GREEN}${BOLD}$recommended${NC}"
|
||||
cecho " Reason: $reason"
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════${NC}"
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OPTION 8: CHECK FOR ISSUES
|
||||
# ============================================================================
|
||||
|
||||
check_config_issues() {
|
||||
show_banner
|
||||
|
||||
local selection
|
||||
selection=$(select_domain "check")
|
||||
|
||||
if [ $? -ne 0 ] || [ -z "$selection" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local domain username
|
||||
domain=$(echo "$selection" | cut -d'|' -f1)
|
||||
username=$(echo "$selection" | cut -d'|' -f2)
|
||||
|
||||
show_banner
|
||||
cecho "${WHITE}${BOLD}CONFIGURATION ISSUES: ${GREEN}$domain${NC}"
|
||||
echo ""
|
||||
|
||||
# Detect issues
|
||||
local issues
|
||||
issues=$(detect_php_config_issues "$username" "$domain")
|
||||
|
||||
# Display by severity
|
||||
local has_critical=false
|
||||
local has_high=false
|
||||
local has_medium=false
|
||||
local has_low=false
|
||||
|
||||
# Check for each severity level
|
||||
echo "$issues" | grep -q "CRITICAL" && has_critical=true
|
||||
echo "$issues" | grep -q "HIGH" && has_high=true
|
||||
echo "$issues" | grep -q "MEDIUM" && has_medium=true
|
||||
echo "$issues" | grep -q "LOW" && has_low=true
|
||||
|
||||
# Display CRITICAL
|
||||
if [ "$has_critical" = true ]; then
|
||||
cecho "${RED}${BOLD}CRITICAL ISSUES:${NC}"
|
||||
echo ""
|
||||
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ "$severity" != "CRITICAL" ] && continue
|
||||
|
||||
cecho " ${RED}●${NC} $message"
|
||||
cecho " ${CYAN}→${NC} $recommendation"
|
||||
echo ""
|
||||
done <<< "$issues"
|
||||
fi
|
||||
|
||||
# Display HIGH
|
||||
if [ "$has_high" = true ]; then
|
||||
cecho "${YELLOW}${BOLD}HIGH PRIORITY ISSUES:${NC}"
|
||||
echo ""
|
||||
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ "$severity" != "HIGH" ] && continue
|
||||
|
||||
cecho " ${YELLOW}●${NC} $message"
|
||||
cecho " ${CYAN}→${NC} $recommendation"
|
||||
echo ""
|
||||
done <<< "$issues"
|
||||
fi
|
||||
|
||||
# Display MEDIUM
|
||||
if [ "$has_medium" = true ]; then
|
||||
cecho "${BLUE}${BOLD}MEDIUM PRIORITY ISSUES:${NC}"
|
||||
echo ""
|
||||
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ "$severity" != "MEDIUM" ] && continue
|
||||
|
||||
cecho " ${BLUE}●${NC} $message"
|
||||
cecho " ${CYAN}→${NC} $recommendation"
|
||||
echo ""
|
||||
done <<< "$issues"
|
||||
fi
|
||||
|
||||
# Display LOW
|
||||
if [ "$has_low" = true ]; then
|
||||
cecho "${GREEN}${BOLD}LOW PRIORITY ISSUES:${NC}"
|
||||
echo ""
|
||||
|
||||
while IFS='|' read -r issue_type severity message recommendation; do
|
||||
[ "$severity" != "LOW" ] && continue
|
||||
|
||||
cecho " ${GREEN}●${NC} $message"
|
||||
cecho " ${CYAN}→${NC} $recommendation"
|
||||
echo ""
|
||||
done <<< "$issues"
|
||||
fi
|
||||
|
||||
# No issues
|
||||
if [ "$has_critical" = false ] && [ "$has_high" = false ] && [ "$has_medium" = false ] && [ "$has_low" = false ]; then
|
||||
cecho "${GREEN}${BOLD}✓ No configuration issues detected!${NC}"
|
||||
cecho "${GREEN}Configuration appears to be optimal.${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
read -p "Press Enter to continue..."
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# MAIN LOOP
|
||||
# ============================================================================
|
||||
|
||||
main() {
|
||||
# Detect system
|
||||
detect_system
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
cecho "${RED}ERROR: This script must be run as root${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for PHP-FPM
|
||||
if ! is_using_php_fpm; then
|
||||
cecho "${YELLOW}WARNING: PHP-FPM not detected. Some features may not work.${NC}"
|
||||
read -p "Press Enter to continue anyway..."
|
||||
fi
|
||||
|
||||
# Main loop
|
||||
while true; do
|
||||
show_banner
|
||||
show_main_menu
|
||||
|
||||
read -p "Select option: " choice
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
analyze_single_domain
|
||||
;;
|
||||
2)
|
||||
analyze_all_domains
|
||||
;;
|
||||
3)
|
||||
quick_health_check
|
||||
;;
|
||||
4)
|
||||
optimize_domain
|
||||
;;
|
||||
5)
|
||||
cecho "${YELLOW}Server-wide optimization not yet implemented${NC}"
|
||||
sleep 2
|
||||
;;
|
||||
6)
|
||||
view_opcache_stats
|
||||
;;
|
||||
7)
|
||||
view_fpm_stats
|
||||
;;
|
||||
8)
|
||||
check_config_issues
|
||||
;;
|
||||
b)
|
||||
cecho "${YELLOW}Backup feature not yet implemented${NC}"
|
||||
sleep 2
|
||||
;;
|
||||
r)
|
||||
cecho "${YELLOW}Restore feature not yet implemented${NC}"
|
||||
sleep 2
|
||||
;;
|
||||
q|Q)
|
||||
cecho "${GREEN}Exiting PHP Optimizer...${NC}"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
cecho "${RED}Invalid option${NC}"
|
||||
sleep 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Run main
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user