System Alert
Server monitoring in Bash and systemd. Alerts land in Telegram, Discord or a webhook.
Free and MIT licensed, currently in alpha. No resident agent, no daemon and no SaaS account. One deploy command copies it to your server.
# set SSH_HOST_1, SSH_USER and REMOTE_DIR in .env
cp .env.example .env
./deploy.shQuiet by default, tunable when you care
CPU, RAM, disk, I/O wait and network alerts fire only after a breach lasts five minutes, so a short spike stays quiet. Each one sends a recovery message when it clears.
- CPU threshold
- 80%
- user plus system
- RAM threshold
- 85%
- percent used
- Disk threshold
- 85%
- checked per mount
- Sustained before alerting
- 5 min
- set by RESOURCE_SUSTAIN_MINUTES
Source: default values in .env.server.example. Every value is a plain variable you can change.
What you get
Resources
CPU, RAM, every mounted disk, I/O wait (needs
iostat) and network throughput on the default interface. tmpfs, udev and loop devices are skipped.Services
Watches the units in
SERVICES_TO_MONITOR, or every enabled service minus a skip list. Down alerts are batched and include the recent journal lines.SSH brute force and logins
Counts failed sshd attempts over five minutes and alerts at 10 or more, listing the top 5 source IPs. A PAM hook alerts the moment someone logs in.
Log growth
Flags files over 500 MB, or a directory over 2 GB, under
LOG_DIRS(default/var/log), so a runaway log does not fill the disk unnoticed.Telegram, Discord or a webhook
One notifier script per channel. Telegram sends info and recovery messages silently, so only real problems make your phone buzz.
One command deploy
deploy.shcopies the scripts and a generated config over SSH, installs missingcurl,bcandsysstat, and sets up a systemd timer or cron.
Read the alert before you read the logs
Every alert names the host, the current value and the threshold. Service alerts add the latest journal lines, and brute force alerts list the source IPs.
Each alert is sent once per breach and tracked in state files, so a problem that lasts an hour does not send sixty messages.
The example on the right uses made-up values.
🔴 *CPU Usage Alert*
🖥 `my-server`
CPU usage is critically high.
📊 Current: `92%` / Threshold: `80%`
📈 Load average: `1.2 1.0 0.9`
⏱ Sustained: `5 min`
🕐 `2026-01-01 12:00:00 UTC`Deploying to a server
- Point it at your host. Copy
.env.exampleto.envand setSSH_HOST_1,SSH_USERandREMOTE_DIR. The default remote directory is/etc/server-monitor. - Preset your alerts, optionally. Copy
.env.server.exampleto.env.serverto set thresholds and channels ahead of time. - Deploy. Run
./deploy.sh. It asks which monitors and channels to enable, then installs a systemd timer that runs every 60 seconds. Pass--cronif you prefer cron. - Check it on the server. Run
run-monitors.sh --listto see the monitors, orrun-monitors.sh --forceto run them now.
Good to know
- It is in alpha, so expect rough edges and changes. Debian and Ubuntu are the tested targets, because the deploy script installs missing tools with
apt-get. - The monitors need systemd and
journalctl. The deploy needs SSH, rsync and sudo on the target. - The service runs as root, hardened with
NoNewPrivileges,ProtectSystem=strict,ProtectHomeandPrivateTmp. It can write only to/etc/server-monitor/state.
Questions
What is System Alert?
Does it install an agent?
Will a short CPU spike wake me up?
Is it free?
Which alert channels are supported?
Deploy it to one test server
Issues and stars on GitHub help other people find it.