Bash Script for Monitoring CPU, Memory, Disk

A central server is connected to three laptops displaying code, representing a network or data processing system.

Want to prevent VPS crashes and performance issues? A simple bash script can help you monitor CPU, memory, and disk usage in real-time, send alerts when thresholds are exceeded, and automate resource checks.

Here’s what you’ll learn in this guide:

  • How to create a resource monitoring script
  • Set thresholds for CPU, memory, and disk usage
  • Automate alerts and log management
  • Schedule the script to run at regular intervals

👉 Facing VPS Performances Issue?  Start with our ultimate troubleshooting guide Why My VPS Is Slow

Quick Overview:

  • CPU Monitoring: Tracks usage and sends alerts if it exceeds a set percentage (e.g., 80%).
  • Memory Monitoring: Adjusts for cached memory and triggers alerts when usage is too high.
  • Disk Monitoring: Monitors space usage, logs details, and alerts on threshold breaches.

This guide is designed for VPS environments with root access and works seamlessly with platforms like VPS.us.

Basic Script Setup

Set up your monitoring script by creating the file, adjusting its permissions, and deciding where to store it.

Create the Script File

To get started, create the script using nano:

nano /usr/local/bin/monitor.sh

Insert the following basic structure into your script:

#!/bin/bash

# Script: VPS Resource Monitor
# Description: Monitors CPU, memory, and disk usage

# Script variables
THRESHOLD_CPU=80
THRESHOLD_MEM=90
THRESHOLD_DISK=85

Set File Permissions

Make the script executable with this command:

chmod 700 /usr/local/bin/monitor.sh

This sets permissions as follows:

  • Owner (root): read, write, and execute
  • Group: no permissions
  • Others: no permissions

These settings ensure only root can access or modify the script, keeping your VPS secure.

Choose Script Location

Here are some directory options for storing your script:

DirectoryPurposeBest For
/usr/local/bin/System-wide scriptsProduction monitoring
/root/scripts/Root-only accessDevelopment testing
/opt/monitoring/Dedicated monitoringEnterprise setups

For most VPS setups, /usr/local/bin/ is a solid choice because it:

  • Is included in the system PATH
  • Adheres to Linux filesystem hierarchy standards
  • Keeps custom scripts separate from system binaries
  • Remains intact during system updates

Before proceeding, ensure the parent directory has strict permissions (755 or lower) to protect your monitoring script.

Next, dive into gathering and formatting CPU usage data.

CPU Usage Monitoring

A computer displays analytics graphs on a desk with a plant, lamp, and clock showing 16:75 in a sunlit room.

Keep track of your VPS’s CPU usage by gathering, organizing, and analyzing processor performance data.

Get CPU Data

Use the top command to collect CPU statistics:

get_cpu_usage() {
    cpu_idle=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/")
    cpu_usage=$(echo "100 - $cpu_idle" | bc)
    echo $cpu_usage
}

This command runs top in batch mode (-bn1) to take a single snapshot of CPU usage data.

Format CPU Output

Organize the CPU usage data for clear and readable logs:

format_cpu_output() {
    local usage=$1
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    printf "%-25s CPU Usage: %6.2f%%\n" "$timestamp" "$usage"
}

The output includes a timestamp in US format (YYYY-MM-DD HH:MM:SS), aligns columns for better readability, and shows CPU usage with two-decimal precision.

Set CPU Limits

Define a CPU usage threshold and implement alerting logic:

check_cpu_limits() {
    local usage=$1
    if (( $(echo "$usage > $THRESHOLD_CPU" | bc -l) )); then
        local message="WARNING: CPU usage at ${usage}% exceeds ${THRESHOLD_CPU}% threshold"
        logger -t vps-monitor "$message"

        if [ -x /usr/bin/mail ]; then
            echo "$message" | mail -s "High CPU Usage Alert" root
        fi
    fi
}

Key details of the threshold system:

  • The $THRESHOLD_CPU variable (default is 80%) determines the limit.
  • Alerts are logged through syslog.
  • Email notifications are sent if the mail utility is available.

Place these functions in your script after defining variables but before any execution logic. Test the script manually to ensure everything works as expected before automating the checks.

Memory Usage Monitoring

Keep track of VPS memory usage with simple bash functions.

Get Memory Data

Use the free command to gather memory statistics:

get_memory_data() {
    local mem_info=$(free -m)
    local total=$(echo "$mem_info" | awk '/Mem:/ {print $2}')
    local used=$(echo "$mem_info" | awk '/Mem:/ {print $3}')
    local free=$(echo "$mem_info" | awk '/Mem:/ {print $4}')
    local cached=$(echo "$mem_info" | awk '/Mem:/ {print $6}')

    echo "$total:$used:$free:$cached"
}

The -m option ensures memory data is displayed in MB for easier readability.

Calculate Memory Usage

Turn the raw memory data into meaningful usage percentages:

calculate_memory_usage() {
    local mem_data=$(get_memory_data)
    local total=$(echo $mem_data | cut -d':' -f1)
    local used=$(echo $mem_data | cut -d':' -f2)
    local cached=$(echo $mem_data | cut -d':' -f4)

    # Adjust usage by subtracting cached memory
    local actual_used=$((used - cached))
    local usage_percent=$(echo "scale=2; ($actual_used * 100) / $total" | bc)

    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    printf "%-25s Memory Usage: %6.2f%% (Total: %dMB, Used: %dMB)\n" \
           "$timestamp" "$usage_percent" "$total" "$actual_used"
}

This function accounts for cached memory and provides a timestamped output of memory usage.

Set Memory Limits

Keep an eye on memory thresholds and trigger alerts when needed:

check_memory_limits() {
    local usage=$1
    local threshold=${THRESHOLD_MEM:-90}

    if (( $(echo "$usage > $threshold" | bc -l) )); then
        local message="ALERT: Memory usage at ${usage}% exceeds ${threshold}% threshold"
        logger -t vps-monitor "$message"

        if [ -x /usr/bin/mail ]; then
            echo "$message" | mail -s "High Memory Usage Alert" root
        fi

        # Optional: Log detailed memory stats
        free -m >> /var/log/memory_alerts.log
    fi
}

This system includes:

  • A configurable threshold to suit your needs
  • Logging through syslog for tracking
  • Email notifications if mail is available
  • Optional logging of detailed memory statistics for further analysis

Combine these memory monitoring functions with CPU and disk checks to create a comprehensive resource monitoring solution./banner/inline/?id=sbb-itb-0ad7fa2

Disk Space Monitoring

Keep an eye on your disk space with bash functions that provide clear storage usage details.

Get Disk Data

Use this function to gather disk usage stats with the df command:

get_disk_data() {
    local mount_point=${1:-"/"}
    local disk_info=$(df -h "$mount_point" | tail -n 1)
    local total=$(echo "$disk_info" | awk '{print $2}')
    local used=$(echo "$disk_info" | awk '{print $3}')
    local available=$(echo "$disk_info" | awk '{print $4}')
    local usage_percent=$(echo "$disk_info" | awk '{print $5}' | tr -d '%')

    echo "$total:$used:$available:$usage_percent"
}

This function takes a mount point as an argument (default is ‘/’) and outputs disk metrics in a simple format.

Get Space Metrics

Turn raw disk data into a user-friendly format:

format_disk_metrics() {
    local mount_point=${1:-"/"}
    local disk_data=$(get_disk_data "$mount_point")
    local total=$(echo "$disk_data" | cut -d':' -f1)
    local used=$(echo "$disk_data" | cut -d':' -f2)
    local available=$(echo "$disk_data" | cut -d':' -f3)
    local usage_percent=$(echo "$disk_data" | cut -d':' -f4)

    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    printf "%-25s Disk Usage (%s): %s%% (Total: %s, Used: %s, Free: %s)\n" \
           "$timestamp" "$mount_point" "$usage_percent" "$total" "$used" "$available"
}

This function generates a timestamped report with readable storage values.

Set Space Limits

Monitor disk usage and trigger alerts when it crosses a defined threshold:

check_disk_limits() {
    local mount_point=${1:-"/"}
    local disk_data=$(get_disk_data "$mount_point")
    local usage_percent=$(echo "$disk_data" | cut -d':' -f4)
    local threshold=${THRESHOLD_DISK:-85}

    if [ "$usage_percent" -gt "$threshold" ]; then
        local message="ALERT: Disk usage for $mount_point at ${usage_percent}% exceeds ${threshold}% threshold"
        logger -t vps-monitor "$message"

        if [ -x /usr/bin/mail ]; then
            echo "$message" | mail -s "High Disk Usage Alert" root
        fi

        # Log detailed disk information
        df -h "$mount_point" >> /var/log/disk_alerts.log
        du -h --max-depth=1 "$mount_point" >> /var/log/disk_alerts.log
    fi
}

This function uses a default threshold of 85%. If disk usage exceeds this limit, it logs the details, sends an alert, and records additional information for troubleshooting.

Combine these disk monitoring tools with CPU and memory checks to create a complete resource monitoring solution for your VPS.

Combine Monitoring Tasks

Integrate various monitoring components into one streamlined solution.

Merge Monitoring Functions

Develop a primary function to manage all resource checks:

monitor_all_resources() {
    local mount_point=${1:-"/"}

    touch "$log_file"

    # Execute all checks
    check_cpu_usage
    check_memory_usage
    check_disk_limits "$mount_point"

    # Add resource reports to the log
    {
        format_cpu_metrics
        format_memory_metrics
        format_disk_metrics "$mount_point"
    } >> "$log_file"
}

This function simplifies monitoring by organizing all checks in one place, making it easier to manage and expand.

Add Timestamps

Standardize log entries with timestamps:

log_with_timestamp() {
    local message="$1"
    local log_file="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S %Z')

    echo "[$timestamp] $message" >> "$log_file"
}

rotate_logs() {
    local log_file="$1"
    local max_size=10485760  # 10MB in bytes

    if [ -f "$log_file" ] && [ $(stat -f%z "$log_file") -gt $max_size ]; then
        mv "$log_file" "${log_file}.$(date +%Y%m%d)"
        gzip "${log_file}.$(date +%Y%m%d)"
    fi
}

Timestamped logs ensure clarity and help with troubleshooting, while automatic log rotation keeps files manageable.

Set Up Alerts

After combining resource checks and logging, centralize notifications for streamlined alert management:

send_alert() {
    local alert_type="$1"
    local message="$2"
    local threshold="$3"
    local current_value="$4"

    local alert_log="/var/log/vps_alerts.log"
    local alert_message="ALERT [$alert_type]: $message (Threshold: $threshold, Current: $current_value)"

    # Log the alert
    log_with_timestamp "$alert_message" "$alert_log"

    # Send email if configured
    if [ -x /usr/bin/mail ] && [ -n "$ALERT_EMAIL" ]; then
        echo "$alert_message" | mail -s "VPS Monitor Alert: $alert_type" "$ALERT_EMAIL"
    fi

    logger -t vps-monitor "$alert_message"
}

Centralize alert thresholds in a configuration file for easy updates:

cat > /etc/vps_monitor.conf << EOF
CPU_THRESHOLD=85
MEMORY_THRESHOLD=90
DISK_THRESHOLD=85

ALERT_EMAIL="admin@yourdomain.com"
CHECK_INTERVAL=300

LOG_FILE="/var/log/vps_monitor.log"
ALERT_LOG="/var/log/vps_alerts.log"
EOF

This setup makes it simple to adjust monitoring parameters without editing the script. The result is a cohesive monitoring system that tracks resource usage, organizes logs, and sends timely alerts when thresholds are exceeded.

🚨 Running into performance issues? Check our ultimate troubleshooting step by step guide (free)

Schedule the Script

To keep your monitoring process running smoothly, automate it with scheduled tasks.

Set Up Cron Jobs

Use crontab to schedule your monitoring script. Start by editing the crontab file:

*/5 * * * * /usr/local/bin/vps_monitor.sh >> /var/log/vps_monitor.log 2>&1

Alternatively, create a dedicated cron file at /etc/cron.d/vps_monitor:

# Execute monitoring every 5 minutes
*/5 * * * * root /usr/local/bin/vps_monitor.sh
# Rotate logs daily at midnight
0 0 * * * root /usr/local/bin/rotate_monitor_logs.sh

Configure Email Alerts

Set up email notifications for alerts by creating a configuration file:

cat > /etc/vps_monitor.mail << EOF
MAIL_SERVER="smtp.yourdomain.com"
MAIL_PORT="587"
MAIL_USER="monitor@yourdomain.com"
MAIL_PASS="your_secure_password"
RECIPIENTS="admin@yourdomain.com,oncall@yourdomain.com"
EOF

This ensures that alerts are sent to the specified recipients whenever an issue arises.

Define Check Intervals

Choose appropriate intervals for resource checks based on the type of resource being monitored:

Resource TypeCheck Interval
CPU Usage5 minutes
Memory Usage5 minutes
Disk Space30 minutes
Critical Services1 minute

Next, create a configuration file at /etc/vps_monitor.conf to set these intervals and thresholds:

# Resource check intervals (in seconds)
CPU_CHECK_INTERVAL=300
MEMORY_CHECK_INTERVAL=300
DISK_CHECK_INTERVAL=1800
SERVICE_CHECK_INTERVAL=60

# Alert thresholds
CPU_THRESHOLD=85
MEMORY_THRESHOLD=90
DISK_THRESHOLD=85

Adjust Monitoring Frequency Dynamically

Add logic to dynamically adjust monitoring frequency based on resource usage:

if [ "$current_cpu_usage" -gt "$CPU_THRESHOLD" ]; then
    CPU_CHECK_INTERVAL=60
    log_with_timestamp "Increased CPU monitoring frequency due to high usage" "$log_file"
fi

This approach ensures that critical resources are monitored more frequently during periods of high usage.

Wrapping Up

This guide covered how to set up and integrate custom monitoring scripts to keep an eye on CPU, memory, and disk usage. With a good monitoring script in place, you can spot and address performance issues on your VPS before they cause problems.

The script outlined here keeps tabs on system resources, sends automated alerts, and runs at configurable intervals. It’s designed to work seamlessly on a VPS.us-hosted VPS, which offers enterprise-grade hardware, full root access, and round-the-clock support.

Here’s what you’ll get:

  • Real-time monitoring of system resources
  • Custom alerts based on your chosen thresholds
  • Automated execution in the background
  • Detailed logs for troubleshooting issues

“Awesome Support! I’m new to the VPS world (came from a shared hosting) and the support had an incredible patience with me. I’ve contacted them tons of times and there was always someone there on the chat ready to help. Everything works like a charm. Thanks a Million!!!” – Diego, Buenos Aires

For a setup that balances performance and cost, the KVM2-US plan at $20/month (with 2 vCores and 2 GB RAM) is a solid choice. It’s capable of running your monitoring script alongside other applications while ensuring alerts remain responsive.

Facebook
Twitter
LinkedIn

Table of Contents

KVM VPS Running Anywhere in 2 minutes

Get started today

With VPS.US VPS Hosting you get all the features, tools

Image