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
# All domains
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"
done
fi
@@ -295,8 +295,20 @@ extract_useful_info() {
# 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)
# Extract error message (clean up ModSec noise, timestamps, etc.)
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"
}
@@ -444,32 +456,46 @@ done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " ERROR DETAILS"
echo " ERROR DETAILS (Top Issues)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Show errors grouped by domain
current_domain=""
domain_count=0
# Group identical errors and count them
awk -F'|' '{
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
if [ "$domain" != "$current_domain" ]; then
if [ -n "$current_domain" ]; then
echo ""
fi
# Skip empty errors
if (length(error) == 0) next
((domain_count++))
[ $domain_count -gt 5 ] && break
print count[key] "|" domain "|" file_path "|" error
}
}' "$CRITICAL_ERRORS" | sort -t'|' -k1 -rn | head -20 | while IFS='|' read -r count domain file_path error_msg; do
echo -e "${YELLOW}$domain${NC}"
current_domain="$domain"
# Color code by frequency
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
if [ -n "$file_path" ]; then
echo " File: $file_path"
fi
echo " Error: $error_msg"
echo -e "${color}● Occurred $count times${NC} $priority"
[ -n "$domain" ] && [ "$domain" != "unknown" ] && echo " Domain: $domain"
[ -n "$file_path" ] && echo " File: $file_path"
echo " Error: $error_msg"
echo ""
done