Docker Container Monitoring Script
This Python script monitors Docker containers for resource usage (CPU and memory) and sends alert emails when usage exceeds the specified thresholds.
Features
- Monitors all running Docker containers.
- Calculates CPU and memory usage for each container.
- Sends email alerts when CPU or memory usage exceeds defined thresholds.
- Easy to configure thresholds and email settings.
Table of Contents
Prerequisites
- Python: Install Python 3.x on your system.
- Docker: Ensure Docker is installed and running. The script uses the Docker SDK for Python.
- Python Libraries: Install the required libraries using
pip:pip3 install docker
Configuration
sender_email: Your email address.password: Your email app password (set up an app-specific password here for Gmail).recipient_email: Add recipient details as a list of dictionaries with name and email.
- Adjust
CPU_THRESHOLDandMEMORY_THRESHOLDto set the percentage usage limits for alerts:CPU_THRESHOLD = 10.0 # CPU usage threshold in percent MEMORY_THRESHOLD = 10.0 # Memory usage threshold in percent
-
Environment Setup
Setting Up a Virtual Environment (Optional)
It’s recommended to use a virtual environment for running the script. Here’s how you can set it up:
python3 -m venv env source env/bin/activate # For Linux/Mac env\Scripts\activate # For Windows
Script
import docker
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import logging
import json
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
recipient_email = [
{'name': 'abc', 'email': 'abc@gmail.com'}
]
sender_email = "abc@gmail.com"
password = "" # https://myaccount.google.com/u/1/apppasswords
host = "smtp.gmail.com"
port = 587
# Adjust the THRESHOLD as required.
CPU_THRESHOLD = 10.0 # in percent
MEMORY_THRESHOLD = 10.0 # in percent
# Initialize Docker client
docker_client = docker.from_env()
def monitor_containers():
try:
for container in docker_client.containers.list():
try:
# Fetch container stats
stats = container.stats(stream=False)
# CPU usage calculation
cpu_delta = stats["cpu_stats"]["cpu_usage"]["total_usage"] - stats["precpu_stats"]["cpu_usage"]["total_usage"]
system_delta = stats["cpu_stats"]["system_cpu_usage"] - stats["precpu_stats"]["system_cpu_usage"]
cpu_usage = (cpu_delta / system_delta) * 100 if system_delta > 0 else 0
# Memory usage calculation
memory_usage = stats["memory_stats"]["usage"] / stats["memory_stats"]["limit"] * 100
logging.info(f"Container: {container.name}, CPU: {cpu_usage:.2f}%, Memory: {memory_usage:.2f}%")
# Check thresholds and send alerts
if cpu_usage > CPU_THRESHOLD:
send_email_alert(container.name, "CPU", cpu_usage)
if memory_usage > MEMORY_THRESHOLD:
send_email_alert(container.name, "Memory", memory_usage)
except KeyError as e:
logging.warning(f"Container: {container.name} - Missing key in stats: {e}")
except Exception as e:
logging.error(f"Error monitoring container '{container.name}': {e}")
except Exception as e:
logging.error(f"Failed to monitor containers: {e}")
def send_email_alert(container_name, resource_type, usage):
try:
logging.info("Connecting to SMTP server...")
with smtplib.SMTP(host=host, port=port) as smtp_server:
smtp_server.starttls()
smtp_server.login(user=sender_email, password=password)
logging.info("TLS connection established")
for recipient in recipient_email:
message = MIMEMultipart('alternative')
message['Subject'] = f"High {resource_type} Usage Alert: {container_name}"
message['To'] = recipient['email']
message['From'] = sender_email
body = f"The container '{container_name}' is using {usage:.2f}% {resource_type}. Please investigate."
email_template = f"""\
Greetings {recipient['name']},
{body}
Regards,
Monitoring System
"""
mail_template = MIMEText(email_template, "plain")
message.attach(mail_template)
smtp_server.sendmail(to_addrs=recipient['email'], from_addr=sender_email, msg=message.as_string())
logging.info(f"Email sent to {recipient['email']}")
except smtplib.SMTPAuthenticationError as e:
logging.error(f"Authentication failed. Check your username and password. {e}")
except smtplib.SMTPConnectError as e:
logging.error(f"Failed to connect to the SMTP server. Check your internet connection or server details. {e}")
except smtplib.SMTPException as e:
logging.error(f"An SMTP error occurred: {e}")
except Exception as e:
logging.error(f"Exception occurred: {e}")
if __name__ == "__main__":
logging.info("Starting Docker container monitoring...")
monitor_containers()
logging.info("Monitoring complete.")
Usage
- Run the Script: Execute the script using Python:
python3 docker_monitor.py - Email Alerts:
- The script will send an email alert if any container exceeds the defined resource thresholds.
Example Output
Log Output
2024-12-30 14:23:45 - INFO - Starting Docker container monitoring...
2024-12-30 14:23:46 - INFO - Container: nginx, CPU: 15.32%, Memory: 7.45%
2024-12-30 14:23:46 - INFO - Email sent to recipient@example.com
2024-12-30 14:23:46 - INFO - Monitoring complete.
Email Example
Subject: High CPU Usage Alert: nginx Body:
Greetings Jatin Sharma,
The container 'nginx' is using 15.32% CPU. Please investigate.
Regards,
Monitoring System
Troubleshooting
SMTP Authentication Error:
- Ensure the
sender_emailandpasswordare correct. - Use app-specific passwords for Gmail accounts.
Docker SDK Issues:
Don’t save the python script as docker.py, because it will endup with
circular import error.
- Verify that Docker is installed and running on your system.
- Check if your user has permission to interact with Docker. If not, run the script as a user with appropriate permissions or add your user to the Docker group:
sudo usermod -aG docker $USER