Add Fast 500 Error Tracker + Fix awk error in analyzer
NEW SCRIPT: modules/website/500-error-tracker.sh - FAST-ONLY 500 error detection (no menus, no options) - Scans access logs for 500 errors - Maps domains to cPanel usernames - Automatically diagnoses root causes by checking error_log files - Shows actual PHP errors causing the 500s ROOT CAUSE DETECTION: - PHP Memory Exhausted (shows current limit) - PHP Fatal Errors - PHP Syntax Errors - Missing PHP Functions/Extensions - Database Connection Failures - .htaccess Issues - Shows ACTUAL error examples, not just suggestions FIXES: - Fixed awk error in website-error-analyzer.sh: • Changed "next" in END block to "if (length > 0)" • "next" cannot be used in END block in awk - Added option 2 in Website Management menu - Renumbered all WordPress tools (3-16) DIFFERENCE FROM FULL ANALYZER: Full Analyzer: All errors, filters, time ranges, user choices Fast Tracker: ONLY 500s, auto-diagnosis, shows WHY not suggestions Use Fast Tracker when you need to quickly find which domains are getting 500 errors and the exact PHP errors causing them.
This commit is contained in:
+30
-28
@@ -435,23 +435,24 @@ show_wordpress_menu() {
|
||||
echo -e "${BOLD}General Website Tools:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}1)${NC} 🔍 Website Error Analyzer - Find 500/config errors (filters bots)"
|
||||
echo -e " ${RED}2)${NC} 🔥 Fast 500 Error Tracker - ONLY 500s + root cause diagnosis"
|
||||
echo ""
|
||||
echo -e "${BOLD}WordPress Tools:${NC}"
|
||||
echo ""
|
||||
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 -e " ${BLUE}3)${NC} Health Check (All Sites) - Scan all WP installations"
|
||||
echo -e " ${BLUE}4)${NC} WP-Cron Status - Check cron job status"
|
||||
echo -e " ${BLUE}5)${NC} WP-Cron Mass Fix - Fix/enable cron on all sites"
|
||||
echo -e " ${BLUE}6)${NC} WP-Cron Mass Create - Setup proper system crons"
|
||||
echo -e " ${BLUE}7)${NC} Plugin Audit - Security scan of plugins"
|
||||
echo -e " ${BLUE}8)${NC} Theme Audit - Security scan of themes"
|
||||
echo -e " ${BLUE}9)${NC} Database Optimizer - Clean/optimize WP databases"
|
||||
echo -e " ${BLUE}10)${NC} Cache Clear (All Sites) - Clear all WP caches"
|
||||
echo -e " ${BLUE}11)${NC} Mass Update Core - Update WordPress core (all)"
|
||||
echo -e " ${BLUE}12)${NC} Mass Update Plugins - Update plugins (all sites)"
|
||||
echo -e " ${BLUE}13)${NC} Login Security Audit - Check for weak passwords"
|
||||
echo -e " ${BLUE}14)${NC} Malware Scanner - Scan for infected files"
|
||||
echo -e " ${BLUE}15)${NC} Permission Fixer - Fix file permissions"
|
||||
echo -e " ${BLUE}16)${NC} Debug Log Analyzer - Parse WP debug logs"
|
||||
echo ""
|
||||
echo -e " ${RED}0)${NC} Back to Main Menu"
|
||||
echo ""
|
||||
@@ -1148,20 +1149,21 @@ handle_wordpress_menu() {
|
||||
|
||||
case $choice in
|
||||
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" ;;
|
||||
2) run_module "website" "500-error-tracker.sh" ;;
|
||||
3) run_module "wordpress" "wp-health-check.sh" ;;
|
||||
4) run_module "wordpress" "wp-cron-status.sh" ;;
|
||||
5) run_module "wordpress" "wp-cron-mass-fix.sh" ;;
|
||||
6) run_module "wordpress" "wp-cron-mass-create.sh" ;;
|
||||
7) run_module "wordpress" "wp-plugin-audit.sh" ;;
|
||||
8) run_module "wordpress" "wp-theme-audit.sh" ;;
|
||||
9) run_module "wordpress" "wp-db-optimizer.sh" ;;
|
||||
10) run_module "wordpress" "wp-cache-clear.sh" ;;
|
||||
11) run_module "wordpress" "wp-mass-update-core.sh" ;;
|
||||
12) run_module "wordpress" "wp-mass-update-plugins.sh" ;;
|
||||
13) run_module "wordpress" "wp-login-security.sh" ;;
|
||||
14) run_module "wordpress" "wp-malware-scanner.sh" ;;
|
||||
15) run_module "wordpress" "wp-permission-fixer.sh" ;;
|
||||
16) run_module "wordpress" "wp-debug-log-analyzer.sh" ;;
|
||||
0) return ;;
|
||||
*) echo -e "${RED}Invalid option${NC}"; sleep 1 ;;
|
||||
esac
|
||||
|
||||
Executable
+245
@@ -0,0 +1,245 @@
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# Fast 500 Error Tracker
|
||||
################################################################################
|
||||
# Purpose: ONLY track 500 errors - find them fast and show WHY
|
||||
# No menus, no options - just find 500s and diagnose the root cause
|
||||
################################################################################
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
source "$SCRIPT_DIR/lib/common-functions.sh"
|
||||
|
||||
print_banner "Fast 500 Error Tracker"
|
||||
|
||||
echo ""
|
||||
echo "Scanning for 500 errors and diagnosing root causes..."
|
||||
echo ""
|
||||
|
||||
# Temporary files
|
||||
TEMP_DIR="/tmp/500-tracker-$$"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
trap "rm -rf $TEMP_DIR" EXIT
|
||||
|
||||
ERRORS_500="$TEMP_DIR/errors_500.txt"
|
||||
ERROR_DETAILS="$TEMP_DIR/error_details.txt"
|
||||
|
||||
# Configuration
|
||||
DOMLOGS_DIR="/var/log/apache2/domlogs"
|
||||
HOURS_TO_SCAN=24
|
||||
|
||||
echo "→ Scanning last $HOURS_TO_SCAN hours of access logs..."
|
||||
echo ""
|
||||
|
||||
# Get cutoff time
|
||||
cutoff_time=$(date -d "$HOURS_TO_SCAN hours ago" +%s 2>/dev/null || echo "0")
|
||||
|
||||
declare -A domain_count
|
||||
declare -A domain_user
|
||||
total_500s=0
|
||||
|
||||
# Scan all domain access logs for 500 errors
|
||||
for log in "$DOMLOGS_DIR"/*; do
|
||||
[ -f "$log" ] || continue
|
||||
[[ "$log" =~ (bytes_log|offset|error_log|ftpxferlog|-ssl_log)$ ]] && continue
|
||||
|
||||
domain="${log##*/}"
|
||||
domain="${domain%%-*}"
|
||||
|
||||
# Find cPanel user for this domain
|
||||
user=$(grep -l "DNS.*$domain" /var/cpanel/users/* 2>/dev/null | head -1 | xargs basename 2>/dev/null)
|
||||
[ -z "$user" ] && user="unknown"
|
||||
|
||||
domain_user["$domain"]="$user"
|
||||
|
||||
# Scan for 500 errors in this log
|
||||
while IFS= read -r line; do
|
||||
# Check for 500 status code
|
||||
if [[ "$line" =~ '"'[[:space:]](5[0-9]{2})[[:space:]] ]]; then
|
||||
status="${BASH_REMATCH[1]}"
|
||||
|
||||
# Time filtering
|
||||
if [ "$cutoff_time" != "0" ]; then
|
||||
if [[ "$line" =~ \[([0-9]{2}/[A-Z][a-z]{2}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}) ]]; then
|
||||
log_date="${BASH_REMATCH[1]}"
|
||||
log_time=$(date -d "${log_date/:/ }" +%s 2>/dev/null || echo "0")
|
||||
[ "$log_time" != "0" ] && [ "$log_time" -lt "$cutoff_time" ] && continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Parse log line
|
||||
read -r ip _ _ timestamp _ request _ _ <<< "$line"
|
||||
|
||||
# Extract URL
|
||||
if [[ "$request" =~ '"'[A-Z]+[[:space:]]([^[:space:]]+) ]]; then
|
||||
url="${BASH_REMATCH[1]:0:80}"
|
||||
else
|
||||
url="/"
|
||||
fi
|
||||
|
||||
# Extract timestamp
|
||||
if [[ "$line" =~ \[([^]]+)\] ]]; then
|
||||
timestamp="${BASH_REMATCH[1]}"
|
||||
else
|
||||
timestamp="unknown"
|
||||
fi
|
||||
|
||||
((domain_count["$domain"]++))
|
||||
((total_500s++))
|
||||
|
||||
# Save for analysis
|
||||
echo "$domain|$user|$status|$url|$timestamp|$ip" >> "$ERRORS_500"
|
||||
fi
|
||||
done < <(tail -n 100000 "$log" 2>/dev/null)
|
||||
done
|
||||
|
||||
if [ "$total_500s" -eq 0 ]; then
|
||||
echo ""
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${GREEN} ✓ NO 500 ERRORS FOUND IN LAST $HOURS_TO_SCAN HOURS!${NC}"
|
||||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " 🔥 500 ERRORS DETECTED: $total_500s errors"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
echo -e "${RED}${BOLD}TOP AFFECTED DOMAINS:${NC}"
|
||||
echo ""
|
||||
|
||||
# Sort and display top domains
|
||||
for domain in "${!domain_count[@]}"; do
|
||||
echo "${domain_count[$domain]} $domain ${domain_user[$domain]}"
|
||||
done | sort -rn | head -10 | while read count domain user; do
|
||||
printf " ${RED}●${NC} %-40s ${BOLD}%4d errors${NC} (user: %s)\n" "$domain" "$count" "$user"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " 🔍 DIAGNOSING ROOT CAUSES"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# For each affected domain, check the actual PHP error logs
|
||||
declare -A diagnosed_causes
|
||||
declare -A cause_examples
|
||||
|
||||
while IFS='|' read -r domain user status url timestamp ip; do
|
||||
[ -z "$domain" ] && continue
|
||||
|
||||
# Find PHP error log for this user
|
||||
error_log="/home/$user/public_html/error_log"
|
||||
|
||||
# Check if error log exists and has recent errors
|
||||
if [ -f "$error_log" ]; then
|
||||
# Look for errors around the same time as the 500
|
||||
recent_error=$(tail -100 "$error_log" | grep -E "Fatal error|Parse error|syntax error|memory.*exhausted|database|MySQL" | tail -1)
|
||||
|
||||
if [ -n "$recent_error" ]; then
|
||||
# Determine cause
|
||||
cause="UNKNOWN"
|
||||
if [[ "$recent_error" =~ (memory.*exhausted|Allowed memory size) ]]; then
|
||||
cause="PHP_MEMORY_EXHAUSTED"
|
||||
cause_examples["$cause"]="$domain: $recent_error"
|
||||
elif [[ "$recent_error" =~ (Fatal error|PHP Fatal error) ]]; then
|
||||
if [[ "$recent_error" =~ (undefined function|Call to undefined function) ]]; then
|
||||
cause="MISSING_PHP_FUNCTION"
|
||||
cause_examples["$cause"]="$domain: $recent_error"
|
||||
else
|
||||
cause="PHP_FATAL_ERROR"
|
||||
cause_examples["$cause"]="$domain: $recent_error"
|
||||
fi
|
||||
elif [[ "$recent_error" =~ (Parse error|syntax error) ]]; then
|
||||
cause="PHP_SYNTAX_ERROR"
|
||||
cause_examples["$cause"]="$domain: $recent_error"
|
||||
elif [[ "$recent_error" =~ (database|MySQL|Can\'t connect) ]]; then
|
||||
cause="DATABASE_CONNECTION"
|
||||
cause_examples["$cause"]="$domain: $recent_error"
|
||||
fi
|
||||
|
||||
((diagnosed_causes["$cause"]++))
|
||||
else
|
||||
((diagnosed_causes["NO_PHP_ERROR_LOGGED"]++))
|
||||
fi
|
||||
else
|
||||
((diagnosed_causes["NO_ERROR_LOG_FILE"]++))
|
||||
cause_examples["NO_ERROR_LOG_FILE"]="$domain (user: $user) - error_log file missing at $error_log"
|
||||
fi
|
||||
done < "$ERRORS_500"
|
||||
|
||||
# Display diagnosed causes
|
||||
echo -e "${CYAN}${BOLD}ROOT CAUSES IDENTIFIED:${NC}"
|
||||
echo ""
|
||||
|
||||
for cause in "${!diagnosed_causes[@]}"; do
|
||||
count="${diagnosed_causes[$cause]}"
|
||||
echo "$count|$cause"
|
||||
done | sort -rn | while IFS='|' read count cause; do
|
||||
clean_cause=$(echo "$cause" | tr '_' ' ')
|
||||
|
||||
case "$cause" in
|
||||
PHP_MEMORY_EXHAUSTED)
|
||||
echo -e "${RED}🔥 $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Fix:${NC} Increase memory_limit in /home/USER/public_html/.user.ini"
|
||||
echo " ${YELLOW}Set:${NC} memory_limit = 512M"
|
||||
;;
|
||||
PHP_FATAL_ERROR)
|
||||
echo -e "${RED}⚠️ $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Fix:${NC} Review recent code/plugin changes"
|
||||
;;
|
||||
PHP_SYNTAX_ERROR)
|
||||
echo -e "${RED}📝 $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Fix:${NC} Check for PHP syntax errors in recent file edits"
|
||||
;;
|
||||
MISSING_PHP_FUNCTION)
|
||||
echo -e "${RED}📦 $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Fix:${NC} Install missing PHP extension (check error for which one)"
|
||||
;;
|
||||
DATABASE_CONNECTION)
|
||||
echo -e "${RED}🗄️ $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Fix:${NC} Check database credentials or MySQL service"
|
||||
;;
|
||||
NO_ERROR_LOG_FILE)
|
||||
echo -e "${YELLOW}📄 $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Note:${NC} error_log file doesn't exist - may be .htaccess or permission issue"
|
||||
;;
|
||||
NO_PHP_ERROR_LOGGED)
|
||||
echo -e "${YELLOW}❓ $clean_cause${NC} - $count occurrences"
|
||||
echo " ${YELLOW}Note:${NC} 500 error but no PHP error in log - likely .htaccess issue"
|
||||
;;
|
||||
*)
|
||||
echo -e "${INFO_COLOR}• $clean_cause${NC} - $count occurrences"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Show example if we have one
|
||||
if [ -n "${cause_examples[$cause]}" ]; then
|
||||
example="${cause_examples[$cause]}"
|
||||
echo " ${DIM}Example: ${example:0:120}...${NC}"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " 📋 DETAILED 500 ERROR LIST"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
# Show most frequent URLs getting 500s
|
||||
echo "Most Frequent 500 Error URLs:"
|
||||
echo ""
|
||||
cut -d'|' -f1,4 "$ERRORS_500" | sort | uniq -c | sort -rn | head -15 | while read count domain_url; do
|
||||
domain=$(echo "$domain_url" | cut -d'|' -f1)
|
||||
url=$(echo "$domain_url" | cut -d'|' -f2)
|
||||
user="${domain_user[$domain]}"
|
||||
printf " ${RED}%4d×${NC} %s%s ${DIM}(user: %s)${NC}\n" "$count" "$domain" "$url" "$user"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Full error list saved to: $ERRORS_500"
|
||||
echo ""
|
||||
|
||||
press_enter
|
||||
@@ -604,9 +604,9 @@ END {
|
||||
file_path = file[key]
|
||||
|
||||
# Skip empty errors
|
||||
if (length(error) == 0) next
|
||||
|
||||
print count[key] "|" domain "|" file_path "|" error "|" root_cause
|
||||
if (length(error) > 0) {
|
||||
print count[key] "|" domain "|" file_path "|" error "|" root_cause
|
||||
}
|
||||
}
|
||||
}' "$CRITICAL_ERRORS" | sort -t'|' -k1 -rn | head -20 | while IFS='|' read -r count domain file_path error_msg root_cause; do
|
||||
|
||||
|
||||
Reference in New Issue
Block a user