How to Monitor VDS Disk Space with a Script?

Maintaining sufficient free disk space on your VDS is a critical task for ensuring the stable operation of services and preventing failures. In this article, we’ll look at how to create and configure scripts to monitor disk space on your VDS so you can respond quickly to problems that arise. We’ll cover various approaches, from simple bash scripts to more complex solutions using Python and sending notifications.

Contents:

Monitoring with Bash and the df Command

The easiest and fastest way to monitor free disk space is to use the df command in a bash script. df (disk free) displays information about the disk space usage of file systems. We can use it in conjunction with other commands to get specific data and set up alerts.

Example 1: Simple script to check free space

#!/bin/bash

# Disk partition to monitor
DISK="/"

# Threshold for free space in percent (e.g., 10%)
THRESHOLD=10

# Get the percentage of disk usage
USAGE=$(df -h "$DISK" | awk 'NR==2{print $5}' | tr -d '%')

# Check if the threshold is exceeded
if [ "$USAGE" -gt $(expr 100 - $THRESHOLD) ]; then
  echo "Warning! Less than $THRESHOLD% free space left on disk $DISK."
fi

This script does the following:

  • Defines the disk partition to monitor (DISK="/").
  • Sets the free space threshold in percent (THRESHOLD=10).
  • Uses df -h "$DISK" to get disk usage information in a human-readable format.
  • Uses awk 'NR==2{print $5}' to extract the percentage of disk usage from the second line of the df output (where the partition information is located).
  • tr -d '%' removes the percent sign from the resulting string.
  • Compares the usage percentage with the threshold. If the usage percentage exceeds 100 - $THRESHOLD, it outputs a warning.

Example 2: More detailed script with output of free space information in gigabytes

#!/bin/bash

# Disk partition to monitor
DISK="/"

# Free space threshold in gigabytes
THRESHOLD=5

# Get free space in gigabytes
FREE_GB=$(df -h "$DISK" | awk 'NR==2{print $4}')

# Remove the letter 'G' from the value
FREE_GB_NUM=$(echo "$FREE_GB" | sed 's/G//')

# Check if the free space is less than the threshold
if (( $(echo "$FREE_GB_NUM > $THRESHOLD" | bc -l) )); then
  echo "Warning! Less than $THRESHOLD GB of free space left on disk $DISK. Currently free: $FREE_GB"
fi

This script does the same thing, but uses gigabytes instead of percentages, which can be more visual:

  • Gets free space in gigabytes using df -h "$DISK" | awk 'NR==2{print $4}'.
  • Removes the letter ‘G’ from the resulting value using sed 's/G//'.
  • Uses bc -l to compare floating-point numbers, as df -h can output values with a decimal point.
  • Outputs a warning if the free space is less than the threshold.

Example 3: Monitoring multiple disk partitions

#!/bin/bash

# Disk partitions to monitor
DISKS=("/")

# Free space threshold in percent
THRESHOLD=10

# Iterate over disk partitions
for DISK in ${DISKS[@]}; do
  # Get the percentage of disk usage
  USAGE=$(df -h "$DISK" | awk 'NR==2{print $5}' | tr -d '%')

  # Check if the threshold is exceeded
  if [ "$USAGE" -gt $(expr 100 - $THRESHOLD) ]; then
    echo "Warning! Less than $THRESHOLD% free space left on disk $DISK."
  fi
done

In this example, the script iterates over multiple disk partitions specified in the DISKS array and performs the check for each of them.

To automate the execution of the script, add it to cron. For example, to run the script every 5 minutes, add the following line to crontab:

*/5 * * * * /path/to/your/script.sh

Replace /path/to/your/script.sh with the actual path to your script.

Expert Tip: Don’t forget to add logging to your monitoring scripts. This will help you track the history of changes and identify long-term trends in disk space usage.

Ivan Petrov, System Administrator

Monitoring with Python and the psutil Library

Python provides a more flexible and powerful approach to disk space monitoring, especially using the psutil (process and system utilities) library. psutil allows you to get information about the system, including disk usage, in a convenient format for processing.

Example 1: Simple Python script to check free space

import psutil

# Disk partition to monitor
DISK="/"

# Free space threshold in percent
THRESHOLD = 10

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get the percentage of disk usage
usage_percent = disk_usage.percent

# Check if the threshold is exceeded
if usage_percent > (100 - THRESHOLD):
    print(f"Warning! Less than {THRESHOLD}% free space left on disk {DISK}. Used: {usage_percent}%")

This script does the following:

  • Imports the psutil library.
  • Defines the disk partition to monitor (DISK="/").
  • Sets the free space threshold in percent (THRESHOLD = 10).
  • Uses psutil.disk_usage(DISK) to get disk usage information.
  • Extracts the percentage of disk usage from the disk_usage object.
  • Compares the usage percentage with the threshold and outputs a warning if the threshold is exceeded.

Example 2: Python script with output of free space information in gigabytes

import psutil

# Disk partition to monitor
DISK="/"

# Free space threshold in gigabytes
THRESHOLD = 5

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get free space in gigabytes
free_gb = disk_usage.free / (2**30)  # Convert bytes to GB

# Check if the free space is less than the threshold
if free_gb < THRESHOLD:
    print(f"Warning! Less than {THRESHOLD} GB of free space left on disk {DISK}. Free: {free_gb:.2f} GB")

This script shows how to get and output free space in gigabytes. Note the conversion of bytes to gigabytes (free_gb = disk_usage.free / (2**30)) and the formatting of the output to display two decimal places ({free_gb:.2f}).

Example 3: Monitoring multiple disk partitions with Python

import psutil

# Disk partitions to monitor
DISKS = ["/", "/home"]

# Free space threshold in percent
THRESHOLD = 10

# Iterate over disk partitions
for DISK in DISKS:
    try:
        # Get disk usage information
        disk_usage = psutil.disk_usage(DISK)

        # Get the percentage of disk usage
        usage_percent = disk_usage.percent

        # Check if the threshold is exceeded
        if usage_percent > (100 - THRESHOLD):
            print(f"Warning! Less than {THRESHOLD}% free space left on disk {DISK}. Used: {usage_percent}%")
    except FileNotFoundError:
        print(f"Disk partition {DISK} not found.")

In this example, the script iterates over a list of disk partitions and performs the check for each of them. Note the try...except block, which handles the case when a disk partition is not found.

To run a Python script, you can also use cron. For example, to run the script every 5 minutes, add the following line to crontab:

*/5 * * * * /usr/bin/python3 /path/to/your/script.py

Replace /usr/bin/python3 with the path to your Python interpreter, and /path/to/your/script.py with the actual path to your script.

FunctionDescription
psutil.disk_usage(path)Returns an object with disk usage information for the specified path.
disk_usage.totalTotal size of the disk partition in bytes.
disk_usage.usedUsed disk space in bytes.
disk_usage.freeFree disk space in bytes.
disk_usage.percentPercentage of disk usage.

Setting Up Email Notifications

To respond quickly to disk space issues, you need to set up email notifications. We can add this functionality to our scripts using various tools and libraries.

Example 1: Sending email notifications using the mail command (bash)

#!/bin/bash

# Disk partition to monitor
DISK="/"

# Free space threshold in percent
THRESHOLD=10

# Get the percentage of disk usage
USAGE=$(df -h "$DISK" | awk 'NR==2{print $5}' | tr -d '%')

# Check if the threshold is exceeded
if [ "$USAGE" -gt $(expr 100 - $THRESHOLD) ]; then
  SUBJECT="Warning! Low disk space on $DISK"
  BODY="Less than $THRESHOLD% free space left on disk $DISK. Used: $USAGE%"
  echo "$BODY" | mail -s "$SUBJECT" your_email@example.com
fi

This script sends an email using the mail command if the disk usage threshold is exceeded. Replace your_email@example.com with your email address.

Note: To use the mail command on your VDS, you may need to install and configure a mail server (e.g., Postfix). If the mail server is not configured, sending emails may not work.

Example 2: Sending email notifications using the smtplib library (Python)

import psutil
import smtplib
from email.mime.text import MIMEText

# Disk partition to monitor
DISK="/"

# Free space threshold in percent
THRESHOLD = 10

# Your email address and password
SENDER_EMAIL = "your_email@example.com"
SENDER_PASSWORD = "your_password"

# Recipient email address
RECEIVER_EMAIL = "recipient_email@example.com"

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get the percentage of disk usage
usage_percent = disk_usage.percent

# Check if the threshold is exceeded
if usage_percent > (100 - THRESHOLD):
    SUBJECT = f"Warning! Low disk space on {DISK}"
    BODY = f"Less than {THRESHOLD}% free space left on disk {DISK}. Used: {usage_percent}%"

    # Create a MIME object
    msg = MIMEText(BODY)
    msg['Subject'] = SUBJECT
    msg['From'] = SENDER_EMAIL
    msg['To'] = RECEIVER_EMAIL

    # Send the email
    try:
        with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
            smtp.login(SENDER_EMAIL, SENDER_PASSWORD)
            smtp.send_message(msg)
        print("Email sent successfully!")
    except Exception as e:
        print(f"Error sending email: {e}")

This script sends an email using the smtplib library. Replace your_email@example.com, your_password, and recipient_email@example.com with your credentials and recipient address. This example uses the Gmail SMTP server. You may need to enable «less secure app access» in your Google account settings.

Important: Storing passwords in scripts is not secure. Consider using environment variables or other more secure ways to store credentials.

Example 3: Sending notifications via Telegram Bot (Python)

import psutil
import telegram

# Disk partition to monitor
DISK="/"

# Free space threshold in percent
THRESHOLD = 10

# Your Telegram bot token
TELEGRAM_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN"

# Your Telegram chat ID
TELEGRAM_CHAT_ID = "YOUR_TELEGRAM_CHAT_ID"

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get the percentage of disk usage
usage_percent = disk_usage.percent

# Check if the threshold is exceeded
if usage_percent > (100 - THRESHOLD):
    MESSAGE = f"Warning! Less than {THRESHOLD}% free space left on disk {DISK}. Used: {usage_percent}%"

    # Send a message via Telegram bot
    try:
        bot = telegram.Bot(token=TELEGRAM_TOKEN)
        bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=MESSAGE)
        print("Message sent successfully to Telegram!")
    except Exception as e:
        print(f"Error sending message to Telegram: {e}")

This script sends a notification via Telegram bot. You will need to create a Telegram bot and get its token, as well as find out your chat ID. Replace YOUR_TELEGRAM_BOT_TOKEN and YOUR_TELEGRAM_CHAT_ID with your values.

Advanced Monitoring and Logging Capabilities

For more effective disk space monitoring, it is recommended to use advanced features such as logging, historical data analysis, and integration with monitoring systems.

Example 1: Logging disk space usage (Python)

import psutil
import datetime
import logging

# Configure logging
logging.basicConfig(filename="/var/log/disk_space.log", level=logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s')

# Disk partition to monitor
DISK="/"

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get the percentage of disk usage
usage_percent = disk_usage.percent

# Log the information
logging.info(f"Disk usage {DISK}: {usage_percent}%")

# Check if the threshold is exceeded (optional, you can only log if the threshold is exceeded)
THRESHOLD = 90
if usage_percent > THRESHOLD:
    logging.warning(f"Warning! More than {THRESHOLD}% of space used on disk {DISK}: {usage_percent}%")

This script adds logging of disk space usage to the file /var/log/disk_space.log. It writes disk usage information each time it runs. Also, if disk usage exceeds a specified threshold (in this case, 90%), a warning is written.

Example 2: Sending data to a monitoring system (e.g., Zabbix) (Python)

import psutil
import subprocess

# Disk partition to monitor
DISK="/"

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get the percentage of disk usage
usage_percent = disk_usage.percent

# Send data to Zabbix using zabbix_sender
zabbix_server = "your_zabbix_server"
zabbix_host = "your_zabbix_host"
zabbix_key = "disk.usage.percent"

command = f"zabbix_sender -z {zabbix_server} -s {zabbix_host} -k {zabbix_key} -o {usage_percent}"
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()

if process.returncode == 0:
    print(f"Data sent successfully to Zabbix: {stdout.decode()}")
else:
    print(f"Error sending data to Zabbix: {stderr.decode()}")

This script sends the percentage of disk usage to the Zabbix monitoring system using the zabbix_sender utility. Replace your_zabbix_server, your_zabbix_host, and disk.usage.percent with the appropriate values for your Zabbix system. zabbix_sender must be installed and configured on your VDS.

Example 3: Analyzing historical data with Grafana and InfluxDB

To analyze historical data on disk space usage, you can use a combination of InfluxDB (for data storage) and Grafana (for visualization). First, you need to configure InfluxDB and Grafana. Then, you can modify the monitoring script to write data to InfluxDB. Example (Python):

import psutil
from influxdb import InfluxDBClient

# Disk partition to monitor
DISK="/"

# InfluxDB parameters
INFLUXDB_HOST = "your_influxdb_host"
INFLUXDB_PORT = 8086
INFLUXDB_DATABASE = "disk_monitoring"

# Get disk usage information
disk_usage = psutil.disk_usage(DISK)

# Get the percentage of disk usage
usage_percent = disk_usage.percent

# Create an InfluxDB client
client = InfluxDBClient(host=INFLUXDB_HOST, port=INFLUXDB_PORT, database=INFLUXDB_DATABASE)

# Form data for writing
data = [
    {
        "measurement": "disk_usage",
        "tags": {
            "disk": DISK
        },
        "fields": {
            "usage_percent": usage_percent
        }
    }
]

# Write data to InfluxDB
try:
    client.write_points(data)
    print("Data written successfully to InfluxDB")
except Exception as e:
    print(f"Error writing data to InfluxDB: {e}")

This script writes the percentage of disk usage to the InfluxDB database. Replace your_influxdb_host and disk_monitoring with the appropriate values for your InfluxDB system. After that, you can create a dashboard in Grafana to visualize this data.

These examples show how you can extend basic disk space monitoring to get a more complete picture and automate responses to problems.