A bash script that monitors server health and sends Telegram alerts when:
- CPU load average exceeds the number of cores
- RAM usage exceeds a configured threshold
- A systemd service has failed
- Disk usage exceeds a configured threshold
bash,curl,systemd- A Telegram bot token and chat ID (how to create a bot)
sudo git clone https://github.com/alfiosalanitri/server-guardian /opt/server-guardian
cd /opt/server-guardianThe repository must stay at this path after installation — the systemd units are symlinked directly from it.
sudo cp .config.demo .config
sudo nano .configFill in telegram_bot_token and telegram_user_chat_id. Adjust the monitoring thresholds as needed (see Configuration below).
sudo make installThis will:
- Set ownership (
root:root) and file permissions - Generate
systemd/guardian.servicewith the correct install path - Symlink both units into
/etc/systemd/system/ - Enable and start the
guardian.timer(runs every minute)
# Check the timer is active
systemctl status guardian.timer
# Send a test message to your Telegram chat
sudo /opt/server-guardian/guardian.sh --testsudo make uninstallStops and disables the timer, removes the symlinks from /etc/systemd/system/, and reloads systemd. The repository directory is left untouched.
Options can be set in .config or overridden at runtime via CLI flags. CLI flags always take precedence.
| Variable | Description | Default |
|---|---|---|
telegram_bot_token |
Telegram bot token | (required) |
telegram_user_chat_id |
Telegram chat ID | (required) |
send_alert_every_minutes |
Minimum minutes between repeated alerts | 60 |
watch_cpu |
1 to monitor CPU, 0 to skip |
— |
cpu_warning_level |
high (1 min avg), medium (5 min avg), low (15 min avg) |
medium |
watch_ram |
1 to monitor RAM, 0 to skip |
— |
memory_perc_limit |
RAM usage percentage threshold | — |
watch_services |
1 to monitor failed systemd services, 0 to skip |
— |
watch_hard_disk |
1 to monitor disk space, 0 to skip |
— |
disk_space_perc_limit |
Disk usage percentage threshold | — |
| Flag | Description |
|---|---|
--warn-every N |
Minutes between repeated alerts |
--watch-cpu 0|1 |
Enable/disable CPU monitoring |
--watch-ram 0|1 |
Enable/disable RAM monitoring |
--watch-services 0|1 |
Enable/disable failed service monitoring |
--watch-hard-disk 0|1 |
Enable/disable disk monitoring |
--cpu-warning-level high|medium|low |
CPU alert sensitivity |
--memory-limit N |
RAM percentage threshold |
--disk-space-limit N |
Disk percentage threshold |
--config /path |
Path to a custom config file |
--config-telegram-variable-token NAME |
Variable name for the bot token in a custom config |
--config-telegram-variable-chatid NAME |
Variable name for the chat ID in a custom config |
--test |
Send a test message to verify the bot is working |
-h, --help |
Show help |
sudo /opt/server-guardian/guardian.sh \
--warn-every 30 \
--watch-cpu 1 --cpu-warning-level high \
--watch-ram 1 --memory-limit 60 \
--watch-services 0 \
--watch-hard-disk 0 \
--config /home/myuser/.guardian.conf \
--config-telegram-variable-token MY_TELEGRAM_TOKEN \
--config-telegram-variable-chatid MY_CHAT_IDThe timer fires every minute (OnCalendar=minutely), matching the original crontab schedule.
systemd/guardian.timer — committed to the repository:
[Unit]
Description=Run server-guardian every minute
[Timer]
OnBootSec=1min
OnCalendar=minutely
AccuracySec=1s
[Install]
WantedBy=timers.targetsystemd/guardian.service — generated by install.sh (not committed, contains the absolute install path):
[Unit]
Description=Server Guardian - monitor CPU, RAM, services and disk
After=network.target
[Service]
Type=oneshot
User=root
WorkingDirectory=/opt/server-guardian
ExecStart=/opt/server-guardian/guardian.sh
StandardOutput=null
StandardError=nullBoth files are symlinked into /etc/systemd/system/ by the installer so updates to the repository are picked up automatically without re-running install.sh.
sudo /opt/server-guardian/guardian.sh --testSends a test message and exits 0 on success, exits 1 with a diagnostic if the Telegram API returns an error.
make test16 tests covering all monitoring paths and edge cases. Each test runs in an isolated temporary directory using stubbed system commands (curl, lscpu, uptime, free, df, systemctl) — no real Telegram credentials or server resources required.