Monitor disk space with Uptime Kuma

2023-03-30 · 464 words · 3 minute read

I use Uptime Kuma as my self hosted monitoring solution and it worked perfectly find so far. But every now an then I run out of disk space on my Hetzner cloud server because they have only 15G in the smallest variant.

Thats very annoing but on the other hand I hesitate to run a full blown monitoring solution.

So today I realized that Uptime Kuma now has the ability to add a so called passive monitor where it does not actively ping a resource but receive a request.

That allows me to monitor the disk space with a sript that gets called by a systemd timer every 10 minutes.

Here’s the script I came up with:

 1#!/bin/bash
 2
 3BASE_URL="https://uptime.bouni.de/api/push/"
 4
 5disks=("/dev/sda1")
 6alerts=(85)
 7urls=("pCDwxPLOoI")
 8
 9check () {
10  DISK=$1
11  ALERT_LEVEL=$2
12  URL_HASH=$3
13
14  disk_usage=`/usr/bin/df -h $DISK | /usr/bin/tail -n +2 | /usr/bin/awk 'END {print $5}' | /usr/bin/tr -d "%"`
15  # Get disk space in GB
16  disk_space=`/usr/bin/df -h $DISK | /usr/bin/tail -n +2 | /usr/bin/awk 'END {print $2}'`
17  # get used disk space in GB
18  used_space=`/usr/bin/df -h $DISK | /usr/bin/tail -n +2 | /usr/bin/awk 'END {print $3}'`
19  # get free disk space in GB
20  free_space=`/usr/bin/df -h $DISK | /usr/bin/tail -n +2 | /usr/bin/awk 'END {print $4}'`
21  # get mount point
22  mount_point=`/usr/bin/df -h $DISK | /usr/bin/tail -n +2 | /usr/bin/awk 'END {print $6}'`
23
24  # Check if disk usage is higher than 85%
25  if [ $disk_usage -gt $ALERT_LEVEL ]; then
26    # Send push notification
27    /usr/bin/curl -k --get \
28      --data-urlencode "msg=Disk usage on ${mount_point} is high: ${disk_usage}% (${free_space}/${used_space}/${disk_space})" \
29      --data-urlencode "status=down" \
30      "${BASE_URL}${URL_HASH}"
31  else
32    /usr/bin/curl -k --get \
33      --data-urlencode "msg=Disk usage on ${mount_point} is OK: ${disk_usage}% (${free_space}/${used_space}/${disk_space})" \
34      --data-urlencode "status=up" \
35      "${BASE_URL}${URL_HASH}"
36  fi
37}
38
39for (( i=0; i<${#disks[@]}; i++ )); do
40    check ${disks[$i]} ${alerts[$i]} ${urls[$i]}
41done

At the top are three arrays in which I configure the disk device, the alert level and the hash from the Uptime Kuma push URL for each disk I want to be monitored.

The script then loop over all configured disks, gets the data for that disk, compares the free space to a threshold and sends the right request to my uptime instance. By setting the GET parameter status to either up or down I decide if everything is still fine or not. It even allows to have a custom message for the logs using the msg parameter.

The systemd service file looks like this:

1[Unit]
2Description=Sends disk space stats to Uptime Kuma
3
4[Service]
5Type=oneshot
6ExecStart=/opt/scripts/diskspace.sh

And the correspondig systemd timer file:

1[Unit]
2Description=Sends disk space stats to Uptime Kuma
3
4[Timer]
5OnCalendar=*:0/10
6
7[Install]
8WantedBy=timers.target

The result in Uptime Kuma looks like this: