Add intelligent failure categorization and analysis
New DELIVERY FAILURE ANALYSIS section that categorizes bounces: - Recipient doesn't exist (invalid email addresses) - Mailbox full (quota exceeded) - Relay denied (not authorized to send) - Blocked/Spam filtered (IP/domain blacklisted) - DNS/Domain issues (domain not found, no MX records) - Connection failures (timeout, refused) - Other failures (uncategorized) Each category shows: - Count of failures - Clear explanation of the reason - Suggested solutions - Example email addresses affected Makes it easy to understand WHY emails are failing instead of showing cryptic log entries.
This commit is contained in:
@@ -507,25 +507,102 @@ if [ "$delivered" -gt 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$bounced" -gt 0 ]; then
|
if [ "$bounced" -gt 0 ]; then
|
||||||
print_header "RECENT BOUNCES/FAILURES (last 5 from past $hours hours)"
|
print_header "DELIVERY FAILURE ANALYSIS"
|
||||||
echo ""
|
|
||||||
print_warning "PROOF - These emails failed delivery:"
|
|
||||||
echo ""
|
|
||||||
grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed\|saved mail to\|=>" | grep -i "550\|551\|552\|553\|554\|bounced\|Mail delivery failed\|** " | tail -5 | while read line; do
|
|
||||||
timestamp=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|[A-Z][a-z]{2} [0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1)
|
|
||||||
if [ -n "$timestamp" ]; then
|
|
||||||
echo -e " ${RED}[$timestamp]${NC} $line"
|
|
||||||
else
|
|
||||||
echo " $line"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Extract bounce reasons
|
# Get all bounce lines
|
||||||
print_header "COMMON BOUNCE REASONS"
|
TEMP_BOUNCES="/tmp/email_bounces_$$.txt"
|
||||||
|
grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed\|saved mail to\|=>" | grep -i "550\|551\|552\|553\|554\|bounced\|Mail delivery failed\|** " > "$TEMP_BOUNCES" 2>/dev/null
|
||||||
|
|
||||||
|
# Categorize failures
|
||||||
|
recipient_unknown=$(grep -ci "user unknown\|No such user\|does not exist\|recipient rejected\|Recipient address rejected\|550.*User" "$TEMP_BOUNCES" 2>/dev/null || echo 0)
|
||||||
|
mailbox_full=$(grep -ci "mailbox.*full\|quota.*exceeded\|552\|insufficient.*space\|over.*quota" "$TEMP_BOUNCES" 2>/dev/null || echo 0)
|
||||||
|
relay_denied=$(grep -ci "relay.*denied\|relay.*not.*permitted\|relaying denied\|554.*relay" "$TEMP_BOUNCES" 2>/dev/null || echo 0)
|
||||||
|
blocked=$(grep -ci "blocked\|blacklist\|550.*spam\|554.*spam\|Policy rejection" "$TEMP_BOUNCES" 2>/dev/null || echo 0)
|
||||||
|
dns_failure=$(grep -ci "domain.*not.*found\|Host.*unknown\|Name.*not.*resolve\|MX.*not.*found" "$TEMP_BOUNCES" 2>/dev/null || echo 0)
|
||||||
|
connection_fail=$(grep -ci "timeout\|connection.*refused\|connection.*failed\|Network.*unreachable" "$TEMP_BOUNCES" 2>/dev/null || echo 0)
|
||||||
|
|
||||||
|
print_info "Failure breakdown by reason:"
|
||||||
echo ""
|
echo ""
|
||||||
grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed\|saved mail to" | grep -i "550\|551\|bounced\|** " | grep -oE "550 [^(]*|551 [^(]*|User unknown|Mailbox.*full|Relay.*denied|No such user|does not exist" | sort | uniq -c | sort -rn | head -5
|
|
||||||
|
if [ "$recipient_unknown" -gt 0 ]; then
|
||||||
|
print_error " Recipient doesn't exist: $recipient_unknown emails"
|
||||||
|
echo " Reason: Email address is invalid or doesn't exist on recipient server"
|
||||||
|
grep -i "user unknown\|No such user\|does not exist\|recipient rejected\|550.*User" "$TEMP_BOUNCES" | head -2 | while read line; do
|
||||||
|
echo " Example: $(echo "$line" | grep -oE '[^ ]+@[^ ,]+' | head -1)"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$mailbox_full" -gt 0 ]; then
|
||||||
|
print_warning " Mailbox full: $mailbox_full emails"
|
||||||
|
echo " Reason: Recipient's mailbox has exceeded storage quota"
|
||||||
|
grep -i "mailbox.*full\|quota.*exceeded\|552" "$TEMP_BOUNCES" | head -2 | while read line; do
|
||||||
|
echo " Example: $(echo "$line" | grep -oE '[^ ]+@[^ ,]+' | head -1)"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$relay_denied" -gt 0 ]; then
|
||||||
|
print_error " Relay denied: $relay_denied emails"
|
||||||
|
echo " Reason: Server not authorized to send to this domain"
|
||||||
|
echo " Solution: Check if server IP needs to be whitelisted"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$blocked" -gt 0 ]; then
|
||||||
|
print_error " Blocked/Spam filtered: $blocked emails"
|
||||||
|
echo " Reason: Sender IP or domain is blacklisted, or content flagged as spam"
|
||||||
|
echo " Solution: Check IP reputation, SPF/DKIM records"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$dns_failure" -gt 0 ]; then
|
||||||
|
print_error " DNS/Domain issues: $dns_failure emails"
|
||||||
|
echo " Reason: Recipient domain doesn't exist or has no MX records"
|
||||||
|
grep -i "domain.*not.*found\|Host.*unknown" "$TEMP_BOUNCES" | head -2 | while read line; do
|
||||||
|
echo " Example: $(echo "$line" | grep -oE '[^ ]+@[^ ,]+' | head -1)"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$connection_fail" -gt 0 ]; then
|
||||||
|
print_warning " Connection failures: $connection_fail emails"
|
||||||
|
echo " Reason: Could not connect to recipient mail server (temporary)"
|
||||||
|
echo " Solution: These usually resolve themselves, check if persistent"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Calculate uncategorized
|
||||||
|
total_categorized=$((recipient_unknown + mailbox_full + relay_denied + blocked + dns_failure + connection_fail))
|
||||||
|
if [ "$total_categorized" -lt "$bounced" ]; then
|
||||||
|
other=$((bounced - total_categorized))
|
||||||
|
print_warning " Other failures: $other emails"
|
||||||
|
echo " See detailed logs below for specific reasons"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show recent failures for reference
|
||||||
|
print_header "RECENT FAILURE EXAMPLES (last 3)"
|
||||||
echo ""
|
echo ""
|
||||||
|
grep -i "$search_pattern" "$TEMP_MATCHES" | grep -v "authenticator failed\|Authentication failed\|saved mail to\|=>" | grep -i "550\|551\|552\|553\|554\|bounced\|Mail delivery failed\|** " | tail -3 | while read line; do
|
||||||
|
timestamp=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}|[A-Z][a-z]{2} [0-9]+ [0-9]{2}:[0-9]{2}:[0-9]{2}' | head -1)
|
||||||
|
if [ -n "$timestamp" ]; then
|
||||||
|
echo -e " ${RED}[$timestamp]${NC}"
|
||||||
|
# Extract the key error message
|
||||||
|
error_msg=$(echo "$line" | grep -oE "550 [^<]*|551 [^<]*|552 [^<]*|User unknown|does not exist|Mailbox full|relay denied" | head -1)
|
||||||
|
if [ -n "$error_msg" ]; then
|
||||||
|
echo " Error: $error_msg"
|
||||||
|
fi
|
||||||
|
recipient=$(echo "$line" | grep -oE '[^ ]+@[^ ,<>]+' | grep -v "$search_pattern" | head -1)
|
||||||
|
if [ -n "$recipient" ]; then
|
||||||
|
echo " To: $recipient"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -f "$TEMP_BOUNCES"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$rejected" -gt 0 ]; then
|
if [ "$rejected" -gt 0 ]; then
|
||||||
@@ -655,4 +732,4 @@ print_info "Full log saved to: $REPORT_FILE"
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
rm -f "$TEMP_MATCHES" "$TEMP_AUTH" "$TEMP_ALL"
|
rm -f "$TEMP_MATCHES" "$TEMP_AUTH" "$TEMP_ALL" "$TEMP_BOUNCES"
|
||||||
|
|||||||
Reference in New Issue
Block a user