Email Server Log Monitoring: Complete Guide
Table of Contents
1. [Introduction](#introduction) 2. [Email Server Types and Log Locations](#email-server-types-and-log-locations) 3. [Log File Formats and Structure](#log-file-formats-and-structure) 4. [Essential Monitoring Commands](#essential-monitoring-commands) 5. [Log Analysis Techniques](#log-analysis-techniques) 6. [Automated Monitoring Solutions](#automated-monitoring-solutions) 7. [Common Issues and Troubleshooting](#common-issues-and-troubleshooting) 8. [Security Monitoring](#security-monitoring) 9. [Performance Monitoring](#performance-monitoring) 10. [Best Practices](#best-practices)Introduction
Email server log monitoring is a critical aspect of maintaining a healthy and secure email infrastructure. Proper monitoring helps administrators detect issues early, troubleshoot problems efficiently, and maintain optimal performance. This comprehensive guide covers various email server platforms, monitoring techniques, and best practices for effective log analysis.
Email servers generate extensive logs that contain valuable information about message delivery, authentication attempts, system errors, and security events. Understanding how to interpret and monitor these logs is essential for system administrators, security professionals, and anyone responsible for email infrastructure management.
Email Server Types and Log Locations
Postfix Mail Server
Postfix is one of the most popular open-source mail transfer agents (MTA) used in Linux environments. It provides robust logging capabilities that help administrators track email flow and diagnose issues.
#### Default Log Locations
| Distribution | Log File Location | Configuration File |
|--------------|-------------------|-------------------|
| Ubuntu/Debian | /var/log/mail.log | /etc/postfix/main.cf |
| CentOS/RHEL | /var/log/maillog | /etc/postfix/main.cf |
| Generic | /var/log/postfix.log | /etc/postfix/main.cf |
#### Postfix Log Configuration
The logging behavior in Postfix is controlled by the syslog configuration and Postfix's own settings:
`bash
View current Postfix logging configuration
postconf | grep log`Common Postfix logging parameters:
| Parameter | Description | Default Value |
|-----------|-------------|---------------|
| maillog_file | Direct logging to specific file | Not set |
| maillog_file_rotate_suffix | Rotation suffix format | %Y%m%d-%H%M%S |
| maillog_file_prefixes | Message prefixes to log | /usr, /dev/fd |
Sendmail
Sendmail is a traditional MTA that has been widely used in Unix systems for decades.
#### Sendmail Log Locations
| System Type | Log File Location | Configuration File |
|-------------|-------------------|-------------------|
| Most Unix/Linux | /var/log/maillog | /etc/mail/sendmail.cf |
| Solaris | /var/log/syslog | /etc/mail/sendmail.cf |
| AIX | /var/adm/maillog | /etc/sendmail.cf |
Microsoft Exchange Server
Exchange Server uses Windows Event Logs and specific Exchange logs for monitoring.
#### Exchange Log Locations
| Log Type | Location | Purpose |
|----------|----------|---------|
| Message Tracking | %ExchangeInstallPath%TransportRoles\Logs\MessageTracking\ | Track message flow |
| Protocol Logs | %ExchangeInstallPath%TransportRoles\Logs\ProtocolLog\ | SMTP/POP3/IMAP activity |
| Connectivity Logs | %ExchangeInstallPath%TransportRoles\Logs\Connectivity\ | Connection attempts |
| Agent Logs | %ExchangeInstallPath%TransportRoles\Logs\AgentLog\ | Transport agent activity |
Dovecot IMAP/POP3 Server
Dovecot is a popular IMAP and POP3 server for Unix-like systems.
#### Dovecot Log Configuration
| Log Type | Default Location | Configuration Parameter |
|----------|------------------|------------------------|
| Main Log | /var/log/dovecot.log | log_path |
| Info Log | /var/log/dovecot-info.log | info_log_path |
| Debug Log | /var/log/dovecot-debug.log | debug_log_path |
Log File Formats and Structure
Postfix Log Format
Postfix logs follow a standardized format that includes timestamps, process information, and message details:
`
Oct 15 10:30:45 mailserver postfix/smtpd[12345]: connect from client.example.com[192.168.1.100]
Oct 15 10:30:46 mailserver postfix/smtpd[12345]: 4A2B31234: client=client.example.com[192.168.1.100]
Oct 15 10:30:47 mailserver postfix/cleanup[12346]: 4A2B31234: message-id=`
#### Log Entry Components
| Component | Description | Example |
|-----------|-------------|---------|
| Timestamp | Date and time of event | Oct 15 10:30:45 |
| Hostname | Server generating the log | mailserver |
| Process | Postfix component | postfix/smtpd[12345] |
| Queue ID | Unique message identifier | 4A2B31234 |
| Event Details | Specific action or status | status=sent |
Sendmail Log Format
Sendmail logs contain similar information but with different formatting:
`
Oct 15 10:30:45 mailserver sendmail[12345]: 2A1B3C4D5: from=sender@example.com, size=1024, class=0, nrcpts=1, msgid=`
Exchange Server Message Tracking Log Format
Exchange uses CSV format for message tracking logs:
`csv
date-time,client-ip,client-hostname,server-ip,server-hostname,source-context,connector-id,source,event-id,internal-message-id,message-id,network-message-id,recipient-address,recipient-status,total-bytes,recipient-count,related-recipient-address,reference,message-subject,sender-address,return-path,message-info,directionality,tenant-id,original-client-ip,original-server-ip,custom-data
`
Essential Monitoring Commands
Real-time Log Monitoring
#### Using tail Command
The tail command is fundamental for real-time log monitoring:
`bash
Monitor mail log in real-time
tail -f /var/log/mail.logMonitor with line numbers
tail -f -n 100 /var/log/mail.logMonitor multiple log files simultaneously
tail -f /var/log/mail.log /var/log/mail.err`Command Parameters:
- -f: Follow log file as it grows
- -n NUM: Display last NUM lines
- -q: Suppress filename headers when monitoring multiple files
#### Using journalctl (systemd systems)
Modern Linux systems using systemd can monitor logs through journalctl:
`bash
Monitor Postfix logs in real-time
journalctl -u postfix -fMonitor with timestamp filtering
journalctl -u postfix --since "2023-10-15 10:00:00" --until "2023-10-15 11:00:00"Monitor with priority filtering
journalctl -u postfix -p errMonitor multiple services
journalctl -u postfix -u dovecot -f`Journalctl Priority Levels:
| Level | Numeric | Description | |-------|---------|-------------| | emerg | 0 | System unusable | | alert | 1 | Action required immediately | | crit | 2 | Critical conditions | | err | 3 | Error conditions | | warning | 4 | Warning conditions | | notice | 5 | Normal but significant | | info | 6 | Informational messages | | debug | 7 | Debug messages |
Log Searching and Filtering
#### Using grep for Pattern Matching
`bash
Search for specific email address
grep "user@example.com" /var/log/mail.logSearch for failed deliveries
grep "status=bounced\|status=deferred" /var/log/mail.logSearch with case insensitive matching
grep -i "error\|warning\|failed" /var/log/mail.logSearch with line numbers and context
grep -n -A 3 -B 3 "NOQUEUE" /var/log/mail.logSearch across multiple files with recursive option
grep -r "suspicious activity" /var/log/`Grep Options:
| Option | Description |
|--------|-------------|
| -i | Case insensitive search |
| -v | Invert match (exclude pattern) |
| -n | Show line numbers |
| -A NUM | Show NUM lines after match |
| -B NUM | Show NUM lines before match |
| -C NUM | Show NUM lines around match |
| -r | Recursive search in directories |
#### Advanced Pattern Matching with awk
`bash
Extract specific fields from Postfix logs
awk '/postfix\/smtp/ {print $1, $2, $3, $6, $7}' /var/log/mail.logCalculate message delivery statistics
awk '/status=sent/ {sent++} /status=bounced/ {bounced++} /status=deferred/ {deferred++} END {print "Sent:", sent, "Bounced:", bounced, "Deferred:", deferred}' /var/log/mail.logFind messages from specific time range
awk '$1=="Oct" && $2>=15 && $3>="10:00:00" && $3<="11:00:00"' /var/log/mail.logExtract unique sender addresses
awk -F'from=<|>,' '/from=/ {print $2}' /var/log/mail.log | sort | uniq`#### Using sed for Log Processing
`bash
Remove timestamps for cleaner output
sed 's/^[A-Z][a-z][a-z] [0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^ ]* //' /var/log/mail.logExtract only queue IDs and status
sed -n 's/.\([A-F0-9]\{10,\}\):.status=\([a-z]\)./\1 \2/p' /var/log/mail.logReplace sensitive information with placeholders
sed 's/\b[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Za-z]\{2,\}\b/[EMAIL]/g' /var/log/mail.log`Log Analysis Scripts
#### Bash Script for Daily Email Statistics
`bash
#!/bin/bash
daily_mail_stats.sh - Generate daily email statistics
LOG_FILE="/var/log/mail.log" DATE=$(date +"%b %d") OUTPUT_FILE="/tmp/mail_stats_$(date +%Y%m%d).txt"
echo "Email Statistics for $DATE" > $OUTPUT_FILE echo "================================" >> $OUTPUT_FILE echo "" >> $OUTPUT_FILE
Count sent messages
SENT=$(grep "$DATE" $LOG_FILE | grep "status=sent" | wc -l) echo "Messages Sent: $SENT" >> $OUTPUT_FILECount bounced messages
BOUNCED=$(grep "$DATE" $LOG_FILE | grep "status=bounced" | wc -l) echo "Messages Bounced: $BOUNCED" >> $OUTPUT_FILECount deferred messages
DEFERRED=$(grep "$DATE" $LOG_FILE | grep "status=deferred" | wc -l) echo "Messages Deferred: $DEFERRED" >> $OUTPUT_FILECount rejected messages
REJECTED=$(grep "$DATE" $LOG_FILE | grep "reject:" | wc -l) echo "Messages Rejected: $REJECTED" >> $OUTPUT_FILETop sender domains
echo "" >> $OUTPUT_FILE echo "Top 10 Sender Domains:" >> $OUTPUT_FILE grep "$DATE" $LOG_FILE | grep "from=<" | sed 's/.from=<[^@]@\([^>]\)>./\1/' | sort | uniq -c | sort -nr | head -10 >> $OUTPUT_FILETop recipient domains
echo "" >> $OUTPUT_FILE echo "Top 10 Recipient Domains:" >> $OUTPUT_FILE grep "$DATE" $LOG_FILE | grep "to=<" | sed 's/.to=<[^@]@\([^>]\)>./\1/' | sort | uniq -c | sort -nr | head -10 >> $OUTPUT_FILEcat $OUTPUT_FILE
`
#### Python Script for Log Analysis
`python
#!/usr/bin/env python3
mail_log_analyzer.py - Advanced mail log analysis
import re import sys from collections import defaultdict, Counter from datetime import datetime
class MailLogAnalyzer: def __init__(self, log_file): self.log_file = log_file self.stats = defaultdict(int) self.queue_ids = defaultdict(dict) self.errors = [] def parse_logs(self): """Parse mail logs and extract statistics""" with open(self.log_file, 'r') as f: for line in f: self.analyze_line(line.strip()) def analyze_line(self, line): """Analyze individual log line""" # Extract queue ID queue_match = re.search(r'([A-F0-9]{10,}):', line) if queue_match: queue_id = queue_match.group(1) # Track message status if 'status=sent' in line: self.stats['sent'] += 1 self.queue_ids[queue_id]['status'] = 'sent' elif 'status=bounced' in line: self.stats['bounced'] += 1 self.queue_ids[queue_id]['status'] = 'bounced' elif 'status=deferred' in line: self.stats['deferred'] += 1 self.queue_ids[queue_id]['status'] = 'deferred' # Extract sender and recipient from_match = re.search(r'from=<([^>]*)>', line) if from_match: self.queue_ids[queue_id]['from'] = from_match.group(1) to_match = re.search(r'to=<([^>]*)>', line) if to_match: self.queue_ids[queue_id]['to'] = to_match.group(1) # Track errors if any(keyword in line.lower() for keyword in ['error', 'warning', 'reject', 'timeout']): self.errors.append(line) def generate_report(self): """Generate comprehensive report""" print("Mail Server Log Analysis Report") print("=" * 50) print(f"Total Messages Processed: {sum(self.stats.values())}") print(f"Sent: {self.stats['sent']}") print(f"Bounced: {self.stats['bounced']}") print(f"Deferred: {self.stats['deferred']}") print(f"Errors Found: {len(self.errors)}") if self.errors: print("\nRecent Errors:") for error in self.errors[-10:]: # Show last 10 errors print(f" {error}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3 mail_log_analyzer.py `
Log Analysis Techniques
Message Flow Tracking
Understanding how messages flow through the email system is crucial for troubleshooting delivery issues.
#### Postfix Message Flow Stages
| Stage | Component | Description | Log Example |
|-------|-----------|-------------|-------------|
| Reception | smtpd | Incoming connection | connect from client.example.com |
| Cleanup | cleanup | Message processing | message-id= |
| Queue | qmgr | Queue management | from= |
| Delivery | smtp/local | Message delivery | status=sent (250 2.0.0 Ok) |
#### Tracking Message by Queue ID
`bash
Track complete message flow using queue ID
QUEUE_ID="4A2B31234" grep "$QUEUE_ID" /var/log/mail.logCreate a timeline for message processing
grep "$QUEUE_ID" /var/log/mail.log | awk '{print $1, $2, $3, $0}' | sort`Performance Analysis
#### Delivery Time Analysis
`bash
Extract delivery delays from Postfix logs
grep "delays=" /var/log/mail.log | awk -F'delays=' '{print $2}' | awk -F',' '{print $1}' | sort -nCalculate average delivery time
grep "delays=" /var/log/mail.log | awk -F'delays=' '{split($2,a,","); sum+=a[1]; count++} END {print "Average delay:", sum/count, "seconds"}'Find messages with high delivery delays
grep "delays=" /var/log/mail.log | awk -F'delays=' '{split($2,a,","); if(a[1]>60) print $0}'`#### Queue Size Monitoring
`bash
Monitor Postfix queue sizes
postqueue -p | tail -1Detailed queue analysis
postqueue -p | awk 'BEGIN {total=0; hold=0; active=0} /^[A-F0-9]/ {total++} /HOLD/ {hold++} /active/ {active++} END {print "Total:", total, "Hold:", hold, "Active:", active}'`Error Pattern Analysis
#### Common Error Patterns
| Error Type | Pattern | Meaning |
|------------|---------|---------|
| Connection timeout | connect to.*timed out | Remote server unreachable |
| DNS resolution | Host or domain name not found | DNS lookup failure |
| Authentication | authentication failed | SMTP AUTH failure |
| Quota exceeded | quota exceeded\|mailbox full | Recipient mailbox full |
| Spam rejection | blocked using.*RBL | Message blocked by RBL |
#### Error Analysis Script
`bash
#!/bin/bash
error_analysis.sh - Analyze common email errors
LOG_FILE="/var/log/mail.log" TODAY=$(date +"%b %d")
echo "Email Error Analysis for $TODAY" echo "================================"
Connection timeouts
TIMEOUTS=$(grep "$TODAY" $LOG_FILE | grep -c "timed out") echo "Connection Timeouts: $TIMEOUTS"DNS failures
DNS_ERRORS=$(grep "$TODAY" $LOG_FILE | grep -c "Host or domain name not found") echo "DNS Resolution Errors: $DNS_ERRORS"Authentication failures
AUTH_FAILURES=$(grep "$TODAY" $LOG_FILE | grep -c "authentication failed") echo "Authentication Failures: $AUTH_FAILURES"Quota exceeded
QUOTA_ERRORS=$(grep "$TODAY" $LOG_FILE | grep -c "quota exceeded\|mailbox full") echo "Quota Exceeded Errors: $QUOTA_ERRORS"RBL blocks
RBL_BLOCKS=$(grep "$TODAY" $LOG_FILE | grep -c "blocked using.*RBL") echo "RBL Blocks: $RBL_BLOCKS"echo ""
echo "Top Error Messages:"
grep "$TODAY" $LOG_FILE | grep -E "reject|error|warning|timeout" | awk '{for(i=6;i<=NF;i++) printf "%s ", $i; print ""}' | sort | uniq -c | sort -nr | head -10
`
Automated Monitoring Solutions
Log Rotation Configuration
#### Logrotate Configuration for Mail Logs
`bash
/etc/logrotate.d/mail
/var/log/mail.log /var/log/mail.info /var/log/mail.warn /var/log/mail.err { daily missingok rotate 52 compress delaycompress sharedscripts postrotate /usr/lib/rsyslog/rsyslog-rotate endscript }`Logrotate Options:
| Option | Description |
|--------|-------------|
| daily | Rotate logs daily |
| weekly | Rotate logs weekly |
| monthly | Rotate logs monthly |
| rotate N | Keep N old log files |
| compress | Compress rotated logs |
| delaycompress | Delay compression until next rotation |
| missingok | Don't error if log file is missing |
| sharedscripts | Run scripts only once for multiple files |
Monitoring with Nagios
#### Nagios Plugin for Mail Queue Monitoring
`bash
#!/bin/bash
check_mail_queue.sh - Nagios plugin for monitoring mail queue
QUEUE_SIZE=$(postqueue -p | tail -1 | awk '{print $5}')
if [ -z "$QUEUE_SIZE" ] || [ "$QUEUE_SIZE" = "empty" ]; then QUEUE_SIZE=0 fi
Remove non-numeric characters
QUEUE_SIZE=$(echo $QUEUE_SIZE | sed 's/[^0-9]*//g')WARNING_THRESHOLD=100 CRITICAL_THRESHOLD=500
if [ $QUEUE_SIZE -ge $CRITICAL_THRESHOLD ]; then
echo "CRITICAL - Mail queue size is $QUEUE_SIZE"
exit 2
elif [ $QUEUE_SIZE -ge $WARNING_THRESHOLD ]; then
echo "WARNING - Mail queue size is $QUEUE_SIZE"
exit 1
else
echo "OK - Mail queue size is $QUEUE_SIZE"
exit 0
fi
`
Monitoring with Zabbix
#### Zabbix UserParameter Configuration
`bash
/etc/zabbix/zabbix_agentd.d/mail_monitoring.conf
Mail queue size
UserParameter=mail.queue.size,postqueue -p | tail -1 | awk '{print $5}' | sed 's/[^0-9]*//g'Messages sent in last hour
UserParameter=mail.sent.lasthour,grep "$(date '+%b %d %H')" /var/log/mail.log | grep -c "status=sent"Messages bounced in last hour
UserParameter=mail.bounced.lasthour,grep "$(date '+%b %d %H')" /var/log/mail.log | grep -c "status=bounced"Authentication failures in last hour
UserParameter=mail.auth.failures.lasthour,grep "$(date '+%b %d %H')" /var/log/mail.log | grep -c "authentication failed"`ELK Stack Integration
#### Logstash Configuration for Mail Logs
`ruby
/etc/logstash/conf.d/mail.conf
input { file { path => "/var/log/mail.log" type => "postfix" start_position => "beginning" } }filter { if [type] == "postfix" { grok { match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{IPORHOST:hostname} %{DATA:program}\[%{POSINT:pid}\]: %{GREEDYDATA:message_body}" } } if [program] =~ /postfix/ { grok { match => { "message_body" => "%{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:postfix_message}" } } if "status=sent" in [postfix_message] { mutate { add_field => { "mail_status" => "sent" } } } else if "status=bounced" in [postfix_message] { mutate { add_field => { "mail_status" => "bounced" } } } else if "status=deferred" in [postfix_message] { mutate { add_field => { "mail_status" => "deferred" } } } } date { match => [ "timestamp", "MMM dd HH:mm:ss" ] } } }
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "mail-logs-%{+YYYY.MM.dd}"
}
}
`
Common Issues and Troubleshooting
Delivery Failures
#### Bounce Message Analysis
`bash
Analyze bounce reasons
grep "status=bounced" /var/log/mail.log | sed 's/.*said: //' | sort | uniq -c | sort -nrFind specific bounce patterns
grep "User unknown" /var/log/mail.log | awk '{print $1, $2, $3}' | uniq -cTrack bounces by domain
grep "status=bounced" /var/log/mail.log | grep -o "to=<[^@]@[^>]>" | sed 's/.*@//' | sed 's/>//' | sort | uniq -c | sort -nr`#### Deferred Message Analysis
`bash
Analyze deferral reasons
grep "status=deferred" /var/log/mail.log | awk -F'(' '{print $2}' | awk -F')' '{print $1}' | sort | uniq -c | sort -nrFind messages deferred multiple times
grep "status=deferred" /var/log/mail.log | awk '{print $6}' | sort | uniq -c | awk '$1>5 {print $2}' | while read qid; do echo "Queue ID $qid deferred multiple times:" grep "$qid" /var/log/mail.log | grep "status=deferred" echo "" done`Authentication Issues
#### SASL Authentication Monitoring
`bash
Monitor SASL authentication attempts
grep "sasl_method" /var/log/mail.log | awk '{print $1, $2, $3, $8, $9, $10}' | sort | uniq -cFailed authentication attempts
grep "authentication failed" /var/log/mail.log | awk '{print $1, $2, $3, $8}' | sort | uniq -cSuccessful authentications by user
grep "sasl_username" /var/log/mail.log | grep -o "sasl_username=[^,]*" | sort | uniq -c | sort -nr`Spam and Security Issues
#### RBL and Spam Filter Analysis
`bash
RBL rejections by list
grep "blocked using" /var/log/mail.log | awk -F'blocked using ' '{print $2}' | awk '{print $1}' | sort | uniq -c | sort -nrSpam score analysis (SpamAssassin)
grep "X-Spam-Status" /var/log/mail.log | grep -o "score=[0-9.]*" | awk -F'=' '{print $2}' | sort -nRejected connections by IP
grep "reject:" /var/log/mail.log | awk '{print $8}' | grep -o '\[[0-9.]*\]' | sort | uniq -c | sort -nr`Security Monitoring
Intrusion Detection
#### Suspicious Activity Patterns
`bash
Multiple failed login attempts from same IP
grep "authentication failed" /var/log/mail.log | awk '{print $8}' | grep -o '\[[0-9.]*\]' | sort | uniq -c | awk '$1>10 {print $2, $1 " attempts"}'Unusual connection patterns
grep "connect from" /var/log/mail.log | awk '{print $6}' | grep -o '\[[0-9.]*\]' | sort | uniq -c | sort -nr | head -20Relay attempts
grep "Relay access denied" /var/log/mail.log | awk '{print $1, $2, $3, $8}' | sort | uniq -c`#### Security Alert Script
`bash
#!/bin/bash
security_monitor.sh - Monitor for security threats
LOG_FILE="/var/log/mail.log" ALERT_FILE="/tmp/security_alerts.log" DATE=$(date +"%b %d")
echo "Security Alert Report - $DATE" > $ALERT_FILE echo "==============================" >> $ALERT_FILE
Check for brute force attempts
echo "Brute Force Attempts:" >> $ALERT_FILE grep "$DATE" $LOG_FILE | grep "authentication failed" | awk '{print $8}' | grep -o '\[[0-9.]*\]' | sort | uniq -c | awk '$1>5 {print "IP", $2, "failed", $1, "times"}' >> $ALERT_FILECheck for relay attempts
echo "" >> $ALERT_FILE echo "Relay Attempts:" >> $ALERT_FILE grep "$DATE" $LOG_FILE | grep -c "Relay access denied" >> $ALERT_FILECheck for suspicious connections
echo "" >> $ALERT_FILE echo "High Volume Connections:" >> $ALERT_FILE grep "$DATE" $LOG_FILE | grep "connect from" | awk '{print $6}' | grep -o '\[[0-9.]*\]' | sort | uniq -c | awk '$1>100 {print "IP", $2, "connected", $1, "times"}' >> $ALERT_FILEEmail alerts if issues found
if [ -s $ALERT_FILE ] && [ $(wc -l < $ALERT_FILE) -gt 3 ]; then mail -s "Mail Server Security Alert" admin@example.com < $ALERT_FILE ficat $ALERT_FILE
`
Performance Monitoring
System Resource Monitoring
#### Disk Space Monitoring
`bash
Monitor log file sizes
du -sh /var/log/mail* | sort -hMonitor queue directory size
du -sh /var/spool/postfix/Alert if log directory exceeds threshold
LOG_SIZE=$(du -s /var/log | awk '{print $1}') THRESHOLD=1000000 # 1GB in KBif [ $LOG_SIZE -gt $THRESHOLD ]; then
echo "WARNING: Log directory size exceeds threshold"
echo "Current size: $(du -sh /var/log | awk '{print $1}')"
fi
`
#### Memory and CPU Monitoring
`bash
Monitor Postfix process resource usage
ps aux | grep postfix | awk '{sum_cpu+=$3; sum_mem+=$4} END {print "Total CPU:", sum_cpu"%", "Total Memory:", sum_mem"%"}'Monitor connection counts
netstat -an | grep :25 | grep ESTABLISHED | wc -lMonitor system load
uptime | awk -F'load average:' '{print "Load Average:", $2}'`Best Practices
Log Management Strategy
#### Retention Policies
| Log Type | Retention Period | Storage Location | Compression | |----------|------------------|------------------|-------------| | Current Logs | 30 days | Local disk | No | | Archived Logs | 1 year | Network storage | Yes | | Security Logs | 2 years | Secure storage | Yes | | Compliance Logs | 7 years | Compliant storage | Yes |
#### Log Aggregation
`bash
Centralized logging with rsyslog
/etc/rsyslog.d/mail-central.conf
*.info;mail.none @logserver.example.com:514 mail.* @maillog.example.com:514Secure log transmission
$DefaultNetstreamDriverCAFile /etc/ssl/certs/ca.pem $DefaultNetstreamDriverCertFile /etc/ssl/certs/client-cert.pem $DefaultNetstreamDriverKeyFile /etc/ssl/private/client-key.pem $DefaultNetstreamDriver gtls $ActionSendStreamDriverMode 1 $ActionSendStreamDriverAuthMode x509/name $ActionSendStreamDriverPermittedPeer logserver.example.com`Monitoring Automation
#### Cron Jobs for Regular Monitoring
`bash
/etc/cron.d/mail-monitoring
Daily statistics report
0 6 * root /usr/local/bin/daily_mail_stats.shHourly queue size check
0 root /usr/local/bin/check_queue_size.shSecurity monitoring every 15 minutes
/15 * root /usr/local/bin/security_monitor.shWeekly log analysis
0 7 1 root /usr/local/bin/weekly_mail_analysis.sh`Documentation and Incident Response
#### Incident Response Checklist
| Step | Action | Command/Tool |
|------|--------|--------------|
| 1 | Identify issue scope | grep "error\|warning" /var/log/mail.log |
| 2 | Check system resources | df -h, free -m, uptime |
| 3 | Analyze queue status | postqueue -p |
| 4 | Review recent changes | grep "$(date +%b\ %d)" /var/log/mail.log |
| 5 | Check connectivity | telnet mx.example.com 25 |
| 6 | Document findings | Log analysis results |
| 7 | Implement solution | Service restart, configuration change |
| 8 | Monitor resolution | Continued log monitoring |
#### Change Management
`bash
Configuration backup before changes
cp /etc/postfix/main.cf /etc/postfix/main.cf.$(date +%Y%m%d_%H%M%S)Log configuration changes
echo "$(date): Modified main.cf - Added relay restrictions" >> /var/log/postfix-changes.logTest configuration
postfix checkReload configuration
postfix reloadMonitor for issues after changes
tail -f /var/log/mail.log | grep -E "error|warning|fatal"`This comprehensive guide provides system administrators with the knowledge and tools necessary to effectively monitor email server logs. Regular monitoring, proper analysis techniques, and automated alerting systems are essential components of maintaining a reliable and secure email infrastructure. The combination of manual analysis skills and automated monitoring tools ensures that issues are detected early and resolved quickly, minimizing impact on email service availability and security.