Why Mail Server Monitoring Matters for Production Email
Your mail server sends thousands of emails daily, but how do you know if they're actually getting delivered? Most hosting customers discover email problems only when clients complain about missed messages. Important notifications disappear into the void.
Professional monitoring tracks delivery rates, identifies bounces, and alerts you to performance issues before they affect your business. This tutorial shows you how to configure mail server monitoring for Postfix on Ubuntu VPS using log analysis and automated alerts.
We'll set up real-time monitoring that tracks message queues, delivery failures, and performance metrics. The result is a mail server that alerts you proactively instead of failing silently.
Prerequisites for Ubuntu VPS Mail Monitoring
Before configuring monitoring, ensure your system meets these requirements:
- Ubuntu 22.04 or 24.04 VPS with root access
- Postfix mail server already installed and configured
- At least 1GB RAM and 2GB free disk space
- Basic familiarity with log files and cron jobs
If you're running Hostperl VPS hosting, these tools integrate with our Ubuntu images and monitoring infrastructure.
Check your current Postfix installation:
sudo systemctl status postfix
postconf mail_version
Install Essential Monitoring Tools
Start by installing the tools needed for comprehensive mail monitoring. We'll use pflogsumm for log analysis and mailutils for queue monitoring.
sudo apt update
sudo apt install pflogsumm mailutils logwatch -y
Install additional Python tools for custom monitoring scripts:
sudo apt install python3-pip python3-email python3-dateutil -y
pip3 install psutil
Verify the installation:
pflogsumm --version
mailq --version
Configure Postfix Verbose Logging
Standard Postfix logging provides basic information. Detailed monitoring requires verbose output. Edit the main configuration file:
sudo nano /etc/postfix/main.cf
Add these logging parameters at the end:
# Enhanced logging for monitoring
debug_peer_level = 2
debug_peer_list = 127.0.0.1
soft_bounce = no
notify_classes = bounce, delay, policy, protocol, resource, software
Configure master.cf for detailed service logging:
sudo nano /etc/postfix/master.cf
Find the smtp service line and modify it to enable verbose logging:
smtp inet n - y - - smtpd
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o receive_override_options=no_header_body_checks
Restart Postfix to apply changes:
sudo systemctl restart postfix
sudo systemctl status postfix
Set Up Log Rotation and Management
Mail logs grow rapidly under normal operation. Configure proper rotation to prevent disk space issues. Maintain monitoring history at the same time.
Edit the mail log rotation configuration:
sudo nano /etc/logrotate.d/rsyslog
Modify the mail log section:
/var/log/mail.log
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
{
daily
missingok
rotate 30
compress
delaycompress
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
systemctl restart postfix
endscript
}
Test the log rotation configuration:
sudo logrotate -d /etc/logrotate.d/rsyslog
For customers using our managed VPS hosting, we provide automated log management that integrates with these monitoring tools.
Create Mail Queue Monitoring Script
Active queue monitoring prevents mail backups from becoming delivery failures. Create a custom script that checks queue depth and alerts on problems.
Create the monitoring script:
sudo nano /usr/local/bin/mail-queue-monitor.sh
Add this monitoring logic:
#!/bin/bash
# Mail Queue Monitor for Postfix
# Checks queue depth and alerts on issues
QUEUE_WARN_THRESHOLD=50
QUEUE_CRITICAL_THRESHOLD=100
LOG_FILE="/var/log/mail-monitoring.log"
ALERT_EMAIL="admin@yourdomain.com"
# Get current queue count
QUEUE_COUNT=$(mailq | tail -n 1 | awk '{print $5}')
# Handle empty queue
if [[ "$QUEUE_COUNT" == "empty" ]]; then
QUEUE_COUNT=0
fi
# Log current status
echo "$(date): Queue count: $QUEUE_COUNT" >> $LOG_FILE
# Check thresholds and send alerts
if [ $QUEUE_COUNT -gt $QUEUE_CRITICAL_THRESHOLD ]; then
echo "CRITICAL: Mail queue has $QUEUE_COUNT messages" | \
mail -s "Critical Mail Queue Alert" $ALERT_EMAIL
elif [ $QUEUE_COUNT -gt $QUEUE_WARN_THRESHOLD ]; then
echo "WARNING: Mail queue has $QUEUE_COUNT messages" | \
mail -s "Mail Queue Warning" $ALERT_EMAIL
fi
# Output detailed queue info if problems exist
if [ $QUEUE_COUNT -gt $QUEUE_WARN_THRESHOLD ]; then
echo "=== Queue Details ===" >> $LOG_FILE
mailq >> $LOG_FILE
echo "==================" >> $LOG_FILE
fi
Make the script executable:
sudo chmod +x /usr/local/bin/mail-queue-monitor.sh
Implement Daily Log Analysis Reports
Daily analysis helps identify trends and recurring issues before they become critical problems. Use pflogsumm to generate comprehensive reports.
Create the daily analysis script:
sudo nano /usr/local/bin/mail-daily-report.sh
Add this reporting configuration:
#!/bin/bash
# Daily Mail Server Report Generator
# Analyzes yesterday's mail logs and sends summary
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
REPORT_EMAIL="admin@yourdomain.com"
REPORT_FILE="/tmp/mail-report-$YESTERDAY.txt"
# Generate pflogsumm report for yesterday
echo "Mail Server Report for $YESTERDAY" > $REPORT_FILE
echo "=================================" >> $REPORT_FILE
echo "" >> $REPORT_FILE
# Extract yesterday's logs
zcat /var/log/mail.log.1.gz 2>/dev/null | \
grep "$YESTERDAY" | pflogsumm >> $REPORT_FILE
# Add queue statistics
echo "" >> $REPORT_FILE
echo "Current Queue Status:" >> $REPORT_FILE
mailq >> $REPORT_FILE
# Add disk usage for mail directories
echo "" >> $REPORT_FILE
echo "Mail Directory Usage:" >> $REPORT_FILE
du -sh /var/spool/postfix/* >> $REPORT_FILE
# Send the report
mail -s "Daily Mail Server Report - $YESTERDAY" \
$REPORT_EMAIL < $REPORT_FILE
# Cleanup
rm -f $REPORT_FILE
Make it executable:
sudo chmod +x /usr/local/bin/mail-daily-report.sh
Configure Bounce and Delivery Tracking
Tracking bounces and failed deliveries helps maintain sender reputation. You'll also identify problematic domains or configurations.
Create a bounce analysis script:
sudo nano /usr/local/bin/bounce-analyzer.sh
Add bounce tracking logic:
#!/bin/bash
# Bounce Rate Analyzer for Mail Server Monitoring
# Tracks bounce rates and identifies problem domains
LOG_FILE="/var/log/mail.log"
BOUNCE_THRESHOLD=5 # Alert if bounce rate > 5%
REPORT_EMAIL="admin@yourdomain.com"
# Analyze last 24 hours of logs
TODAY=$(date +"%b %d")
# Count total sent messages
TOTAL_SENT=$(grep "$TODAY" $LOG_FILE | \
grep "status=sent" | wc -l)
# Count bounced messages
TOTAL_BOUNCED=$(grep "$TODAY" $LOG_FILE | \
grep "status=bounced" | wc -l)
# Calculate bounce rate
if [ $TOTAL_SENT -gt 0 ]; then
BOUNCE_RATE=$(( ($TOTAL_BOUNCED * 100) / $TOTAL_SENT ))
else
BOUNCE_RATE=0
fi
echo "$(date): Sent: $TOTAL_SENT, Bounced: $TOTAL_BOUNCED, Rate: $BOUNCE_RATE%" \
>> /var/log/bounce-tracking.log
# Alert if bounce rate is too high
if [ $BOUNCE_RATE -gt $BOUNCE_THRESHOLD ]; then
{
echo "High bounce rate detected: $BOUNCE_RATE%"
echo "Total sent: $TOTAL_SENT"
echo "Total bounced: $TOTAL_BOUNCED"
echo ""
echo "Top bouncing domains:"
grep "$TODAY" $LOG_FILE | grep "status=bounced" | \
awk '{print $7}' | sort | uniq -c | sort -nr | head -10
} | mail -s "High Bounce Rate Alert - $BOUNCE_RATE%" $REPORT_EMAIL
fi
Make it executable:
sudo chmod +x /usr/local/bin/bounce-analyzer.sh
Set Up Automated Monitoring with Cron
Consistent monitoring requires automation. Configure cron jobs to run your monitoring scripts at appropriate intervals.
Edit the root crontab:
sudo crontab -e
Add these monitoring jobs:
# Mail server monitoring automation
# Check mail queue every 5 minutes
*/5 * * * * /usr/local/bin/mail-queue-monitor.sh
# Analyze bounces every hour
0 * * * * /usr/local/bin/bounce-analyzer.sh
# Generate daily reports at 6 AM
0 6 * * * /usr/local/bin/mail-daily-report.sh
# Clean old monitoring logs weekly
0 3 * * 0 find /var/log -name "*mail-monitoring*" -mtime +30 -delete
Verify cron jobs are scheduled:
sudo crontab -l
Monitor Postfix Performance Metrics
Performance monitoring helps identify bottlenecks before they affect mail delivery. Track connection rates, processing times, and resource usage.
Create a performance monitoring script:
sudo nano /usr/local/bin/postfix-performance.py
Add this Python monitoring code:
#!/usr/bin/env python3
import subprocess
import psutil
import time
import json
from datetime import datetime
def get_postfix_stats():
"""Collect Postfix performance statistics"""
stats = {
'timestamp': datetime.now().isoformat(),
'queue_size': 0,
'active_connections': 0,
'memory_usage': 0,
'cpu_usage': 0
}
# Get queue size
try:
queue_output = subprocess.check_output(['mailq'], text=True)
if 'empty' not in queue_output:
lines = queue_output.strip().split('\n')
stats['queue_size'] = len([l for l in lines if l and not l.startswith('-')])
except subprocess.CalledProcessError:
pass
# Get Postfix process stats
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
if proc.info['name'] == 'master':
try:
proc_obj = psutil.Process(proc.info['pid'])
if 'postfix' in ' '.join(proc_obj.cmdline()):
stats['memory_usage'] = proc.info['memory_percent']
stats['cpu_usage'] = proc.info['cpu_percent']
break
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
# Count active SMTP connections
try:
netstat_output = subprocess.check_output(['netstat', '-an'], text=True)
stats['active_connections'] = netstat_output.count(':25 ')
except subprocess.CalledProcessError:
pass
return stats
def write_stats(stats):
"""Write statistics to log file"""
with open('/var/log/postfix-performance.log', 'a') as f:
f.write(json.dumps(stats) + '\n')
if __name__ == '__main__':
stats = get_postfix_stats()
write_stats(stats)
# Alert on high resource usage
if stats['cpu_usage'] > 80 or stats['memory_usage'] > 90:
alert_msg = f"High resource usage detected:\nCPU: {stats['cpu_usage']:.1f}%\nMemory: {stats['memory_usage']:.1f}%"
subprocess.run(['mail', '-s', 'Postfix Performance Alert', 'admin@yourdomain.com'],
input=alert_msg, text=True)
Make the script executable and test it:
sudo chmod +x /usr/local/bin/postfix-performance.py
sudo /usr/local/bin/postfix-performance.py
Add it to cron for regular performance monitoring:
sudo crontab -e
Add this line:
# Performance monitoring every 10 minutes
*/10 * * * * /usr/local/bin/postfix-performance.py
Configure Real-Time Alert Thresholds
Effective monitoring requires appropriate alert thresholds that balance sensitivity with practicality. Configure alerts for different severity levels.
Create a centralized alerting configuration:
sudo nano /etc/postfix-monitoring.conf
Define your alert thresholds:
# Postfix Monitoring Configuration
# Queue thresholds
QUEUE_WARNING=25
QUEUE_CRITICAL=75
# Bounce rate thresholds (percentage)
BOUNCE_WARNING=3
BOUNCE_CRITICAL=8
# Performance thresholds
CPU_WARNING=70
CPU_CRITICAL=85
MEMORY_WARNING=80
MEMORY_CRITICAL=90
# Connection thresholds
CONNECTION_WARNING=100
CONNECTION_CRITICAL=200
# Alert destinations
WARNING_EMAIL="alerts@yourdomain.com"
CRITICAL_EMAIL="critical@yourdomain.com"
# Monitoring intervals (minutes)
QUEUE_CHECK_INTERVAL=5
PERFORMACE_CHECK_INTERVAL=10
BOUNCE_CHECK_INTERVAL=60
Source this configuration in your monitoring scripts by adding this line at the top:
source /etc/postfix-monitoring.conf
Ready to implement professional monitoring for your mail server? Hostperl VPS hosting provides the stable Ubuntu environment and monitoring infrastructure you need for reliable email delivery. Our New Zealand-based support team helps with mail server optimization and troubleshooting.
Testing and Validation
Validate your monitoring setup by testing each component and verifying alert delivery.
Test queue monitoring by creating artificial queue buildup:
# Temporarily disable delivery to create queue
sudo postconf -e "defer_transports = smtp"
sudo systemctl reload postfix
# Send test messages
echo "Test message" | mail test@example.com
echo "Another test" | mail test@example.com
# Check if monitoring detects the queue
mailq
sudo /usr/local/bin/mail-queue-monitor.sh
Re-enable delivery:
sudo postconf -e "defer_transports = "
sudo systemctl reload postfix
Test bounce detection by sending to invalid addresses:
echo "Bounce test" | mail nonexistent@invaliddomain12345.com
sudo /usr/local/bin/bounce-analyzer.sh
Verify log files are being created and updated:
ls -la /var/log/*mail*
tail -f /var/log/mail-monitoring.log
Frequently Asked Questions
How often should mail server monitoring check the queue?
Check the mail queue every 5 minutes for most production servers. High-volume servers may need more frequent checks. Low-traffic servers can use 10-15 minute intervals.
What bounce rate indicates a problem?
Bounce rates above 5% typically indicate delivery issues. Rates above 10% suggest serious problems with configuration, reputation, or recipient lists that require immediate attention.
How long should monitoring logs be retained?
Keep detailed monitoring logs for 30 days for troubleshooting. Retain summarized daily reports for 6-12 months for trend analysis and capacity planning.
Can monitoring scripts affect mail server performance?
Properly configured monitoring has minimal impact. Run resource-intensive analysis during low-traffic periods and limit concurrent monitoring processes.
What memory usage is normal for Postfix monitoring?
Monitoring tools typically use 10-50MB of RAM. Alert if monitoring processes exceed 100MB. This may indicate log parsing issues or memory leaks.

