Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Monitoring script

Featured Replies

Just wanted to share the following script I use to monitor availability of some of my systems and services.

 

The script runs in CRON at a five minute interval, runs a set of checks and then creates a HTML file that is shown by a webserver process running on the same system.

 

The script sends notifications to PUSHOVER so you get notified of important issues.

 

The script stores the latest test results to make sure a notification only gets sent the moment a service becomes unavailable and not every 5 minutes. 

monitor.thumb.png.149b0104d49aa0b47fd8ba8181ca0bd5.png

 

 

#!/bin/bash

# Define output file
OUTPUT_FILE="/var/www/html/monitor.html"

# Start of the HTML file - styling
cat <<EOF >$OUTPUT_FILE
<html>
<head>
<title>Server Status</title>
<style>
  body { font-family: 'Courier New', monospace; background-color: #f4f4f8; color: #333; }
  h1 { color: #0056b3; }
  table { width: 100%; border-collapse: collapse; }
  th, td { border: 1px solid #dddddd; padding: 8px; text-align: left; }
  th { background-color: #0056b3; color: #ffffff; }
  tr:nth-child(even) { background-color: #f2f2f2; }
  .check-name { width: 20%; }
  .ip-address { width: 20%; }
  .result { width: 20%; }
  .details { width: 30%; }
  .status-icon { width: 10%; }
  .green { width: 20px; height: 20px; background-color: green; border-radius: 50%; display: inline-block; }
  .red { width: 20px; height: 20px; background-color: red; border-radius: 50%; display: inline-block; }
  .orange { width: 20px; height: 20px; background-color: orange; border-radius: 50%; display: inline-block; }

</style>
</head>
<body>
<h1>Server Status Report</h1>
<p>Last updated: $(TZ='Europe/Amsterdam' date '+%Y-%m-%d %H:%M:%S')</p>
<table>
<tr>
  <th>Status</th>
  <th>Check Name</th>
  <th>IP Address</th>
  <th>Result</th>
  <th>Details</th>
</tr>
EOF

log_status_change() {
    local message=$1
    local log_file="/home/marc/monitor/status_changes.log"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> $log_file

    # Limit shown log to 25 lines
    tail -n 25 $log_file > $log_file.tmp
    mv $log_file.tmp $log_file
}



get_hostname() {
    local ip=$1
    local hostname=$(dig +short -x $ip @<YOUR DNS SERVER>)
    hostname=${hostname%%.*}  
    echo "${hostname:-Unknown}"
}


send_pushover() {
    curl -s \
      --form-string "token=pushover app token" \
      --form-string "user=pushover user token" \
      --form-string "message=$1" \
      --form-string "title=Monitoring Alert !" \
      https://api.pushover.net/1/messages.json
}


# Store current state of service
save_status() {
    local service=$1
    local status=$2
    local status_file="/home/marc/monitor/${service}.status"
    echo "$status" > "$status_file"
}

# Retrieve latest status of service
get_status() {
    local service=$1
    local status_file="/home/marc/monitor/${service}.status"
    if [[ -f "$status_file" ]]; then
        cat "$status_file"
    else
        echo "unknown"  # Standard value
    fi
}



# Functions for checking several things

check_server() {
    local ip=$1
    local response=$(curl -s -o /dev/null -w "%{http_code}" http://$ip:80)
    local current_status=""
    local hostname=$(get_hostname $ip)
    if [[ "$response" =~ ^2 || "$response" =~ ^3 ]]; then
        current_status="online"
    else
        current_status="offline"
    fi

    local old_status=$(get_status "HTTP_Server_$ip")
    old_status=${old_status:-online}  # If no old status assume 'online'

    if [ "$old_status" == "online" ] && [ "$current_status" == "offline" ]; then
        echo "<tr><td><span class='red'></span></td><td>HTTP Server Check</td><td>$ip ($hostname)</td><td>Offline</td><td>Status changed from online</td></tr>" >> $OUTPUT_FILE
        send_pushover "Monitoring: HTTP server at $ip has become offline."
        log_status_change "Server at $ip changed from Online to Offline."
    elif [ "$old_status" == "offline" ] && [ "$current_status" == "offline" ]; then
        echo "<tr><td><span class='orange'></span></td><td>HTTP Server Check</td><td>$ip ($hostname)</td><td>Offline</td><td>Continues to be offline</td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "offline" ] && [ "$current_status" == "online" ]; then
        echo "<tr><td><span class='green'></span></td><td>HTTP Server Check</td><td>$ip ($hostname)</td><td>Online</td><td>Server became online again</td></tr>" >> $OUTPUT_FILE
        log_status_change "Server at $ip changed from Offline to Online."
    elif [ "$old_status" == "online" ] && [ "$current_status" == "online" ]; then
        echo "<tr><td><span class='green'></span></td><td>HTTP Server Check</td><td>$ip ($hostname)</td><td>Online</td><td>Status code: $response</td></tr>" >> $OUTPUT_FILE
    fi

    save_status "HTTP_Server_$ip" "$current_status"
}

check_dhcp() {
    local ip=$1
    local dhcp_check=$(sudo nmap -sU -p 67 --script dhcp-discover $ip 2>&1)
    local current_status=""
    local hostname=$(get_hostname $ip)

    if echo "$dhcp_check" | grep -q "67/udp open\|67/udp open|filtered"; then
        current_status="active"
    else
        current_status="inactive"
    fi

    local old_status=$(get_status "DHCP_Server_$ip")
    old_status=${old_status:-active}  # If no old status assume 'active'


    if [ "$old_status" == "active" ] && [ "$current_status" == "inactive" ]; then
        echo "<tr><td><span class='red'></span></td><td>DHCP Server Check</td><td>$ip ($hostname)</td><td>Inactive</td><td>DHCP Became unactive</td></tr>" >> $OUTPUT_FILE
        send_pushover "Monitoring: DHCP server at $ip has become inactive."
        log_status_change "DHCP Server at $ip changed from Online to Offline."
   elif [ "$old_status" == "inactive" ] && [ "$current_status" == "inactive" ]; then
        echo "<tr><td><span class='orange'></span></td><td>DHCP Server Check</td><td>$ip ($hostname)</td><td>Inactive</td><td>Continues to be inactive</td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "active" ] && [ "$current_status" == "active" ]; then
        echo "<tr><td><span class='green'></span></td><td>DHCP Server Check</td><td>$ip ($hostname)</td><td>Active</td><td></td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "inactive" ] && [ "$current_status" == "active" ] ; then
        echo "<tr><td><span class='green'></span></td><td>DHCP Server Check</td><td>$ip ($hostname)</td><td>Active</td><td>Server became active again</td></tr>" >> $OUTPUT_FILE
        log_status_change "DHCP Server at $ip changed from Offline to Online."
    fi

    save_status "DHCP_Server_$ip" "$current_status"

}


check_ip() {
    local ip=$1
    local current_status=""
    local hostname=$(get_hostname $ip)

    if ping -c 1 -W 1 $ip > /dev/null 2>&1; then
        current_status="reachable"
    else
        current_status="not reachable"
    fi

    local old_status=$(get_status "ICMP_Ping_$ip")
    old_status=${old_status:-reachable}  # If no old status assume 'reachable'

    if [ "$old_status" == "reachable" ] && [ "$current_status" == "not reachable" ]; then
        echo "<tr><td><span class='red'></span></td><td>ICMP Ping Check</td><td>$ip ($hostname)</td><td>Not Reachable</td><td>ICMP ping became unresponsive</td></tr>" >> $OUTPUT_FILE
        send_pushover "Monitoring: ICMP Ping failed for $ip"
        log_status_change "$ip become unreachable."
    elif [ "$old_status" == "not reachable" ] && [ "$current_status" == "not reachable" ]; then
        echo "<tr><td><span class='orange'></span></td><td>ICMP Ping Check</td><td>$ip ($hostname)</td><td>Not Reachable</td><td>Continues to be unresponsive</td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "reachable" ] && [ "$current_status" == "reachable" ]; then
        echo "<tr><td><span class='green'></span></td><td>ICMP Ping Check</td><td>$ip ($hostname)</td><td>Reachable</td><td></td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "not reachable" ] && [ "$current_status" == "reachable" ]; then
        echo "<tr><td><span class='green'></span></td><td>ICMP Ping Check</td><td>$ip ($hostname)</td><td>Reachable</td><td>Ping response restored</td></tr>" >> $OUTPUT_FILE
        log_status_change "$ip became reachable."
    fi

    save_status "ICMP_Ping_$ip" "$current_status"
}


check_dns() {
    local ip=$1
    local dns_check=$(dig @$ip +nocmd +noall +answer +time=1 +tries=1 SOA google.com)
    local current_status=""
    local hostname=$(get_hostname $ip)

    # Check for 'google.com' in the answer
    if echo "$dns_check" | grep -q "google.com"; then
        current_status="active"
    else
        current_status="inactive"
    fi

    local old_status=$(get_status "DNS_Server_$ip")
    old_status=${old_status:-active}  # If no old status assume 'active'

    if [ "$old_status" == "active" ] && [ "$current_status" == "inactive" ]; then
        echo "<tr><td><span class='red'></span></td><td>DNS Server Check</td><td>$ip ($hostname)</td><td>Inactive</td><td>DNS became inactive</td></tr>" >> $OUTPUT_FILE
        send_pushover "Monitoring: DNS server at $ip has become inactive."
        log_status_change "DNS Server at $ip changed from Online to Offline."
    elif [ "$old_status" == "inactive" ] && [ "$current_status" == "inactive" ]; then
        echo "<tr><td><span class='orange'></span></td><td>DNS Server Check</td><td>$ip ($hostname)</td><td>Inactive</td><td>Continues to be inactive</td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "active" ] && [ "$current_status" == "active" ]; then
        echo "<tr><td><span class='green'></span></td><td>DNS Server Check</td><td>$ip ($hostname)</td><td>Active</td><td></td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "inactive" ] && [ "$current_status" == "active" ] ; then
        echo "<tr><td><span class='green'></span></td><td>DNS Server Check</td><td>$ip ($hostname)</td><td>Active</td><td>DNS became active again</td></tr>" >> $OUTPUT_FILE
        log_status_change "DNS Server at $ip changed from Offline to Online."
    fi
    save_status "DNS_Server_$ip" "$current_status"

}


check_external_ip() {
    # Get external address
    local external_ip=$(curl -s ifconfig.me)
    local current_status=""
    local hostname=$(get_hostname $ip)

    # Check if IP was received
    if [[ -n "$external_ip" ]]; then
        current_status="success"
    else
        current_status="failed"
    fi
    local old_status=$(get_status "External_IP_Check")
    old_status=${old_status:-success}  # If no old status assume 'success'

    if [ "$old_status" == "success" ] && [ "$current_status" == "failed" ]; then
        echo "<tr><td><span class='red'></span></td><td>External IP Check</td><td>N/A</td><td>Failed</td><td>Could not retrieve external IP</td></tr>" >> $OUTPUT_FILE
        send_pushover "Monitoring: Get external IP failed"
        log_status_change "Internet became unavailable."
    elif [ "$old_status" == "failed" ] && [ "$current_status" == "failed" ]; then
        echo "<tr><td><span class='orange'></span></td><td>External IP Check</td><td>N/A</td><td>Failed</td><td>Continues to fail retrieving external IP</td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "success" ] && [ "$current_status" == "success" ]; then
        echo "<tr><td><span class='green'></span></td><td>External IP Check</td><td>$external_ip</td><td>Active</td><td>Internet up</td></tr>" >> $OUTPUT_FILE
    elif [ "$old_status" == "failed" ] && [ "$current_status" == "success" ] ; then
        echo "<tr><td><span class='green'></span></td><td>External IP Check</td><td>$external_ip</td><td>Active</td><td>Internet back up</td></tr>" >> $OUTPUT_FILE
        log_status_change "Internet became available."
    fi
    save_status "External_IP_Check" "$current_status"
}



# Main process, do the checks
check_external_ip
check_server 192.168.2.5
check_server 192.168.2.78
check_dhcp 192.168.2.206
check_dhcp 192.168.2.220
check_dns 192.168.2.206
check_dns 192.168.2.220

# Add recent status changes to page
echo "<table><tr><th>Time</th><th>Change</th></tr>" >> $OUTPUT_FILE
echo " " >> $OUTPUT_FILE
echo "<h2>Recent Status Changes</h2>" >> $OUTPUT_FILE

# Read log and add lines to page
if [[ -f "/home/marc/monitor/status_changes.log" ]]; then
    tac /home/marc/monitor/status_changes.log | while read line
    do
        echo "<tr><td>${line%% - *}</td><td>${line##* - }</td></tr>" >> $OUTPUT_FILE
    done
fi
echo "</table>" >> $OUTPUT_FILE

# Close HTML page
echo "</body></html>" >> $OUTPUT_FILE

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.