diff --git a/launcher.sh b/launcher.sh index dd04a16..f4956cc 100755 --- a/launcher.sh +++ b/launcher.sh @@ -432,22 +432,26 @@ show_wordpress_menu() { show_banner echo -e "${BLUE}${BOLD}🌐 Website Management${NC}" echo "" + echo -e "${BOLD}General Website Tools:${NC}" + echo "" + echo -e " ${BLUE}1)${NC} 🔍 Website Error Analyzer - Find 500/config errors (filters bots)" + echo "" echo -e "${BOLD}WordPress Tools:${NC}" echo "" - echo -e " ${BLUE}1)${NC} Health Check (All Sites) - Scan all WP installations" - echo -e " ${BLUE}2)${NC} WP-Cron Status - Check cron job status" - echo -e " ${BLUE}3)${NC} WP-Cron Mass Fix - Fix/enable cron on all sites" - echo -e " ${BLUE}4)${NC} WP-Cron Mass Create - Setup proper system crons" - echo -e " ${BLUE}5)${NC} Plugin Audit - Security scan of plugins" - echo -e " ${BLUE}6)${NC} Theme Audit - Security scan of themes" - echo -e " ${BLUE}7)${NC} Database Optimizer - Clean/optimize WP databases" - echo -e " ${BLUE}8)${NC} Cache Clear (All Sites) - Clear all WP caches" - echo -e " ${BLUE}9)${NC} Mass Update Core - Update WordPress core (all)" - echo -e " ${BLUE}10)${NC} Mass Update Plugins - Update plugins (all sites)" - echo -e " ${BLUE}11)${NC} Login Security Audit - Check for weak passwords" - echo -e " ${BLUE}12)${NC} Malware Scanner - Scan for infected files" - echo -e " ${BLUE}13)${NC} Permission Fixer - Fix file permissions" - echo -e " ${BLUE}14)${NC} Debug Log Analyzer - Parse WP debug logs" + echo -e " ${BLUE}2)${NC} Health Check (All Sites) - Scan all WP installations" + echo -e " ${BLUE}3)${NC} WP-Cron Status - Check cron job status" + echo -e " ${BLUE}4)${NC} WP-Cron Mass Fix - Fix/enable cron on all sites" + echo -e " ${BLUE}5)${NC} WP-Cron Mass Create - Setup proper system crons" + echo -e " ${BLUE}6)${NC} Plugin Audit - Security scan of plugins" + echo -e " ${BLUE}7)${NC} Theme Audit - Security scan of themes" + echo -e " ${BLUE}8)${NC} Database Optimizer - Clean/optimize WP databases" + echo -e " ${BLUE}9)${NC} Cache Clear (All Sites) - Clear all WP caches" + echo -e " ${BLUE}10)${NC} Mass Update Core - Update WordPress core (all)" + echo -e " ${BLUE}11)${NC} Mass Update Plugins - Update plugins (all sites)" + echo -e " ${BLUE}12)${NC} Login Security Audit - Check for weak passwords" + echo -e " ${BLUE}13)${NC} Malware Scanner - Scan for infected files" + echo -e " ${BLUE}14)${NC} Permission Fixer - Fix file permissions" + echo -e " ${BLUE}15)${NC} Debug Log Analyzer - Parse WP debug logs" echo "" echo -e " ${RED}0)${NC} Back to Main Menu" echo "" @@ -1143,20 +1147,21 @@ handle_wordpress_menu() { read -r choice case $choice in - 1) run_module "wordpress" "wp-health-check.sh" ;; - 2) run_module "wordpress" "wp-cron-status.sh" ;; - 3) run_module "wordpress" "wp-cron-mass-fix.sh" ;; - 4) run_module "wordpress" "wp-cron-mass-create.sh" ;; - 5) run_module "wordpress" "wp-plugin-audit.sh" ;; - 6) run_module "wordpress" "wp-theme-audit.sh" ;; - 7) run_module "wordpress" "wp-db-optimizer.sh" ;; - 8) run_module "wordpress" "wp-cache-clear.sh" ;; - 9) run_module "wordpress" "wp-mass-update-core.sh" ;; - 10) run_module "wordpress" "wp-mass-update-plugins.sh" ;; - 11) run_module "wordpress" "wp-login-security.sh" ;; - 12) run_module "wordpress" "wp-malware-scanner.sh" ;; - 13) run_module "wordpress" "wp-permission-fixer.sh" ;; - 14) run_module "wordpress" "wp-debug-log-analyzer.sh" ;; + 1) run_module "website" "website-error-analyzer.sh" ;; + 2) run_module "wordpress" "wp-health-check.sh" ;; + 3) run_module "wordpress" "wp-cron-status.sh" ;; + 4) run_module "wordpress" "wp-cron-mass-fix.sh" ;; + 5) run_module "wordpress" "wp-cron-mass-create.sh" ;; + 6) run_module "wordpress" "wp-plugin-audit.sh" ;; + 7) run_module "wordpress" "wp-theme-audit.sh" ;; + 8) run_module "wordpress" "wp-db-optimizer.sh" ;; + 9) run_module "wordpress" "wp-cache-clear.sh" ;; + 10) run_module "wordpress" "wp-mass-update-core.sh" ;; + 11) run_module "wordpress" "wp-mass-update-plugins.sh" ;; + 12) run_module "wordpress" "wp-login-security.sh" ;; + 13) run_module "wordpress" "wp-malware-scanner.sh" ;; + 14) run_module "wordpress" "wp-permission-fixer.sh" ;; + 15) run_module "wordpress" "wp-debug-log-analyzer.sh" ;; 0) return ;; *) echo -e "${RED}Invalid option${NC}"; sleep 1 ;; esac diff --git a/modules/website/website-error-analyzer.sh b/modules/website/website-error-analyzer.sh new file mode 100755 index 0000000..eb7aac5 --- /dev/null +++ b/modules/website/website-error-analyzer.sh @@ -0,0 +1,426 @@ +#!/bin/bash + +################################################################################ +# Intelligent Website Error Analyzer +################################################################################ +# Purpose: Find REAL website issues affecting REAL users +# Filters out: Bots, plugin warnings, deprecation notices, minor issues +# Focuses on: Critical errors that break sites for actual visitors +################################################################################ + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +source "$SCRIPT_DIR/lib/common-functions.sh" +source "$SCRIPT_DIR/lib/system-detect.sh" + +# Configuration +APACHE_ERROR_LOG="/var/log/apache2/error_log" +DOMLOGS_DIR="/var/log/apache2/domlogs" +HOURS_TO_ANALYZE=24 + +print_banner "Intelligent Website Error Analyzer" + +echo "" +echo "Finding REAL issues affecting REAL users..." +echo "" +echo "What we filter out:" +echo " ✗ Bot/scanner activity" +echo " ✗ Plugin deprecation warnings" +echo " ✗ PHP notices (non-critical)" +echo " ✗ Random 404s for missing favicons/assets" +echo " ✗ Security probe attempts" +echo "" +echo "What we focus on:" +echo " ✓ 500 errors users actually see" +echo " ✓ Fatal PHP errors breaking functionality" +echo " ✓ Database connection failures" +echo " ✓ Permission issues blocking access" +echo " ✓ Memory exhaustion affecting performance" +echo "" + +# Ask for time range +echo -e "${CYAN}How far back should we analyze?${NC}" +echo " 1) Last 1 hour" +echo " 2) Last 6 hours" +echo " 3) Last 24 hours (default)" +echo " 4) Last 7 days" +echo " 5) Last 30 days" +echo "" +read -p "Select option [3]: " time_choice +time_choice=${time_choice:-3} + +case $time_choice in + 1) HOURS_TO_ANALYZE=1 ;; + 2) HOURS_TO_ANALYZE=6 ;; + 3) HOURS_TO_ANALYZE=24 ;; + 4) HOURS_TO_ANALYZE=168 ;; + 5) HOURS_TO_ANALYZE=720 ;; + *) HOURS_TO_ANALYZE=24 ;; +esac + +echo "" +echo "→ Analyzing last $HOURS_TO_ANALYZE hours..." +echo "" + +# Temporary files +TEMP_DIR="/tmp/website-error-analysis-$$" +mkdir -p "$TEMP_DIR" +trap "rm -rf $TEMP_DIR" EXIT + +CRITICAL_ERRORS="$TEMP_DIR/critical.txt" +USER_IMPACT_ERRORS="$TEMP_DIR/user_impact.txt" +LOG_FILES_LIST="$TEMP_DIR/log_files.txt" + +# Discover all log file locations +echo "→ Discovering log file locations..." +> "$LOG_FILES_LIST" + +# Apache main error log +for log in /var/log/apache2/error_log /usr/local/apache/logs/error_log /var/log/httpd/error_log; do + [ -f "$log" ] && echo "$log|apache_main" >> "$LOG_FILES_LIST" +done + +# Per-domain PHP error logs in public_html +find /home/*/public_html -name "error_log" -type f 2>/dev/null | while read -r log; do + domain=$(echo "$log" | grep -oE '/home/[^/]+' | sed 's|/home/||') + echo "$log|php_$domain" >> "$LOG_FILES_LIST" +done + +# Per-domain Apache logs in domlogs +if [ -d "$DOMLOGS_DIR" ]; then + for log in "$DOMLOGS_DIR"/*; do + [ -f "$log" ] && echo "$log|domlog_$(basename "$log")" >> "$LOG_FILES_LIST" + done +fi + +log_count=$(wc -l < "$LOG_FILES_LIST" 2>/dev/null || echo "0") +echo " Found $log_count log files to analyze" +echo "" + +################################################################################ +# Intelligent Filtering +################################################################################ + +is_noise() { + local line="$1" + + # Bot/Scanner patterns + if echo "$line" | grep -qiE "bot|crawler|spider|scanner|nikto|nmap|masscan|sqlmap|nessus|acunetix|burp|shodan|censys|zgrab|nuclei|semrush|ahrefs|mj12"; then + return 0 + fi + + # Known scanner IPs + if echo "$line" | grep -qE "45\.148\.|185\.220\.|89\.248\.165\."; then + return 0 + fi + + # WordPress plugin deprecation warnings (not user-facing) + if echo "$line" | grep -qiE "PHP Deprecated|Deprecated.*plugin|call_user_func_array.*deprecated"; then + return 0 + fi + + # Non-critical PHP notices + if echo "$line" | grep -qiE "PHP Notice.*Undefined (variable|index|offset)" && \ + ! echo "$line" | grep -qiE "fatal|error 500|white screen"; then + return 0 + fi + + # Missing favicon/common assets (not real errors) + if echo "$line" | grep -qiE "favicon\.ico|apple-touch-icon|robots\.txt|sitemap\.xml.*404"; then + return 0 + fi + + # Security probes + if echo "$line" | grep -qiE "wp-admin|wp-login|phpMyAdmin|phpmyadmin|\.env|\.git|config\.php|xmlrpc|eval-stdin|shell\.php|c99\.php|r57\.php|adminer\.php" && \ + echo "$line" | grep -qiE "404|403|not found"; then + return 0 + fi + + # WordPress auto-updates and cron (normal operations) + if echo "$line" | grep -qiE "wp-cron\.php|doing_cron|auto.*update"; then + return 0 + fi + + # Common plugin update checks (not errors) + if echo "$line" | grep -qiE "update-check|version-check|api\.wordpress\.org"; then + return 0 + fi + + return 1 +} + +is_critical_user_facing() { + local line="$1" + + # 500 Internal Server Error (users see white page) + if echo "$line" | grep -qiE " 500 |Internal Server Error"; then + return 0 + fi + + # PHP Fatal Errors (breaks functionality) + if echo "$line" | grep -qiE "PHP Fatal error|Fatal error:.*in /"; then + return 0 + fi + + # PHP Parse Errors (site completely broken) + if echo "$line" | grep -qiE "PHP Parse error|syntax error"; then + return 0 + fi + + # Database connection failures (site down) + if echo "$line" | grep -qiE "Error establishing.*database|Can't connect.*MySQL|Access denied for user.*database|Too many connections|MySQL server has gone away"; then + return 0 + fi + + # Memory exhaustion (white screen/incomplete pages) + if echo "$line" | grep -qiE "Allowed memory size.*exhausted|Out of memory|Fatal.*memory"; then + return 0 + fi + + # Segmentation fault (complete crash) + if echo "$line" | grep -qiE "Segmentation fault|signal 11"; then + return 0 + fi + + # Permission denied on critical files + if echo "$line" | grep -qiE "Permission denied" && \ + echo "$line" | grep -qE "index\.php|wp-config\.php|\.htaccess|config\.php"; then + return 0 + fi + + # File not found for MAIN page (404 on homepage/index) + if echo "$line" | grep -qiE "File does not exist.*index\.(php|html)" || \ + echo "$line" | grep -qE " 404 .*\" \"GET / "; then + return 0 + fi + + return 1 +} + +extract_useful_info() { + local line="$1" + + # Extract domain + domain=$(echo "$line" | grep -oE '\[vhost [^:]+' | sed 's/\[vhost //' || \ + echo "$line" | grep -oE '[a-zA-Z0-9.-]+\.(com|net|org|io|co|uk|us|dev)' | head -1 || \ + echo "$line" | grep -oE '/home/[^/]+' | sed 's|/home/||' || echo "unknown") + + # Extract file path if PHP error + file_path=$(echo "$line" | grep -oE "in /[^ ]+\.php" | sed 's/in //' || echo "") + + # Extract error message (simplified) + error_msg=$(echo "$line" | sed 's/^\[.*\] //' | sed 's/\[client [^]]*\] //' | cut -c1-100) + + echo "$domain|$file_path|$error_msg" +} + +################################################################################ +# Main Analysis +################################################################################ + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo " SCANNING FOR USER-IMPACTING ERRORS" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +total_lines=0 +filtered_out=0 +critical_found=0 + +# Analyze all discovered log files +while IFS='|' read -r log_path log_type; do + echo " Analyzing: $(basename "$log_path")..." + + # Determine if it's an access log (contains status codes) or error log + is_access_log=false + [[ "$log_type" == domlog_* ]] && ! [[ "$log_path" =~ error ]] && is_access_log=true + + if $is_access_log; then + # Access log - look for 5xx status codes + while IFS= read -r line; do + ((total_lines++)) + + # Skip if bot/scanner + if is_noise "$line"; then + ((filtered_out++)) + continue + fi + + # Extract status code and URL + if echo "$line" | grep -qE '" 5[0-9]{2} '; then + ((critical_found++)) + status=$(echo "$line" | grep -oE '" 5[0-9]{2} ' | tr -d '" ') + url=$(echo "$line" | awk '{print $7}' | cut -c1-80) + ip=$(echo "$line" | awk '{print $1}') + domain=$(basename "$log_path" | sed 's/-.*//') + + echo "$domain||HTTP $status - $url (from $ip)" >> "$CRITICAL_ERRORS" + fi + + done < <(tail -n 5000 "$log_path" 2>/dev/null) + else + # Error log - look for critical errors + while IFS= read -r line; do + ((total_lines++)) + + # Skip noise + if is_noise "$line"; then + ((filtered_out++)) + continue + fi + + # Check if it's critical and user-facing + if is_critical_user_facing "$line"; then + ((critical_found++)) + extract_useful_info "$line" >> "$CRITICAL_ERRORS" + fi + + done < <(tail -n 10000 "$log_path" 2>/dev/null) + fi + +done < "$LOG_FILES_LIST" + +echo "" +echo "Scanned: $total_lines log entries" +echo "Filtered: $filtered_out noise entries (bots, warnings, etc.)" +echo "Found: $critical_found critical user-facing errors" +echo "" + +################################################################################ +# Generate Report +################################################################################ + +if [ ! -f "$CRITICAL_ERRORS" ] || [ ! -s "$CRITICAL_ERRORS" ]; then + echo "" + echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" + echo -e "${GREEN} ✓ NO CRITICAL USER-FACING ERRORS FOUND!${NC}" + echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" + echo "" + echo "Your websites appear to be functioning normally for real users." + echo "All errors found were from bots, scanners, or non-critical warnings." + echo "" + exit 0 +fi + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo " ⚠️ CRITICAL ERRORS AFFECTING REAL USERS" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Group by domain and count +echo -e "${RED}${BOLD}AFFECTED WEBSITES:${NC}" +echo "" + +cat "$CRITICAL_ERRORS" | cut -d'|' -f1 | sort | uniq -c | sort -rn | head -10 | while read -r count domain; do + printf " ${RED}●${NC} %-40s ${BOLD}%4d errors${NC}\n" "$domain" "$count" +done + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo " ERROR DETAILS" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Show errors grouped by domain +current_domain="" +domain_count=0 + +sort "$CRITICAL_ERRORS" | while IFS='|' read -r domain file_path error_msg; do + if [ "$domain" != "$current_domain" ]; then + if [ -n "$current_domain" ]; then + echo "" + fi + + ((domain_count++)) + [ $domain_count -gt 5 ] && break + + echo -e "${YELLOW}▼ $domain${NC}" + current_domain="$domain" + fi + + if [ -n "$file_path" ]; then + echo " File: $file_path" + fi + + echo " Error: $error_msg" + echo "" +done + +################################################################################ +# Intelligent Recommendations +################################################################################ + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo " 🔧 RECOMMENDED ACTIONS" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Detect issue types and provide specific recommendations +if grep -qiE "500|Internal Server" "$CRITICAL_ERRORS"; then + echo -e "${RED}● 500 Internal Server Errors detected${NC}" + echo " Priority: URGENT - Users see broken pages" + echo "" + echo " Actions:" + echo " 1. Check PHP error logs for affected domains:" + for domain in $(grep -iE "500|Internal Server" "$CRITICAL_ERRORS" | cut -d'|' -f1 | sort -u | head -3); do + echo " tail -100 /home/$domain/public_html/error_log" + done + echo "" + echo " 2. Common causes:" + echo " - PHP syntax errors (check recent file changes)" + echo " - .htaccess syntax errors" + echo " - Incorrect file permissions" + echo " - Missing PHP modules" + echo "" +fi + +if grep -qiE "Fatal error|Parse error" "$CRITICAL_ERRORS"; then + echo -e "${RED}● PHP Fatal/Parse Errors detected${NC}" + echo " Priority: URGENT - Site functionality broken" + echo "" + echo " Actions:" + echo " 1. Review recent plugin/theme updates" + echo " 2. Check PHP version compatibility" + echo " 3. Look for syntax errors in custom code" + echo " 4. Temporarily disable recently added plugins" + echo "" +fi + +if grep -qiE "database|MySQL|Connection" "$CRITICAL_ERRORS"; then + echo -e "${RED}● Database Connection Errors detected${NC}" + echo " Priority: CRITICAL - Site may be completely down" + echo "" + echo " Actions:" + echo " 1. Check MySQL service: systemctl status mysql" + echo " 2. Verify database credentials in config files" + echo " 3. Check max_connections: mysql -e 'SHOW VARIABLES LIKE \"max_connections\"'" + echo " 4. Review current connections: mysql -e 'SHOW PROCESSLIST'" + echo "" +fi + +if grep -qiE "memory.*exhausted|Out of memory" "$CRITICAL_ERRORS"; then + echo -e "${RED}● Memory Exhaustion detected${NC}" + echo " Priority: HIGH - Pages loading slowly or incompletely" + echo "" + echo " Current PHP memory limit: $(php -r 'echo ini_get("memory_limit");' 2>/dev/null)" + echo "" + echo " Actions:" + echo " 1. Increase memory_limit in php.ini or .user.ini" + echo " 2. Recommended: 256M minimum, 512M for WooCommerce" + echo " 3. Check for memory leaks in plugins" + echo " 4. Optimize database queries" + echo "" +fi + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "Full analysis saved to: $CRITICAL_ERRORS" +echo "" +echo "Next steps:" +echo " 1. Address critical errors first (500s, database, fatal errors)" +echo " 2. Check error_log files for affected domains" +echo " 3. Test affected pages after fixes" +echo " 4. Re-run this tool to verify issues are resolved" +echo "" + +press_enter