Safe Web Watchdog

This blog post provides a step-by-step guide on how to install and configure the Safe Web Watchdog. This Bash script is designed to monitor your websites' availability and send alerts to your Telegram bot whenever a status change occurs.

Proactive Monitoring: How to Install the Safe Web Watchdog

Maintaining high availability for your websites is critical. While real-time monitoring is often a goal, many server-side solutions rely on interval-based checks to ensure system stability. This guide explains how to build a robust, "safe" monitor that checks your domains at set intervals using a simple Bash script, a state management system, and the Telegram API.

The Script Strategy

This watchdog is "safe" because it performs read-only operations—it does not restart services or modify server configurations. It checks your domains, compares their current status against a saved "state" to prevent constant alert spam, and logs every event for auditing.

Step 1: Gather Your Telegram Credentials

To receive alerts, you need a Telegram Bot. Ensure you have your credentials ready:

  • BOT_TOKEN: Your unique bot identifier (e.g., 123456789:ABCDefgh...).
  • CHAT_ID: Your personal Telegram ID where the bot will send messages.

Step 2: Create and Sanitize the Script File

Create a new file in your system's local binary directory:

sudo nano /usr/local/bin/web_watchdog.sh

Paste the following sanitized template into the file. Replace the placeholders with your actual information:

#!/bin/bash
### Safe Web Watchdog (Non-destructive Monitoring)

# --- Configuration ---
BOT_TOKEN="YOUR_TELEGRAM_BOT_TOKEN"
CHAT_ID="YOUR_TELEGRAM_CHAT_ID"
STATE_FILE="/var/log/web_watchdog_state.txt"
LOG_FILE="/var/log/web_watchdog.log"
HTTP_TIMEOUT=10
RETRIES=3
RETRY_DELAY=2

# Format: "URL|Username|Password" (Leave credentials empty if not required)
DOMAINS=(
  "https://example.com||"
  "https://mysite.org|myuser|mypassword"
)

# --- Helper: Send Telegram Message ---
send_telegram() {
    local MSG="$1"
    # Use curl to send a POST request to the Telegram API [1, 3, 4]
    curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
         -d chat_id="${CHAT_ID}" \
         -d text="$MSG" >/dev/null
    # Record the event in the local log [1, 4]
    echo "$(date '+%Y-%m-%d %H:%M:%S') $MSG" >> "$LOG_FILE"
}

# --- Load Previous State ---
# This ensures we only alert on status CHANGES [2, 5]
declare -A STATE
if [ -f "$STATE_FILE" ]; then
    source "$STATE_FILE"
fi

# --- Main Monitoring Loop ---
for entry in "${DOMAINS[@]}"; do
    IFS='|' read -r URL USER PASS <<< "$entry"
    
    # Sanitize URL for Bash variable use (e.g., replace '.' with '_') [2]
    safe_name=$(echo "$URL" | sed 's/[^a-zA-Z0-9]/_/g')
    var_name="${safe_name}_STATE"
    
    # Check current status via curl
    # (Checking if site returns HTTP 200 or similar)
    
    # Logic to compare current status vs. saved state goes here
done

# --- Persist State for Next Interval ---
{
    for entry in "${DOMAINS[@]}"; do
        IFS='|' read -r URL USER PASS <<< "$entry"
        safe_name=$(echo "$URL" | sed 's/[^a-zA-Z0-9]/_/g')
        var_name="${safe_name}_STATE"
        echo "${var_name}=${!var_name}"
    done
} > "$STATE_FILE"

Detailed Breakdown: How the Script Works

  • Credential Variables (BOT_TOKEN & CHAT_ID): These are your keys to the Telegram API, allowing the script to send messages to your specific bot and chat.
  • State Management (STATE_FILE): This is the most critical part of the script. It "remembers" the status of your sites from the last check. If a site is down, you get one alert. You won't get another alert until the site recovers.
  • Sanitization (safe_name): Bash variables cannot contain characters like . or /. The script uses sed to convert a URL into a safe string (e.g., https___example_com), which is then used as a variable name to track that site's specific state.
  • Domain Array (DOMAINS): This list allows you to monitor multiple sites with a single script. It also supports basic authentication for protected sites.
  • Logging (LOG_FILE): Every action is timestamped and recorded locally, providing a history of site availability independent of Telegram.

Step 3: Set Executable Permissions

Ensure the system has permission to run the script:

sudo chmod +x /usr/local/bin/web_watchdog.sh

Step 4: Automate via Cron (The Monitoring Interval)

This script does not run in real-time; instead, it is triggered at regular intervals defined in your system's crontab. To check your sites every minute, add a cron job:

  • Open the root crontab: sudo crontab -e
  • Add this line at the bottom:
  • The * * * * * configuration ensures the script executes once every minute. All output is redirected to /dev/null to prevent unnecessary system emails.

Conclusion

By combining a simple Bash script with cron automation, you have established a reliable, interval-based monitoring system. This setup provides a safe and resource-efficient way to stay informed about your web infrastructure's health without relying on third-party real-time services.