Improve error display with grouping and counting

- Group identical errors and show occurrence count
- Color-code by frequency (HIGH/MEDIUM/LOW)
- Show top 20 most frequent errors instead of all
- Clean up ModSecurity noise (unique_id, pid, tid tags)
- Skip empty error messages
- Exclude FTP logs and bytes_log files from analysis
- Much cleaner output focused on actionable errors
- Answer: Access logs show 5xx errors (500-599), not 404s
This commit is contained in:
cschantz
2025-11-03 19:11:31 -05:00
parent 5e517b9858
commit 2c8ab0cd90
+47 -21
View File
@@ -159,7 +159,7 @@ if [ -d "$DOMLOGS_DIR" ]; then
else else
# All domains # All domains
for log in "$DOMLOGS_DIR"/*; do for log in "$DOMLOGS_DIR"/*; do
[ -f "$log" ] && ! [[ "$log" =~ (bytes_log|offset|error_log)$ ]] && \ [ -f "$log" ] && ! [[ "$log" =~ (bytes_log|offset|error_log|ftpxferlog)$ ]] && \
echo "$log|domlog_$(basename "$log")" >> "$LOG_FILES_LIST" echo "$log|domlog_$(basename "$log")" >> "$LOG_FILES_LIST"
done done
fi fi
@@ -295,8 +295,20 @@ extract_useful_info() {
# Extract file path if PHP error # Extract file path if PHP error
file_path=$(echo "$line" | grep -oE "in /[^ ]+\.php" | sed 's/in //' || echo "") file_path=$(echo "$line" | grep -oE "in /[^ ]+\.php" | sed 's/in //' || echo "")
# Extract error message (simplified) # Extract error message (clean up ModSec noise, timestamps, etc.)
error_msg=$(echo "$line" | sed 's/^\[.*\] //' | sed 's/\[client [^]]*\] //' | cut -c1-100) error_msg=$(echo "$line" | \
sed 's/^\[.*\] //' | \
sed 's/\[client [^]]*\] //' | \
sed 's/\[unique_id "[^"]*"\]//g' | \
sed 's/\[pid [^]]*\]//g' | \
sed 's/\[tid [^]]*\]//g' | \
grep -v "^$" | \
cut -c1-150)
# Skip if error message is empty or just whitespace
if [ -z "$(echo "$error_msg" | tr -d '[:space:]')" ]; then
return 1
fi
echo "$domain|$file_path|$error_msg" echo "$domain|$file_path|$error_msg"
} }
@@ -444,32 +456,46 @@ done
echo "" echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " ERROR DETAILS" echo " ERROR DETAILS (Top Issues)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "" echo ""
# Show errors grouped by domain # Group identical errors and count them
current_domain="" awk -F'|' '{
domain_count=0 key = $1 "|" $3 # domain|error_msg (skip file_path for grouping)
file[$1"|"$3] = $2 # Store file path
count[key]++
}
END {
for (key in count) {
split(key, parts, "|")
domain = parts[1]
error = parts[2]
file_path = file[key]
sort "$CRITICAL_ERRORS" | while IFS='|' read -r domain file_path error_msg; do # Skip empty errors
if [ "$domain" != "$current_domain" ]; then if (length(error) == 0) next
if [ -n "$current_domain" ]; then
echo ""
fi
((domain_count++)) print count[key] "|" domain "|" file_path "|" error
[ $domain_count -gt 5 ] && break }
}' "$CRITICAL_ERRORS" | sort -t'|' -k1 -rn | head -20 | while IFS='|' read -r count domain file_path error_msg; do
echo -e "${YELLOW}$domain${NC}" # Color code by frequency
current_domain="$domain" if [ "$count" -ge 10 ]; then
color="${RED}"
priority="[HIGH FREQUENCY]"
elif [ "$count" -ge 5 ]; then
color="${YELLOW}"
priority="[MEDIUM]"
else
color="${INFO_COLOR}"
priority=""
fi fi
if [ -n "$file_path" ]; then echo -e "${color}● Occurred $count times${NC} $priority"
echo " File: $file_path" [ -n "$domain" ] && [ "$domain" != "unknown" ] && echo " Domain: $domain"
fi [ -n "$file_path" ] && echo " File: $file_path"
echo " Error: $error_msg"
echo " Error: $error_msg"
echo "" echo ""
done done