import psutil
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime
from typing import Dict, Optional
class SystemMonitor:
def __init__(self, alert_thresholds: Dict[str, float], email_config: Optional[Dict] = None):
"""
Initialize the system monitor with alert thresholds and optional email configuration.
Args:
alert_thresholds: Dictionary with keys 'cpu', 'memory', 'disk' and values as percentages
email_config: Optional dictionary with email server settings
"""
self.thresholds = alert_thresholds
self.email_config = email_config
self.alert_history = {}
def get_system_metrics(self) -> Dict[str, float]:
"""Collect current system metrics."""
return {
'cpu': psutil.cpu_percent(interval=1),
'memory': psutil.virtual_memory().percent,
'disk': psutil.disk_usage('/').percent,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
def check_thresholds(self, metrics: Dict[str, float]) -> Dict[str, bool]:
"""Check if any metrics exceed configured thresholds."""
alerts = {}
for resource, value in metrics.items():
if resource in self.thresholds:
alerts[resource] = value > self.thresholds[resource]
return alerts
def send_alert(self, resource: str, value: float) -> None:
"""Send alert email if email configuration is provided."""
if not self.email_config:
print(f"ALERT: {resource} usage is at {value}%")
return
# Prevent sending too many alerts for the same resource
if resource in self.alert_history:
if (datetime.now() - self.alert_history[resource]).seconds < 300: # 5 minutes
return
self.alert_history[resource] = datetime.now()
try:
msg = MIMEMultipart()
msg['From'] = self.email_config['sender']
msg['To'] = self.email_config['recipient']
msg['Subject'] = f"System Alert: High {resource} Usage"
body = f"""
System Resource Alert - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
Resource: {resource}
Current Usage: {value}%
Threshold: {self.thresholds[resource]}%
Please check the system immediately.
"""
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP(self.email_config['smtp_server'], self.email_config['smtp_port'])
server.starttls()
server.login(self.email_config['sender'], self.email_config['password'])
text = msg.as_string()
server.sendmail(self.email_config['sender'], self.email_config['recipient'], text)
server.quit()
print(f"Alert email sent for {resource} usage")
except Exception as e:
print(f"Failed to send email alert: {str(e)}")
def run_monitoring(self, interval: int = 5) -> None:
"""Run continuous system monitoring."""
print("Starting system monitoring...")
print(f"Thresholds: {self.thresholds}")
print("Press Ctrl+C to stop monitoring\n")
try:
while True:
metrics = self.get_system_metrics()
alerts = self.check_thresholds(metrics)
# Display current metrics
print(f"[{metrics['timestamp']}] "
f"CPU: {metrics['cpu']:.1f}% | "
f"Memory: {metrics['memory']:.1f}% | "
f"Disk: {metrics['disk']:.1f}%")
# Check for alerts
for resource, is_alert in alerts.items():
if is_alert:
self.send_alert(resource, metrics[resource])
time.sleep(interval)
except KeyboardInterrupt:
print("\nMonitoring stopped.")
# Example usage
if __name__ == "__main__":
# Configure alert thresholds (percentage values)
thresholds = {
'cpu': 80.0,
'memory': 85.0,
'disk': 90.0
}
# Optional email configuration for alerts
# email_config = {
# 'smtp_server': 'smtp.gmail.com',
# 'smtp_port': 587,
# 'sender': 'your_email@gmail.com',
# 'password': 'your_password',
# 'recipient': 'admin@company.com'
# }
# Initialize and start monitoring
monitor = SystemMonitor(thresholds) # Add email_config if needed
monitor.run_monitoring(interval=3) # Check every 3 seconds
This real-time system resource monitor continuously tracks CPU usage, memory consumption, and disk space utilization on your system. When any resource exceeds the configured threshold, it triggers an alert - either printing to the console or sending an email notification.
The script uses the psutil library to efficiently collect system metrics and includes intelligent alerting that prevents spam by limiting notifications to once every 5 minutes per resource. Key features include:
System administrators and developers often need to monitor server health to prevent performance degradation or outages. This tool provides an automated way to track resource usage and get immediate notifications when problems arise. Rather than manually checking system stats, you can set it up to run continuously and alert you only when action is needed.
This is particularly valuable for:
pip install psutil
Save the code to a file (e.g., system_monitor.py)
thresholds dictionary
(Optional) Configure email alerts by uncommenting and filling the email_config dictionary
python system_monitor.py
To stop monitoring, press Ctrl+C. The script will clean up and exit gracefully.
For production use, consider running this as a background service or cron job to ensure continuous monitoring. You can adjust the monitoring interval (default 3 seconds) to balance between responsiveness and system overhead.