Monitor tool resources per user?

Hi,

I’ve got Monitorix that gives some understanding of resource use server wide. But sometimes I find it hard to find which user(website) is using a lot of resources. Even triggering a OOM-kill sometimes.

So I wonder, what is a good monitor tool that also gives some insights of resources used per user?

apt install atop
atop
press u

apt install htop
htop
press u
select user and press enter

1 Like

Thank you. Yes this works great for debugging and the OOM-kill cause was found swiftly.

However, I was looking for some visual thing, like Monitorix or Netdata and then with the resource use split per user. But maybe this is not available and would cause a lot of drag on the server.

It’s more a nice to have, so see the impact per website on a server.

Had some time to spare and came up with this Python script.
You can run it as a service or in background.
WIll monitor CPU usage and will send an alert based on your settings.

Needs Python 3 and to be run from a root or similar level user.

import psutil
import time
import smtplib
from email.mime.text import MIMEText
from subprocess import Popen, PIPE

# Email configuration
SMTP_SERVER = 'smtp.your-email-server.com'
SMTP_PORT = 587
SMTP_USERNAME = 'your-email@example.com'
SMTP_PASSWORD = 'your-email-password'
EMAIL_FROM = 'your-email@example.com'
EMAIL_TO = 'recipient@example.com'
EMAIL_SUBJECT = 'High CPU Usage Alert'

# Monitoring parameters
CPU_THRESHOLD = 2  # CPU load threshold
MONITOR_INTERVAL = 60  # seconds between checks
ALERT_AFTER_MINUTES = 3  # Alert after 3 minutes

def get_cpu_load():    
    return psutil.getloadavg()[0]

def get_top_cpu_processes():    
    processes = []
    for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent']):
        try:
            proc_info = proc.info
            processes.append(proc_info)
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            continue
    # Sort by CPU usage
    processes = sorted(processes, key=lambda x: x['cpu_percent'], reverse=True)
    return processes

def send_email(body):   
    msg = MIMEText(body)
    msg['Subject'] = EMAIL_SUBJECT
    msg['From'] = EMAIL_FROM
    msg['To'] = EMAIL_TO

    with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
        server.starttls()
        server.login(SMTP_USERNAME, SMTP_PASSWORD)
        server.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())

def alert_if_needed():    
    high_load_counter = 0

    while True:
        load = get_cpu_load()
        print(f"Current load: {load}")

        if load > CPU_THRESHOLD:
            high_load_counter += 1
            print(f"High load detected for {high_load_counter} minute(s).")

            # If CPU usage is above threshold for more than ALERT_AFTER_MINUTES
            if high_load_counter >= ALERT_AFTER_MINUTES:
                print("Threshold exceeded, gathering process details...")
                processes = get_top_cpu_processes()

                # Create email body with process details
                body = f"CPU load has been above {CPU_THRESHOLD} for more than {ALERT_AFTER_MINUTES} minutes.\n"
                body += f"Current load: {load}\n\n"
                body += "Top CPU-consuming processes:\n"
                for proc in processes[:5]:  # Limit to top 5 processes
                    body += f"User: {proc['username']}, Process: {proc['name']} (PID: {proc['pid']}), CPU: {proc['cpu_percent']}%\n"
                
                # Send the email
                send_email(body)
                print("Alert email sent!")

                # Reset counter after sending the alert
                high_load_counter = 0
        else:
            high_load_counter = 0

        time.sleep(MONITOR_INTERVAL)

if __name__ == "__main__":
    alert_if_needed()

WIll get an email like:

CPU load has been above 2 for more than 3 minutes.
Current load: 4.4169921875

Top CPU-consuming processes:
User: root, Process: stress (PID: 3675424), CPU: 99.9%
User: root, Process: stress (PID: 3675425), CPU: 99.9%
User: root, Process: stress (PID: 3675422), CPU: 99.8%
User: root, Process: stress (PID: 3675423), CPU: 99.8%
User: root, Process: systemd (PID: 1), CPU: 5.2%

1 Like

Thanks for sharing!

That sounds pretty cool, gonne try that, thanks for sharing!