Last active
November 8, 2021 13:37
-
-
Save hjbotha/d45e319597b6683d2fb81de30def5db7 to your computer and use it in GitHub Desktop.
Submit Synology backup task results to Icinga
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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