Complete profile-based PHP-FPM optimization system with real usage data
Implement data-driven optimization using actual server metrics instead of thresholds: NEW FEATURES: - lib/php-analytics.sh: Analytics engine for domain profiling • analyze_memory_errors_from_logs: Parse error logs for memory exhaustion • analyze_process_memory_usage: Measure actual PHP process memory via ps • get_peak_concurrent_detailed: Extract peak concurrent requests from access logs • detect_memory_leak_pattern: Identify domains with memory leak issues • build_domain_profile: Complete profile with all real usage data • Intelligent recommendations based on ACTUAL peak memory, traffic, and leak patterns - modules/performance/php-domain-analyzer.sh: Pre-analysis script • Scans all domains and builds comprehensive profiles • Stores profiles in /tmp/php-domain-profiles/ for use by optimizer • Shows summary with top memory users, traffic patterns, and potential leaks • Displays analysis in real-time with progress indicators - php-optimizer.sh: Profile-based optimization levels • Option 0: Run pre-analysis to collect real usage data • Levels 1-5: Now use profile-based recommendations (fallback to traffic-based if no profiles) • Shows real usage data from profiles when optimizations applied • Memory recommendations: peak_memory_seen + 20% buffer • Max children: peak_concurrent_requests + 30% safety margin • Max requests: 250 for leak-prone domains, 500 for normal domains ARCHITECTURE: - Profile format (pipe-delimited): domain|username|peak_concurrent|avg_concurrent| total_hits|min_mem|max_mem|avg_mem|proc_count|mem_exhausted|peak_mem_seen| leak_type|current_memory_limit|current_max_children - Profiles cached in /tmp/php-domain-profiles/ (24 hour TTL) - All 5 optimization levels now profile-aware - Seamless fallback to traffic-based method if no profiles exist CONVERSION COMPLETED: - Level 1: Optimizes pm.max_children only (profile-aware) - Level 2: pm.max_children + memory_limit (profile-aware) - Level 3: All of above + pm.max_requests for leak prevention (profile-aware) - Level 4: OPcache optimization (unchanged) - Level 5: Complete optimization with all settings (NOW PROFILE-AWARE - FIXED) All levels now enumeraate users/domains directly and use profile recommendations when available, with intelligent fallback to the original traffic-based method. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Executable
+146
@@ -0,0 +1,146 @@
|
||||
#!/bin/bash
|
||||
# PHP Domain Analyzer - Collect real usage data for true optimization
|
||||
# Run this before optimization to build accurate domain profiles
|
||||
# Uses actual logs and process data instead of thresholds
|
||||
|
||||
# Source required libraries
|
||||
PHP_TOOLKIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../.. && pwd)"
|
||||
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-analytics.sh" 2>/dev/null || { echo "ERROR: php-analytics.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 "$@"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# MAIN ANALYSIS
|
||||
# ============================================================================
|
||||
|
||||
initialize_system_detection
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
cecho "${RED}ERROR: This script must be run as root${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cecho "${CYAN}╔════════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
cecho "${CYAN}║${WHITE} PHP DOMAIN ANALYZER - REAL USAGE DATA COLLECTION ${CYAN}║${NC}"
|
||||
cecho "${CYAN}╚════════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
cecho "${WHITE}${BOLD}Starting Analysis...${NC}"
|
||||
cecho "${CYAN}This may take a few minutes. Analyzing logs, processes, and traffic patterns.${NC}"
|
||||
echo ""
|
||||
|
||||
# Get all users and domains
|
||||
users=$(list_all_users)
|
||||
|
||||
declare -a all_profiles
|
||||
total_domains=0
|
||||
analyzed=0
|
||||
|
||||
cecho "${YELLOW}Analyzing domains...${NC}"
|
||||
echo ""
|
||||
|
||||
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))
|
||||
|
||||
cecho -n " [$total_domains] Analyzing $domain..."
|
||||
|
||||
# Build profile with actual data
|
||||
profile=$(build_domain_profile "$username" "$domain")
|
||||
|
||||
if [ -n "$profile" ]; then
|
||||
all_profiles+=("$profile")
|
||||
store_domain_profile "$profile"
|
||||
analyzed=$((analyzed + 1))
|
||||
|
||||
# Extract key metrics
|
||||
peak_concurrent=$(echo "$profile" | cut -d'|' -f3)
|
||||
peak_mem=$(echo "$profile" | cut -d'|' -f11)
|
||||
leak_status=$(echo "$profile" | cut -d'|' -f12)
|
||||
|
||||
cecho "${GREEN} ✓${NC}"
|
||||
cecho " Peak: $peak_concurrent concurrent | Memory: ${peak_mem}MB | Leak: $leak_status"
|
||||
else
|
||||
cecho "${YELLOW} ✗${NC} (could not collect data)"
|
||||
fi
|
||||
done <<< "$user_domains"
|
||||
done <<< "$users"
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════════════${NC}"
|
||||
cecho "${WHITE}${BOLD}ANALYSIS COMPLETE${NC}"
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
cecho " Total domains analyzed: ${WHITE}${analyzed}${NC} / ${total_domains}"
|
||||
cecho " Profiles stored in: ${WHITE}/tmp/php-domain-profiles/${NC}"
|
||||
echo ""
|
||||
|
||||
# Display summary
|
||||
if [ "${#all_profiles[@]}" -gt 0 ]; then
|
||||
cecho "${CYAN}ANALYSIS SUMMARY:${NC}"
|
||||
echo ""
|
||||
|
||||
# Find domains with highest memory usage
|
||||
cecho "${WHITE}${BOLD}Top Memory Usage:${NC}"
|
||||
printf '%s\n' "${all_profiles[@]}" | sort -t'|' -k11 -rn | head -5 | while IFS='|' read -r domain username peak_concurrent avg_concurrent total_hits min_mem max_mem avg_mem proc_count mem_exhausted peak_mem leak rest; do
|
||||
cecho " • $domain: ${peak_mem}MB peak memory"
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# Find domains with highest traffic
|
||||
cecho "${WHITE}${BOLD}Top Traffic:${NC}"
|
||||
printf '%s\n' "${all_profiles[@]}" | sort -t'|' -k3 -rn | head -5 | while IFS='|' read -r domain username peak_concurrent avg_concurrent total_hits rest; do
|
||||
cecho " • $domain: $peak_concurrent concurrent requests"
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# Find domains with potential leaks
|
||||
leak_count=$(printf '%s\n' "${all_profiles[@]}" | \grep -c "LIKELY_LEAK")
|
||||
if [ "$leak_count" -gt 0 ]; then
|
||||
cecho "${RED}${BOLD}⚠ Domains with potential memory leaks:${NC} $leak_count"
|
||||
printf '%s\n' "${all_profiles[@]}" | \grep "LIKELY_LEAK" | while IFS='|' read -r domain username rest; do
|
||||
cecho " • $domain"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Show high memory usage domains
|
||||
high_mem=$(printf '%s\n' "${all_profiles[@]}" | awk -F'|' '$11 > 200 {print}' | wc -l)
|
||||
if [ "$high_mem" -gt 0 ]; then
|
||||
cecho "${YELLOW}${BOLD}Domains using >200MB:${NC} $high_mem"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
cecho "${CYAN}═══════════════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
cecho "${GREEN}${BOLD}✓ Domain profiles ready for optimization!${NC}"
|
||||
echo ""
|
||||
cecho "Next step: Run php-optimizer.sh → Option 5 → Select optimization level"
|
||||
cecho "The optimizer will now use REAL usage data for accurate recommendations."
|
||||
echo ""
|
||||
Reference in New Issue
Block a user