Skip to content

Instantly share code, notes, and snippets.

@hjbotha
Last active November 8, 2021 13:37
Show Gist options
  • Save hjbotha/d45e319597b6683d2fb81de30def5db7 to your computer and use it in GitHub Desktop.
Save hjbotha/d45e319597b6683d2fb81de30def5db7 to your computer and use it in GitHub Desktop.
Submit Synology backup task results to Icinga
#! /bin/bash -e
# This script searches HyperBackup or ActiveBackup logs to determine
# the last time a specified backup task completed successfully
# That timestamp is then submitted to Icinga along with an OK
# if the task was completed within the last number of hours
# specified by the -w value, WARNING if between the values of
# -w and -c, and CRITICAL for values over that.
# If no value is given for -w it will be set to -c.
# For that submission to work, the following have to be true:
# - Icinga API enabled and accessible
# - Icinga API user specified with rights to submit that passive
# check result
# - The service name matches a service in Icinga
# - The host name matches the name of the host to which that
# service is assigned
# It uses curl to submit the result and does not require that NRPE
# be installed on the Synology NAS
# If the Service in Icinga has both active and passive checks enabled
# Icinga can alert the administrator if either
# - A Critical service check is received
# - No service check is received in more than check_interval
# This script can and should be used as a scheduled task on the Synology NAS
# This script assumes that ActiveBackup files are in /volume1/@ActiveBackup/
# Adjust as needed
function usage {
cat <<EOM
Usage: $(basename "$0") [OPTION]...
Spaces should be quoted or escaped
Options:
-s Service name Service as named in Icinga
Spaces will be replaced with %20
Other special characters may need
to be replaced manually
-t Task name Name of the backup task to check
the logs for
-a Application Backup application used
AB for ActiveBackup
HB for HyperBackup
-b Path ActiveBackup Path
Defaults to /volume1/@ActiveBackup
-n host Name of the host to which the
service is assigned in Icinga
-w value WARNING threshold in hours. If the
last successful backup occurred
more than this number of hours
in the past, a WARNING status
will be sent to Icinga
-c value CRITICAL threshold in hours. If the
last successful backup occurred
more than this number of hours
in the past, a CRITICAL status
will be sent to Icinga
Must be higher than Warning
threshold
-i url Icinga protocol, host and port
e.g. https://192.168.1.1:5665
Note: no trailing slash
-u username Icinga API User name
-p password Icinga API Password
-h Display help
EOM
exit 2
}
while getopts ":s:t:a:n:w:i:u:p:c:" optKey; do
case "$optKey" in
b)
ABPath=$OPTARG
;;
s)
ServiceName=$OPTARG
;;
t)
TaskName=$OPTARG
;;
a)
BackupType=$OPTARG
;;
n)
HostName=$OPTARG
;;
w)
WarningHours=$OPTARG
;;
c)
CriticalHours=$OPTARG
;;
i)
IcingaURL=$OPTARG
;;
u)
IcingaUser=$OPTARG
;;
p)
IcingaPass=$OPTARG
;;
h|*)
usage
;;
esac
done
[[ "$ServiceName" == "" ]] && echo Error: && echo -s is required && echo && usage
[[ "$TaskName" == "" ]] && echo Error: && echo -t is required && usage
[[ "$BackupType" != "AB" ]] && [[ "$BackupType" != "HB" ]] && echo Error: && echo Invalid backup type && echo && usage
[[ "$HostName" == "" ]] && echo Error: && echo -n is required && usage
[[ "$CriticalHours" == "" ]] && echo Error: && echo -c is required && echo && usage
[[ "$WarningHours" == "" ]] && WarningHours=$CriticalHours
[[ "$WarningHours" -gt "$CriticalHours" ]] && echo Error: && echo -w must be smaller than or equal to -c && usage
[[ "$IcingaURL" == "" ]] && echo Error: && echo -i is required && usage
[[ "$IcingaUser" == "" ]] && echo Error: && echo -u is required && usage
[[ "$IcingaPass" == "" ]] && echo Error: && echo -p is required && usage
[[ "$BackupType" == "AB" ]] && [[ "$ABPath" == "" ]] && ABPath='/volume1/@ActiveBackup'
function query_sqlite() {
i=1
while [ $i -le 12 ]; do
echo Querying sqlite. Attempt number: ${i}/12 | tee -a /tmp/check_backup.log
sqlite3 ${ABPath}/activity.db "select time_end from result_table where task_name = '$TaskName' and status = 2 order by time_end desc limit 1" 2>&1 > /tmp/check_backup_result | tee -a /tmp/check_backup.log
Exit_Code=$?
if [ $Exit_Code == 0 ]; then
echo Successfully queried database | tee -a /tmp/check_backup.log
LastSuccessUnixFmt=$(cat /tmp/check_backup_result)
LastSuccessDate=$(date --date @$LastSuccessUnixFmt)
elif [ $Exit_Code == 5 ]; then
echo Database is locked. | tee -a /tmp/check_backup.log
i=$(expr $i + 1)
sleep 5
continue
fi
break
done
if [[ $i -ge 6 ]] && [[ "$LastSuccessDate" == "" ]]; then
echo Could not get a last successful backup timestamp from the database. Will send CRITICAL status to Icinga
Output="Timeout querying ActiveBackup database"
fi
}
if [[ $CriticalHours < $WarningHours ]]; then
echo Critical threshold must be same or higher than Warning threshold
fi
echo > /tmp/check_backup.log
Now=$(date +%s)
WarningHoursUnixFmt=$(expr $WarningHours \* 60 \* 60)
CriticalHoursUnixFmt=$(expr $CriticalHours \* 60 \* 60)
WarningThreshold=$(expr $Now - $WarningHoursUnixFmt)
CriticalThreshold=$(expr $Now - $CriticalHoursUnixFmt)
ServiceName=$(echo $ServiceName | sed 's/ /%20/g')
case $BackupType in
HB) echo Backup type: HyperBackup | tee -a /tmp/check_backup.log
SearchString="Backup task finished successfully."
LastSuccessDate=$(grep "$TaskName" /var/log/synolog/synobackup.log | grep "$SearchString" | tail -1 | awk '{print $2 " " $3}')
LastSuccessUnixFmt=$(date --date="$LastSuccessDate" +"%s")
;;
AB) echo Backup type: ActiveBackup | tee -a /tmp/check_backup.log
query_sqlite
;;
esac
if [[ "$LastSuccessDate" != "" ]]; then
Output="Last backup: $LastSuccessDate"
if [[ $LastSuccessUnixFmt < $CriticalThreshold ]]; then
ExitStatus=2
elif [[ $LastSuccessUnixFmt < $WarningThreshold ]]; then
ExitStatus=1
else
ExitStatus=0
fi
else
echo Could not determine last successful backup date, will submit CRITICAL response to Icinga
Output="Last backup: Unknown"
ExitStatus=2
fi
echo Submitting check result to Icinga2 | tee -a /tmp/check_backup.log
echo '{ "exit_status": '$ExitStatus', "plugin_output": "'$Output'", "check_source": "'$CheckSource'" }' \ |
curl -k -u $IcingaUser:$IcingaPass -H 'Accept: application/json' -X POST "$IcingaURL/v1/actions/process-check-result?service=$HostName!$ServiceName" -d @- 2> /tmp/check_backup_curl.log > /tmp/check_backup_response.log
if [[ "$?" == 0 ]]; then
echo Successfully submitted check result | tee -a /tmp/check_backup.log
echo Response from Icinga: | tee -a /tmp/check_backup.log
cat /tmp/check_backup_response.log | tee -a /tmp/check_backup.log
echo
exit 0
else
echo Failed to submit check result. Log follows.
cat /tmp/check_backup.log
echo Icinga response, if any, below:
cat /tmp/check_backup_response.log
exit 1
fi
echo
@nestyxx
Copy link

nestyxx commented Nov 8, 2021

Hello.
After several hours of research, I came across your script which looks a lot like what I'm trying to produce as a notification about backing up the various NAS under management.
Is it easy to adapt this script to simply send an email notification if a backup (Hyper Backup or Active Backup) has not been performed for x days?
Thanks in advance for the feedback.
Alexandre

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment