Making rsync backups measurable and monitored: writing informative logs, mapping exit codes, email notifications on failure, Zabbix/ Prometheus alerting integration via a cron wrapper, rsyslog for daemon mode, and the habit of periodic backup log reviews.

A backup running without monitoring is an illusion of security. You only find out a backup is broken when you need to restore — and by then it's too late. Episode 20 closes that gap: how to make rsync backups measurable, logged, and alerted so failures are detected in minutes, not months. We cover five layers: logs, exit codes, notifications, alerting integration, and periodic audits — all buildable with tools already on your server.
A good log has three properties: timestamped, with context, and with a summary. The script in episode 10 already wrote timestamps; improve it with a statistics summary:
#!/bin/bash
LOG=/var/log/rsync.log
{
echo "=== $(date '+%F %T') rsync started ==="
rsync -avh --stats --delete /home/data/ /backup/daily/
echo "=== exit=$? finished $(date '+%F %T') ==="
} >> "$LOG" 2>&1A one-block-per-run format (=== started === … === finished ===) is easy to parse. For logs that are easy to analyze, consider a one-line-per-run format — ideal for querying and charting, and we'll use it in the Prometheus section below:
echo "$(date '+%F %T') rc=$RC sent=$SENT recv=$RECV speedup=$SPEEDUP" >> "$LOG"Already mapped in episode 10: 0 success, 23 partial transfer, 24 files vanished, 255 connection error. The key to using them in scripts:
RC=$?
if [ $RC -eq 0 ]; then
STATUS="OK"
elif [ $RC -eq 23 ] || [ $RC -eq 24 ]; then
STATUS="PARTIAL" # some files failed/vanished — must be checked
else
STATUS="FAILED"
fiTreat 23/24 as a warning that must be looked at, not success: some data may not be synced. This STATUS is what you'll send to notifications and alerting.
The simplest notification — email when it's not 0 (the episode 10 pattern):
if [ "$STATUS" != "OK" ]; then
tail -30 "$LOG" | mail -s "Rsync $STATUS (rc=$RC) - $(hostname)" admin@example.com
fiFor modern teams, replace mail with a webhook — Slack/Telegram/Mattermost only need curl:
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
-d chat_id="$CHAT_ID" -d text="Rsync $STATUS rc=$RC di $(hostname)"Note
Too many notifications = numb notifications. Alert only for non-OK — pick a channel you'll actually see, because an email that's never read is as bad as no notification at all. Successful runs just get logged.
The most flexible form: a cron wrapper that runs the backup, writes a status, and exposes it to your monitoring system. The Prometheus textfile collector pattern (via node_exporter):
#!/bin/bash
LOG=/var/log/rsync.log
rsync -avh --delete /home/data/ /backup/daily/ >> "$LOG" 2>&1
RC=$?
printf 'rsync_backup_last_status %s\n' "$RC" > /var/lib/node_exporter/rsync.prom
printf 'rsync_backup_last_run %s\n' "$(date +%s)" >> /var/lib/node_exporter/rsync.promnode_exporter publishes the .prom file as metrics; Prometheus scrapes it on every interval; Alertmanager sends an alert when rsync_backup_last_status ≠ 0 for more than N minutes. The flow diagram:
cron → rsync script → exit code → textfile .prom → node_exporter
→ Prometheus (rule) → Alertmanager → email/Slack/PagerDutyFor Zabbix, the pattern is the same with different tooling: zabbix_sender sends the status straight to the server, or an external item reads the log. What matters is the principle, not the tool: a backup's exit code must become a metric that gets scraped.
When using rsyncd (daemon mode), it can write logs to syslog — managed by rsyslog — instead of only its own file. Configuration in /etc/rsyncd.conf:
use syslog = yes
log format = %h %o %f %bEvery daemon connection now goes to syslog with a host, operation, file, and byte format. On the rsyslog side, direct a specific facility to a file or forward it to a central log server:
daemon.* /var/log/rsyncd.logSending to a central log server (e.g. @logserver:514) centralizes daemon auditing — useful for monitoring who pulls from a module, and for investigating suspicious access.
Even the best tooling means nothing without a human reviewing it. Build an audit habit:
grep 'rc=' /var/log/rsync.log | awk '{print $1, $2, $5}'Periodic reviews (weekly/monthly) with these questions:
0 runs that slipped past the alert?PARTIAL pattern (files that always fail — a sign of a permanent problem)?Tip
Make backup review a recurring agenda item (weekly) and include periodic "restore drills": try restoring one random file from a week-old snapshot. A backup is only proven to work when its restore is proven to work.
In this episode you've made rsync backups measurable and monitored.
Key takeaways:
0 OK, 23/24 partial (beware), anything else failed.rsyncd can log to rsyslog; periodic audit reviews and restore drills are mandatory.In episode 21 we look ahead: roadmap & community — ongoing security focus, 3.4.x maintenance releases, no major features planned, management via lists.samba.org, the GitHub repo, and the rsync mailing list. See you in episode 21!