Server status monitor bash script
When managing multiple servers, keeping track of their availability is crucial. Building on an example from “Cybersecurity Ops with bash” by Paul Troncone, I’ve developed a bash script that provides a simple yet effective way to monitor server status across multiple hosts. Let’s break down how this script works and why it can be a valuable tool for system administrators.
#!/usr/bin/env bash
# For a given list of servers, this script will check the status of the server and notify the user if the server is down.
#
# Usage: ./server_status.sh [-i <interval>] < server_list.txt
declare -i INTERVAL=30 # Default interval is 30 seconds
if [ ! -f /var/log/server_status.log ]; then
# Check if user has permission to write to /var/log
if [ ! -w /var/log ]; then
echo "Cannot write to /var/log/server_status.log; hint: use sudo when running this script for the first time" 1>&2
exit 1
fi
touch /var/log/server_status.log
chown "$USER" /var/log/server_status.log
chmod 644 /var/log/server_status.log
fi
while getopts ":i:" opt; do
case ${opt} in
i)
INTERVAL=$OPTARG
;;
\?)
echo "Invalid option: $OPTARG" 1>&2
;;
:)
echo "Invalid option: $OPTARG requires an argument" 1>&2
;;
esac
shift $((OPTIND - 1))
done
while true; do
clear
echo 'Server Status Monitor'
echo 'Status: Scanning ...'
echo '---------------------------------'
while read -r server_hostname; do
server_hostname=$(echo $server_hostname | tr -d '\r')
if [[ $server_hostname == http* ]]; then
curl -s -o /dev/null -w "%{http_code}" "$server_hostname" | grep -E '(000|404)' &>/dev/null
if [ $? -eq 0 ]; then
tput setaf 1
echo "Server: $server_hostname is down - $(date)" | tee -a /var/log/server_status.log
tput setaf 7
fi
continue
fi
ping -c 1 "$server_hostname" | grep -E '(Destination Host Unreachable|100% packet loss)' &>/dev/null
if [ $? -eq 0 ]; then
tput setaf 1
echo "Server: $server_hostname is down - $(date)" | tee -a /var/log/server_status.log
tput setaf 7
fi
done <"${1:-/dev/stdin}"
echo ""
echo "Press [CTRL+C] to stop..."
declare -i i
for ((i = $INTERVAL; i > 0; i--)); do
tput cup 1 0
echo "Status: Next scan in $i seconds "
sleep 1
done
done
Script Overview
The script allows you to monitor the status of a list of servers, whether they’re URLs or hostnames, and provides real-time notifications when a server goes down. Here’s how it functions:
./server_status.sh [-i <interval>] < server_list.txt
Key Features
- Flexible Input: The script can read server names from a file or standard input.
- Configurable Scan Interval: You can specify a custom scan interval (default is 30 seconds).
- Logging: Automatically logs server down events to
/var/log/server_status.log
. - Support for Both Hostnames and URLs: Can ping traditional servers or check HTTP status codes for web servers.
Implementation
Logging Setup
The script first checks if it can create and write to the log file at /var/log/server_status.log
. If the directory isn’t writable, it provides a helpful hint to use sudo
when running the script for the first time. This ensures proper permissions are set for logging.
Server Status Checking
The script supports two types of server checks:
# For traditional servers (hostnames)
ping -c 1 "$server_hostname" | grep -E '(Destination Host Unreachable|100% packet loss)' &>/dev/null
# For web servers (URLs)
curl -s -o /dev/null -w "%{http_code}" "$server_hostname" | grep -E '(000|404)' &>/dev/null
This dual approach allows monitoring of both network-level connectivity for traditional servers and HTTP availability for web services.
User Experience
The script provides a clean, interactive terminal interface:
- Colorized output (red for down servers)
- Countdown timer to next scan
- Option to stop monitoring with
CTRL+C
Usage Example
Create a server_list.txt
with your servers:
example.com
https://mywebsite.com
192.168.1.100
Then run the script:
./server_status.sh -i 60 < server_list.txt # Scan every 60 seconds
Considerations and Warnings
As with any system monitoring script, be cautious:
- Ensure you have permission to monitor the servers
- Be mindful of network load, especially with frequent scans
- The script is best used in controlled, internal network environments
- Unless the hostname starts with
http
, the script assumes it’s a traditional server and usesping
for monitoring; therefore, it may not work for all types of servers if they don’t respond to ICMP requests (I had to add a custom rule to an AWS security group to allow ICMP traffic for this script to work for my EC2 instances)
Conclusion
This bash script offers a lightweight, flexible solution for monitoring server availability. It demonstrates the power of bash scripting in system administration tasks, providing a simple yet effective tool for keeping an eye on your infrastructure.
Remember to always test scripts in a staging environment before deploying to production, and customize the script to fit your specific monitoring needs.
Happy scripting!