Python Snippets

Monitor System Resources and Send Alerts via Email

import psutil
import smtplib
import time
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime

class SystemMonitor:
    def __init__(self, cpu_threshold=80, memory_threshold=80, disk_threshold=90):
        self.cpu_threshold = cpu_threshold
        self.memory_threshold = memory_threshold
        self.disk_threshold = disk_threshold
        
    def get_system_info(self):
        """Get current system resource usage"""
        cpu_percent = psutil.cpu_percent(interval=1)
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        
        return {
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'cpu_percent': cpu_percent,
            'memory_percent': memory.percent,
            'memory_used_gb': round(memory.used / (1024**3), 2),
            'memory_total_gb': round(memory.total / (1024**3), 2),
            'disk_percent': disk.percent,
            'disk_used_gb': round(disk.used / (1024**3), 2),
            'disk_total_gb': round(disk.total / (1024**3), 2)
        }
    
    def check_thresholds(self, info):
        """Check if any resource exceeds threshold"""
        alerts = []
        
        if info['cpu_percent'] > self.cpu_threshold:
            alerts.append(f"CPU usage high: {info['cpu_percent']}%")
            
        if info['memory_percent'] > self.memory_threshold:
            alerts.append(f"Memory usage high: {info['memory_percent']}%")
            
        if info['disk_percent'] > self.disk_threshold:
            alerts.append(f"Disk usage high: {info['disk_percent']}%")
            
        return alerts
    
    def send_alert(self, info, alerts, smtp_server, smtp_port, email_user, email_password, to_email):
        """Send email alert with system information"""
        try:
            msg = MIMEMultipart()
            msg['From'] = email_user
            msg['To'] = to_email
            msg['Subject'] = f"System Alert - {info['timestamp']}"
            
            body = f"""
            System Resource Alert:
            
            Time: {info['timestamp']}
            
            Resource Usage:
            - CPU: {info['cpu_percent']}%
            - Memory: {info['memory_percent']}% ({info['memory_used_gb']} GB / {info['memory_total_gb']} GB)
            - Disk: {info['disk_percent']}% ({info['disk_used_gb']} GB / {info['disk_total_gb']} GB)
            
            Alert Conditions:
            {' | '.join(alerts)}
            
            Please check your system immediately.
            """
            
            msg.attach(MIMEText(body, 'plain'))
            
            server = smtplib.SMTP(smtp_server, smtp_port)
            server.starttls()
            server.login(email_user, email_password)
            text = msg.as_string()
            server.sendmail(email_user, to_email, text)
            server.quit()
            
            print(f"[{info['timestamp']}] Alert sent successfully!")
            return True
            
        except Exception as e:
            print(f"[{info['timestamp']}] Failed to send alert: {str(e)}")
            return False
    
    def monitor(self, check_interval=60, smtp_server='smtp.gmail.com', smtp_port=587, 
                email_user='', email_password='', to_email=''):
        """Main monitoring loop"""
        print(f"Starting system monitor... (Checking every {check_interval} seconds)")
        print(f"Thresholds - CPU: {self.cpu_threshold}%, Memory: {self.memory_threshold}%, Disk: {self.disk_threshold}%")
        
        while True:
            try:
                # Get system info
                info = self.get_system_info()
                
                # Check thresholds
                alerts = self.check_thresholds(info)
                
                # Print current status
                print(f"[{info['timestamp']}] CPU: {info['cpu_percent']}% | "
                      f"Memory: {info['memory_percent']}% | "
                      f"Disk: {info['disk_percent']}%")
                
                # Send alert if needed
                if alerts:
                    self.send_alert(info, alerts, smtp_server, smtp_port, 
                                  email_user, email_password, to_email)
                
                # Wait before next check
                time.sleep(check_interval)
                
            except KeyboardInterrupt:
                print("\nMonitoring stopped by user.")
                break
            except Exception as e:
                print(f"Error during monitoring: {str(e)}")
                time.sleep(check_interval)

# Example usage
if __name__ == "__main__":
    # Initialize monitor with custom thresholds
    monitor = SystemMonitor(
        cpu_threshold=75,      # Alert when CPU > 75%
        memory_threshold=80,   # Alert when Memory > 80%
        disk_threshold=85      # Alert when Disk > 85%
    )
    
    # Start monitoring (commented out for safety)
    # monitor.monitor(
    #     check_interval=30,           # Check every 30 seconds
    #     smtp_server='smtp.gmail.com',
    #     smtp_port=587,
    #     email_user='your_email@gmail.com',
    #     email_password='your_app_password',  # Use app password for Gmail
    #     to_email='admin@example.com'
    # )
    
    # For testing without email alerts:
    info = monitor.get_system_info()
    print("Current System Status:")
    for key, value in info.items():
        print(f"  {key}: {value}")

This system monitoring tool continuously checks your computer’s key resources (CPU, memory, and disk usage) and sends email alerts when usage exceeds defined thresholds. It’s particularly useful for:

  1. Server Monitoring: Keep track of your servers and get notified when they’re under heavy load
  2. Resource Management: Prevent system crashes by being aware of resource exhaustion
  3. Performance Optimization: Identify when your system needs upgrades or optimization
  4. Remote System Supervision: Monitor computers you don’t have direct access to

The script uses psutil to gather system information and smtplib to send email alerts. It’s designed to run continuously in the background, checking resources at regular intervals.

To use this snippet:

  1. Install required packages: pip install psutil
  2. Configure your email SMTP settings (Gmail, Outlook, etc.)
  3. Set appropriate thresholds for your system
  4. Run the script as a background process

For Gmail users, you’ll need to generate an “App Password” instead of using your regular password for security reasons. The monitoring interval and alert thresholds are customizable to fit different system requirements.