<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rubin Mosepinza</title>
    <description>The latest articles on DEV Community by Rubin Mosepinza (@rubin_mosepinza_14aa9d6ca).</description>
    <link>https://dev.to/rubin_mosepinza_14aa9d6ca</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3165495%2Ff7d7d712-b7eb-479d-992e-fc2d8bda0a75.JPG</url>
      <title>DEV Community: Rubin Mosepinza</title>
      <link>https://dev.to/rubin_mosepinza_14aa9d6ca</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rubin_mosepinza_14aa9d6ca"/>
    <language>en</language>
    <item>
      <title>How to Build a Lightweight System Monitoring and Alert Script on linux Using Python and MSMTP</title>
      <dc:creator>Rubin Mosepinza</dc:creator>
      <pubDate>Mon, 19 May 2025 16:45:37 +0000</pubDate>
      <link>https://dev.to/rubin_mosepinza_14aa9d6ca/how-to-build-a-lightweight-system-monitoring-and-alert-script-on-linux-using-python-and-msmtp-2fkp</link>
      <guid>https://dev.to/rubin_mosepinza_14aa9d6ca/how-to-build-a-lightweight-system-monitoring-and-alert-script-on-linux-using-python-and-msmtp-2fkp</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Monitoring your server’s vital resources like CPU, memory, and disk is crucial for performance, uptime, and system health. While advanced solutions like Zabbix and Prometheus exist, they can be overkill for smaller servers or specific use cases.&lt;/p&gt;

&lt;p&gt;In this article, you’ll learn how to create a lightweight monitoring script in Python, which can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collect system metrics (CPU, RAM, Disk)&lt;/li&gt;
&lt;li&gt;Automatically send email alerts when thresholds are exceeded&lt;/li&gt;
&lt;li&gt;Log alerts to a file&lt;/li&gt;
&lt;li&gt;Run silently when everything is fine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s perfect for all linux-based systems and uses &lt;strong&gt;msmtp&lt;/strong&gt; to send alert emails via Gmail.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Requirements&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To get started, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3 installed&lt;/li&gt;
&lt;li&gt;The psutil library (for system metrics)&lt;/li&gt;
&lt;li&gt;msmtp installed and configured with Gmail&lt;/li&gt;
&lt;li&gt;Basic knowledge of bash and cron (optional for automation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Installing Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install psutil in a virtual environment (recommended)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install python3-venv
python3 -m venv env
source env/bin/activate
pip install psutil
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install and configure msmtp:&lt;br&gt;
&lt;code&gt;sudo apt install msmtp msmtp-mta&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create or edit the ~/.msmtprc file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defaults
auth           on
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        ~/.msmtp.log

account        gmail
host           smtp.gmail.com
port           587
from           your@gmail.com
user           your@gmail.com
password       gmail_password

account default : gmail

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t forget to secure the password file:&lt;br&gt;
&lt;code&gt;chmod 600 ~/.msmtprc&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The Monitoring Script&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Below is the Python script that does all the work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import psutil
import socket
import datetime
import subprocess


# Configuration


TO_EMAIL = "your@gmail.com"
FROM_EMAIL = "your@gmail.com"
CPU_THRESHOLD = 90
RAM_THRESHOLD = 10
DISK_THRESHOLD = 90


# Collect system metrics

def get_metrics():
    hostname = socket.gethostname()
    now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    cpu = psutil.cpu_percent(interval=1)
    ram = psutil.virtual_memory()
    disk = psutil.disk_usage('/')

    return {
        "hostname": hostname,
        "timestamp": now,
        "cpu": cpu,
        "ram": ram.percent,
        "ram_used": round(ram.used / (1024**3), 2),
        "ram_total": round(ram.total / (1024**3), 2),
        "disk": disk.percent,
        "disk_used": round(disk.used / (1024**3), 2),
        "disk_total": round(disk.total / (1024**3), 2)
    }


# Build email content

def format_email(metrics):
    issues = []
    if metrics["cpu"] &amp;gt; CPU_THRESHOLD:
        issues.append(f"CPU {metrics['cpu']}%")
    if metrics["ram"] &amp;gt; RAM_THRESHOLD:
        issues.append(f"RAM {metrics['ram']}%")
    if metrics["disk"] &amp;gt; DISK_THRESHOLD:
        issues.append(f"Disk {metrics['disk']}%")

    if issues:
        subject = f"[ALERT] {', '.join(issues)} on {metrics['hostname']}"
    else:
        subject = f"[INFO] System Stable - {metrics['hostname']}"

    message = f"""\ 
Subject: {subject}
From: Monitoring &amp;lt;{FROM_EMAIL}&amp;gt;
To: {TO_EMAIL}

Date       : {metrics['timestamp']}
Server     : {metrics['hostname']}

CPU     : {metrics['cpu']}% used
RAM     : {metrics['ram']}% used ({metrics['ram_used']} GB / {metrics['ram_total']} GB)
Disk    : {metrics['disk']}% used ({metrics['disk_used']} GB / {metrics['disk_total']} GB)
"""
    return message, bool(issues)


# Send the email using msmtp

def send_email(body):
    process = subprocess.Popen(
        ['msmtp', TO_EMAIL],
        stdin=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    stdout, stderr = process.communicate(input=body.encode())

    if process.returncode != 0:
        print("Failed to send email:", stderr.decode())
    else:
        print("Email sent successfully.")


# Log alerts locally
def log_alert(message):
    with open("monitoring.log", "a") as log:
        log.write(f"[{datetime.datetime.now()}]\n{message}\n{'-'*40}\n")


# Main

if __name__ == "__main__":
    metrics = get_metrics()
    email_body, alert_needed = format_email(metrics)

    if alert_needed:
        send_email(email_body)
        log_alert(email_body)
    else:
        print(" System is stable. No alert sent.")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom Thresholds&lt;br&gt;
Adjust these values as needed in the configuration section of the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CPU_THRESHOLD = 90
RAM_THRESHOLD = 10
DISK_THRESHOLD = 90

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAM 85%+ is usually a sign of overload.&lt;/li&gt;
&lt;li&gt;CPU usage above 90% for more than a few seconds can be critical.&lt;/li&gt;
&lt;li&gt;Disk usage near 100% can cause application crashes
Running and Testing
Make it executable:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x monitor.py
./monitor.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also schedule it with cron:&lt;br&gt;
&lt;code&gt;crontab -e&lt;/code&gt;&lt;br&gt;
Add this to run every 10 minutes:&lt;br&gt;
&lt;code&gt;*/10 * * * * /path/to/monitor.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67lgj0dcxaxgnatz6axw.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F67lgj0dcxaxgnatz6axw.JPG" alt="Image description" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log file output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each alert is saved in a file named monitoring.log with the timestamp and full details. This helps with auditing and tracking repeated issues over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With just a few lines of Python and the power of msmtp, you’ve built a compact monitoring system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keeps track of key system metrics&lt;/li&gt;
&lt;li&gt;Sends real-time email alerts&lt;/li&gt;
&lt;li&gt;Stores logs for later review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This solution is perfect for home servers, Raspberry Pi setups, low-resource VPSs, or developers who want full control over their monitoring stack.&lt;/p&gt;

&lt;p&gt;You can extend it further by adding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load average and uptime&lt;/li&gt;
&lt;li&gt;Service availability checks (e.g., web server, database)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;THANK YOU!&lt;/p&gt;

</description>
      <category>python</category>
      <category>linux</category>
      <category>monitoring</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
