Enhance 500 error tracker: bot filtering, comprehensive validation, specific diagnostics

Major improvements to provide actionable, specific diagnostics instead of generic advice:

- Add bot/scanner filtering to reduce noise (monitors, SEO tools, security scanners, HTTP clients)
- Track and display filtered bot count in summary
- Remove all emojis from output
- Fix ANSI escape codes with echo -e for proper color rendering

Comprehensive file/permission validation:
- Resolve URLs to actual file paths being requested
- Test .htaccess readability by Apache (nobody user)
- Validate .htaccess syntax with apache2ctl -t
- Detect invalid PHP directives (php_value/php_flag without mod_php)
- Find malformed RewriteRule and orphaned RewriteCond
- Check document root and specific file permissions
- Test if files are readable by Apache user

Enhanced error extraction:
- Extract exact file paths from PHP errors
- Get line numbers for syntax errors
- Extract function names for missing function errors
- Get database usernames/names from DB errors
- Show current memory limits for memory exhaustion
- Identify specific files with permission issues

Add detailed per-URL diagnostics section:
- Show domain + URL + specific issue + file path + exact problem
- Group by error type with up to 20 examples per type
- Examples: "example.com/wp-admin - Permission denied on: /home/user/wp-config.php (perms: 600, owner: root:root) - NOT readable by Apache"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cschantz
2025-11-03 21:00:27 -05:00
parent 1674a62eae
commit e21e4a9fb7
+321 -48
View File
@@ -57,6 +57,7 @@ cutoff_time=$(date -d "$HOURS_TO_SCAN hours ago" +%s 2>/dev/null || echo "0")
declare -A domain_count declare -A domain_count
declare -A domain_user declare -A domain_user
total_500s=0 total_500s=0
filtered_bots=0
# Scan all domain access logs for 500 errors # Scan all domain access logs for 500 errors
for log in "$DOMLOGS_DIR"/*; do for log in "$DOMLOGS_DIR"/*; do
@@ -90,6 +91,21 @@ for log in "$DOMLOGS_DIR"/*; do
fi fi
fi fi
# Bot/Scanner filtering - skip noise
line_lower="${line,,}"
if [[ "$line_lower" =~ (bot|crawler|spider|scraper|scanner|check|monitor|uptime|pingdom|newrelic|datadog|nagios|zabbix|prtg|gomez|keynote|catchpoint|dotcom-monitor|site24x7|uptimerobot|statuscake|nodequery|hetrixtools|freshping|uptrendscom|siteuptime|montastic|updown\.io|apex|alertsite|webmon|wormly) ]]; then
((filtered_bots++))
continue
fi
if [[ "$line_lower" =~ (semrush|ahrefs|moz|majestic|serpstat|screaming|screamingfrog|sitebulb|linkchecker|validator|scanner|security|acunetix|nessus|openvas|burp|nikto|skipfish|w3af|sqlmap|metasploit|nmap|masscan|zmap|shodan|censys|binaryedge) ]]; then
((filtered_bots++))
continue
fi
if [[ "$line_lower" =~ (curl|wget|python|perl|ruby|java|go-http|libwww|axios|node-fetch|http\.client|httpie|postman|insomnia|apachehttp|okhttp|httpclient) ]]; then
((filtered_bots++))
continue
fi
# Parse log line # Parse log line
read -r ip _ _ timestamp _ request _ _ <<< "$line" read -r ip _ _ timestamp _ request _ _ <<< "$line"
@@ -126,7 +142,7 @@ if [ "$total_500s" -eq 0 ]; then
fi fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " 🔥 500 ERRORS DETECTED: $total_500s errors" echo " 500 ERRORS DETECTED: $total_500s errors (filtered out $filtered_bots bot/scanner requests)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "" echo ""
@@ -142,21 +158,52 @@ done
echo "" echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " 🔍 DIAGNOSING ROOT CAUSES" echo " DIAGNOSING ROOT CAUSES"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "" echo ""
# For each affected domain, check the actual PHP error logs # Detailed diagnostic tracking - per URL/file
DETAILED_DIAGNOSIS="$TEMP_DIR/detailed_diagnosis.txt"
> "$DETAILED_DIAGNOSIS"
declare -A diagnosed_causes declare -A diagnosed_causes
declare -A cause_examples declare -A cause_examples
while IFS='|' read -r domain user status url timestamp ip; do while IFS='|' read -r domain user status url timestamp ip; do
[ -z "$domain" ] && continue [ -z "$domain" ] && continue
diagnosis=""
cause="UNKNOWN"
specific_file=""
# Get document root
docroot="/home/$user/public_html"
# Try to determine the actual file being requested
if [[ "$url" =~ ^/([^?]+) ]]; then
url_path="${BASH_REMATCH[1]}"
# Handle common patterns
if [ -z "$url_path" ] || [ "$url_path" = "/" ]; then
possible_files=("$docroot/index.php" "$docroot/index.html")
elif [[ "$url_path" =~ \.php$ ]]; then
possible_files=("$docroot/$url_path")
else
possible_files=("$docroot/$url_path" "$docroot/${url_path}.php" "$docroot/$url_path/index.php")
fi
# Find the actual file
for pf in "${possible_files[@]}"; do
if [ -f "$pf" ]; then
specific_file="$pf"
break
fi
done
fi
# Find PHP error log - check multiple locations # Find PHP error log - check multiple locations
error_log="" error_log=""
if [ "$user" != "unknown" ]; then if [ "$user" != "unknown" ]; then
# Try multiple possible locations
for potential_log in \ for potential_log in \
"/home/$user/public_html/error_log" \ "/home/$user/public_html/error_log" \
"/home/$user/logs/error_log" \ "/home/$user/logs/error_log" \
@@ -173,51 +220,245 @@ while IFS='|' read -r domain user status url timestamp ip; do
# Check if error log exists and has recent errors # Check if error log exists and has recent errors
if [ -n "$error_log" ] && [ -f "$error_log" ]; then if [ -n "$error_log" ] && [ -f "$error_log" ]; then
# Look for errors around the same time as the 500 # Look for errors matching this URL/timestamp
recent_error=$(tail -500 "$error_log" | grep -E "Fatal error|Parse error|syntax error|memory.*exhausted|database|MySQL|Permission denied" | tail -1) recent_error=$(tail -1000 "$error_log" | grep -F "$url" | tail -1)
# If no URL match, get most recent error
[ -z "$recent_error" ] && recent_error=$(tail -500 "$error_log" | grep -E "Fatal error|Parse error|syntax error|memory.*exhausted|database|MySQL|Permission denied|failed to open stream" | tail -1)
if [ -n "$recent_error" ]; then if [ -n "$recent_error" ]; then
# Determine cause # Extract file path from error if present
cause="UNKNOWN" if [[ "$recent_error" =~ in[[:space:]](/[^:]+\.php) ]]; then
error_file="${BASH_REMATCH[1]}"
specific_file="$error_file"
fi
# Determine cause and diagnose
if [[ "$recent_error" =~ (memory.*exhausted|Allowed memory size) ]]; then if [[ "$recent_error" =~ (memory.*exhausted|Allowed memory size) ]]; then
cause="PHP_MEMORY_EXHAUSTED" cause="PHP_MEMORY_EXHAUSTED"
cause_examples["$cause"]="$domain: $recent_error"
# Check current memory limit
mem_limit=$(grep -h "memory_limit" "$docroot/.user.ini" "$docroot/../.php.ini" 2>/dev/null | tail -1 | cut -d'=' -f2 | tr -d ' ')
[ -z "$mem_limit" ] && mem_limit=$(php -r "echo ini_get('memory_limit');" 2>/dev/null)
diagnosis="$domain$url - Memory exhausted (current limit: ${mem_limit:-unknown})"
[ -n "$specific_file" ] && diagnosis="$diagnosis - File: $specific_file"
elif [[ "$recent_error" =~ (failed to open stream|Permission denied) ]]; then
cause="PERMISSION_ERROR"
# Extract the file with permission issue
if [[ "$recent_error" =~ failed\ to\ open\ stream.*\'([^\']+)\' ]]; then
perm_file="${BASH_REMATCH[1]}"
elif [[ "$recent_error" =~ Permission\ denied.*\'([^\']+)\' ]]; then
perm_file="${BASH_REMATCH[1]}"
else
perm_file="$specific_file"
fi
# Check permissions on that specific file
if [ -n "$perm_file" ] && [ -e "$perm_file" ]; then
file_perms=$(stat -c "%a" "$perm_file" 2>/dev/null)
file_owner=$(stat -c "%U:%G" "$perm_file" 2>/dev/null)
diagnosis="$domain$url - Permission denied on: $perm_file (perms: $file_perms, owner: $file_owner)"
# Check if file is readable by Apache
if [ -f "$perm_file" ]; then
if ! sudo -u nobody test -r "$perm_file" 2>/dev/null; then
diagnosis="$diagnosis - File NOT readable by Apache (nobody user)"
fi
fi
else
diagnosis="$domain$url - Permission denied (file in error: $perm_file - does not exist)"
fi
elif [[ "$recent_error" =~ (Fatal error|PHP Fatal error) ]]; then elif [[ "$recent_error" =~ (Fatal error|PHP Fatal error) ]]; then
if [[ "$recent_error" =~ (undefined function|Call to undefined function) ]]; then if [[ "$recent_error" =~ (undefined function|Call to undefined function) ]]; then
cause="MISSING_PHP_FUNCTION" cause="MISSING_PHP_FUNCTION"
cause_examples["$cause"]="$domain: $recent_error"
# Extract function name
if [[ "$recent_error" =~ Call\ to\ undefined\ function\ ([a-zA-Z0-9_]+) ]]; then
missing_func="${BASH_REMATCH[1]}"
# Check which extension provides this function
ext_info=$(php -r "if(function_exists('$missing_func')) echo 'EXISTS'; else echo 'MISSING';" 2>&1)
diagnosis="$domain$url - Missing function: $missing_func"
[ -n "$specific_file" ] && diagnosis="$diagnosis - in file: $specific_file"
else
diagnosis="$domain$url - Missing PHP function - $recent_error"
fi
else else
cause="PHP_FATAL_ERROR" cause="PHP_FATAL_ERROR"
cause_examples["$cause"]="$domain: $recent_error" diagnosis="$domain$url - PHP Fatal Error"
[ -n "$specific_file" ] && diagnosis="$diagnosis - File: $specific_file"
diagnosis="$diagnosis - ${recent_error:0:200}"
fi fi
elif [[ "$recent_error" =~ (Parse error|syntax error) ]]; then elif [[ "$recent_error" =~ (Parse error|syntax error) ]]; then
cause="PHP_SYNTAX_ERROR" cause="PHP_SYNTAX_ERROR"
cause_examples["$cause"]="$domain: $recent_error"
elif [[ "$recent_error" =~ (database|MySQL|Can\'t connect) ]]; then # Extract line number if present
if [[ "$recent_error" =~ line\ ([0-9]+) ]]; then
error_line="${BASH_REMATCH[1]}"
diagnosis="$domain$url - PHP Syntax Error at line $error_line"
else
diagnosis="$domain$url - PHP Syntax Error"
fi
[ -n "$specific_file" ] && diagnosis="$diagnosis - File: $specific_file"
elif [[ "$recent_error" =~ (database|MySQL|Can\'t connect|Access denied for user) ]]; then
cause="DATABASE_CONNECTION" cause="DATABASE_CONNECTION"
cause_examples["$cause"]="$domain: $recent_error"
if [[ "$recent_error" =~ Access\ denied\ for\ user\ \'([^\']+)\' ]]; then
db_user="${BASH_REMATCH[1]}"
diagnosis="$domain$url - Database access denied for user: $db_user"
elif [[ "$recent_error" =~ Unknown\ database\ \'([^\']+)\' ]]; then
db_name="${BASH_REMATCH[1]}"
diagnosis="$domain$url - Unknown database: $db_name"
else
diagnosis="$domain$url - Database connection error"
fi
[ -n "$specific_file" ] && diagnosis="$diagnosis - from file: $specific_file"
fi fi
# Save detailed diagnosis
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++)) ((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
else else
((diagnosed_causes["NO_PHP_ERROR_LOGGED"]++)) ((diagnosed_causes["NO_PHP_ERROR_LOGGED"]++))
fi fi
else else
# No error log found - likely .htaccess issue # No error log found - check .htaccess and permissions thoroughly
# Check if .htaccess exists and might have issues if [ "$user" != "unknown" ]; then
if [ "$user" != "unknown" ] && [ -f "/home/$user/public_html/.htaccess" ]; then htaccess_file="$docroot/.htaccess"
# Check for common .htaccess syntax errors
htaccess_check=$(grep -E "RewriteEngine|RewriteRule|RewriteCond|php_value|php_flag" "/home/$user/public_html/.htaccess" 2>/dev/null) if [ -f "$htaccess_file" ]; then
if [ -n "$htaccess_check" ]; then # Check .htaccess file permissions first
((diagnosed_causes["HTACCESS_LIKELY"]++)) htaccess_perms=$(stat -c "%a" "$htaccess_file" 2>/dev/null)
cause_examples["HTACCESS_LIKELY"]="$domain (user: $user) - has .htaccess with rewrite rules, check syntax" htaccess_owner=$(stat -c "%U:%G" "$htaccess_file" 2>/dev/null)
# Check if readable by Apache
htaccess_readable="yes"
if ! sudo -u nobody test -r "$htaccess_file" 2>/dev/null; then
htaccess_readable="no"
fi
# Actually validate .htaccess syntax
htaccess_test=$(apache2ctl -t 2>&1)
htaccess_issues=""
# Check for invalid directives
if grep -qE "^[[:space:]]*(php_value|php_flag|php_admin_value|php_admin_flag)" "$htaccess_file" 2>/dev/null; then
if ! apache2ctl -M 2>/dev/null | grep -q "php.*module"; then
htaccess_issues="PHP directives (php_value/php_flag) incompatible with current PHP handler (not mod_php)"
fi
fi
# Check for malformed RewriteRule
bad_rewrite=$(grep -nE "RewriteRule.*\[.*[^]]*$" "$htaccess_file" 2>/dev/null | head -1)
if [ -n "$bad_rewrite" ]; then
htaccess_issues="${htaccess_issues:+$htaccess_issues; }Malformed RewriteRule: $bad_rewrite"
fi
# Check for RewriteCond without following RewriteRule
orphan_cond=$(grep -n "RewriteCond" "$htaccess_file" | while read line; do
linenum=$(echo "$line" | cut -d: -f1)
nextline=$((linenum + 1))
next=$(sed -n "${nextline}p" "$htaccess_file")
if [[ ! "$next" =~ RewriteRule|RewriteCond ]]; then
echo "Line $linenum: RewriteCond without RewriteRule"
fi
done | head -1)
if [ -n "$orphan_cond" ]; then
htaccess_issues="${htaccess_issues:+$htaccess_issues; }$orphan_cond"
fi
# Check for syntax errors in .htaccess
if echo "$htaccess_test" | grep -qi "syntax error"; then
syntax_err=$(echo "$htaccess_test" | grep -i "syntax error" | head -1)
htaccess_issues="${htaccess_issues:+$htaccess_issues; }Apache syntax error: $syntax_err"
fi
if [ "$htaccess_readable" = "no" ]; then
cause="PERMISSION_ERROR"
diagnosis="$domain$url - .htaccess not readable by Apache (perms: $htaccess_perms, owner: $htaccess_owner)"
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
elif [ -n "$htaccess_issues" ]; then
cause="HTACCESS_ERROR"
diagnosis="$domain$url - .htaccess error: $htaccess_issues"
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
else
# .htaccess appears valid - check document root and file permissions
docroot_perms=$(stat -c "%a" "$docroot" 2>/dev/null)
docroot_owner=$(stat -c "%U:%G" "$docroot" 2>/dev/null)
if [ "$docroot_perms" != "755" ] && [ "$docroot_perms" != "750" ]; then
cause="PERMISSION_ERROR"
diagnosis="$domain$url - Document root incorrect permissions (perms: $docroot_perms, owner: $docroot_owner, should be 755)"
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
elif [ -n "$specific_file" ] && [ -f "$specific_file" ]; then
# Check the specific PHP file permissions
file_perms=$(stat -c "%a" "$specific_file" 2>/dev/null)
file_owner=$(stat -c "%U:%G" "$specific_file" 2>/dev/null)
file_readable="yes"
if ! sudo -u nobody test -r "$specific_file" 2>/dev/null; then
file_readable="no"
fi
if [ "$file_readable" = "no" ]; then
cause="PERMISSION_ERROR"
diagnosis="$domain$url - File not readable by Apache: $specific_file (perms: $file_perms, owner: $file_owner)"
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
else
((diagnosed_causes["NO_PHP_ERROR_LOGGED"]++))
fi
else
((diagnosed_causes["NO_PHP_ERROR_LOGGED"]++))
fi
fi
else else
((diagnosed_causes["NO_ERROR_LOG_FILE"]++)) # No .htaccess - check document root and file permissions
cause_examples["NO_ERROR_LOG_FILE"]="$domain (user: $user) - checked multiple locations, no error_log found" docroot_perms=$(stat -c "%a" "$docroot" 2>/dev/null)
docroot_owner=$(stat -c "%U:%G" "$docroot" 2>/dev/null)
if [ "$docroot_perms" != "755" ] && [ "$docroot_perms" != "750" ]; then
cause="PERMISSION_ERROR"
diagnosis="$domain$url - Document root incorrect permissions (perms: $docroot_perms, owner: $docroot_owner, should be 755)"
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
elif [ -n "$specific_file" ] && [ -f "$specific_file" ]; then
# Check the specific PHP file
file_perms=$(stat -c "%a" "$specific_file" 2>/dev/null)
file_owner=$(stat -c "%U:%G" "$specific_file" 2>/dev/null)
if ! sudo -u nobody test -r "$specific_file" 2>/dev/null; then
cause="PERMISSION_ERROR"
diagnosis="$domain$url - File not readable: $specific_file (perms: $file_perms, owner: $file_owner)"
echo "$cause|$diagnosis" >> "$DETAILED_DIAGNOSIS"
((diagnosed_causes["$cause"]++))
[ -z "${cause_examples[$cause]}" ] && cause_examples["$cause"]="$diagnosis"
else
((diagnosed_causes["NO_ERROR_LOG_FILE"]++))
fi
else
((diagnosed_causes["NO_ERROR_LOG_FILE"]++))
fi
fi fi
else else
((diagnosed_causes["NO_ERROR_LOG_FILE"]++)) ((diagnosed_causes["NO_ERROR_LOG_FILE"]++))
cause_examples["NO_ERROR_LOG_FILE"]="$domain (user: $user) - checked multiple locations, no error_log found"
fi fi
fi fi
done < "$ERRORS_500" done < "$ERRORS_500"
@@ -234,43 +475,43 @@ done | sort -rn | while IFS='|' read count cause; do
case "$cause" in case "$cause" in
PHP_MEMORY_EXHAUSTED) PHP_MEMORY_EXHAUSTED)
echo -e "${RED}🔥 $clean_cause${NC} - $count occurrences" echo -e "${RED}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Fix:${NC} Increase memory_limit in /home/USER/public_html/.user.ini" echo -e " ${YELLOW}Fix:${NC} Increase memory_limit in /home/USER/public_html/.user.ini"
echo " ${YELLOW}Set:${NC} memory_limit = 512M" echo -e " ${YELLOW}Set:${NC} memory_limit = 512M"
;; ;;
PHP_FATAL_ERROR) PHP_FATAL_ERROR)
echo -e "${RED}⚠️ $clean_cause${NC} - $count occurrences" echo -e "${RED}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Fix:${NC} Review recent code/plugin changes" echo -e " ${YELLOW}Fix:${NC} Review recent code/plugin changes"
;; ;;
PHP_SYNTAX_ERROR) PHP_SYNTAX_ERROR)
echo -e "${RED}📝 $clean_cause${NC} - $count occurrences" echo -e "${RED}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Fix:${NC} Check for PHP syntax errors in recent file edits" echo -e " ${YELLOW}Fix:${NC} Check for PHP syntax errors in recent file edits"
;; ;;
MISSING_PHP_FUNCTION) MISSING_PHP_FUNCTION)
echo -e "${RED}📦 $clean_cause${NC} - $count occurrences" echo -e "${RED}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Fix:${NC} Install missing PHP extension (check error for which one)" echo -e " ${YELLOW}Fix:${NC} Install missing PHP extension (check error for which one)"
;; ;;
DATABASE_CONNECTION) DATABASE_CONNECTION)
echo -e "${RED}🗄️ $clean_cause${NC} - $count occurrences" echo -e "${RED}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Fix:${NC} Check database credentials or MySQL service" echo -e " ${YELLOW}Fix:${NC} Check database credentials or MySQL service"
;; ;;
HTACCESS_LIKELY) HTACCESS_ERROR)
echo -e "${RED}⚙️ .HTACCESS SYNTAX ERROR (LIKELY)${NC} - $count occurrences" echo -e "${RED}.HTACCESS ERROR DETECTED${NC} - $count occurrences"
echo " ${YELLOW}Fix:${NC} Check .htaccess file for syntax errors" ;;
echo " ${YELLOW}Test:${NC} Temporarily rename .htaccess to .htaccess.bak and test" PERMISSION_ERROR)
echo " ${YELLOW}Common issues:${NC} Invalid RewriteRule, bad php_value directives" echo -e "${RED}PERMISSION ERROR DETECTED${NC} - $count occurrences"
;; ;;
NO_ERROR_LOG_FILE) NO_ERROR_LOG_FILE)
echo -e "${YELLOW}📄 $clean_cause${NC} - $count occurrences" echo -e "${YELLOW}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Note:${NC} Checked multiple error_log locations - none found" echo -e " ${YELLOW}Note:${NC} Checked multiple error_log locations - none found"
echo " ${YELLOW}Check:${NC} May need to enable PHP error logging" echo -e " ${YELLOW}Check:${NC} May need to enable PHP error logging"
;; ;;
NO_PHP_ERROR_LOGGED) NO_PHP_ERROR_LOGGED)
echo -e "${YELLOW}$clean_cause${NC} - $count occurrences" echo -e "${YELLOW}$clean_cause${NC} - $count occurrences"
echo " ${YELLOW}Note:${NC} 500 error but no PHP error in log - likely .htaccess or Apache config" echo -e " ${YELLOW}Note:${NC} 500 error but no PHP error in log - likely .htaccess or Apache config"
;; ;;
*) *)
echo -e "${INFO_COLOR}$clean_cause${NC} - $count occurrences" echo -e "${INFO_COLOR}$clean_cause${NC} - $count occurrences"
;; ;;
esac esac
@@ -283,7 +524,7 @@ done | sort -rn | while IFS='|' read count cause; do
done done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " 📋 DETAILED 500 ERROR LIST" echo " DETAILED 500 ERROR LIST"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "" echo ""
@@ -298,7 +539,39 @@ cut -d'|' -f1,4 "$ERRORS_500" | sort | uniq -c | sort -rn | head -15 | while rea
done done
echo "" echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " SPECIFIC DIAGNOSTICS (per URL/file)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Show detailed diagnostics grouped by cause
if [ -f "$DETAILED_DIAGNOSIS" ] && [ -s "$DETAILED_DIAGNOSIS" ]; then
for cause_type in PHP_MEMORY_EXHAUSTED PERMISSION_ERROR HTACCESS_ERROR PHP_FATAL_ERROR PHP_SYNTAX_ERROR MISSING_PHP_FUNCTION DATABASE_CONNECTION; do
cause_count=$(grep -c "^${cause_type}|" "$DETAILED_DIAGNOSIS" 2>/dev/null || echo "0")
if [ "$cause_count" -gt 0 ]; then
cause_display=$(echo "$cause_type" | tr '_' ' ')
echo -e "${RED}${BOLD}$cause_display ($cause_count)${NC}"
echo ""
grep "^${cause_type}|" "$DETAILED_DIAGNOSIS" | cut -d'|' -f2 | head -20 | while read -r diag_line; do
echo -e " ${YELLOW}${NC} $diag_line"
done
if [ "$cause_count" -gt 20 ]; then
remaining=$((cause_count - 20))
echo -e " ${DIM}... and $remaining more${NC}"
fi
echo ""
fi
done
else
echo "No detailed diagnostics available."
echo ""
fi
echo "Full error list saved to: $ERRORS_500" echo "Full error list saved to: $ERRORS_500"
echo "Detailed diagnostics saved to: $DETAILED_DIAGNOSIS"
echo "" echo ""
press_enter press_enter