added ninjareport
[matthijs/upstream/backupninja.git] / src / ninjareport.in
diff --git a/src/ninjareport.in b/src/ninjareport.in
new file mode 100755 (executable)
index 0000000..b68efb8
--- /dev/null
@@ -0,0 +1,205 @@
+#!@BASH@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
+#
+#
+# Ninjareport - generate a single simple report for a lot of hosts
+#
+# requires logtail
+#
+# Copyright (C) 2007 - riseup.net -- property is theft.
+
+# TODO:
+#
+#  . check for logs that are never updating and warn
+#  . change constantly updating logs (maildir) to be more friendly
+#  . documentation
+#  . maybe make config option that lists all hosts that should report-in, and if 
+#    one doesn't then warn
+#  . restrict rsync somehow?
+#  . abstract path for logtail
+#  . on the report master, the reportdirectory should be set where the reports will be going, note this
+
+mail=1
+display=0
+
+process() {
+
+# look in the logfile for any lines like the following:
+# Jan 20 01:02:46 Info: FINISHED: 2 actions run. 0 fatal. 0 error. 0 warning.
+#
+# note: some backups never finish, such as the maildir one, need to handle these
+# perhaps by looking for FAILED messages?
+# note2: what about logs that aren't being updated? this is a failure case and 
+# should be looked for
+# note3: there are also these entries:
+# Jan 20 14:00:01 Fatal: No backup actions configured in '/etc/backup.d', run ninjahelper!
+
+# The following has to be done without invoking a subshell (see BashFAQ #24)
+logupdates=`maketemp ninjadata`
+
+/usr/sbin/logtail -f $host > $logupdates
+grep FINISHED $logupdates | 
+(
+       fatal=0
+       warning=0
+       error=0
+
+       while read line
+       do
+               line_array=($line)
+               fatal=$(($fatal + ${line_array[8]}))
+               error=$(($error + ${line_array[10]}))
+               warning=$(($warning + ${line_array[12]}))
+       done
+       if (( $fatal || $warning || $error )); then
+               echo "`basename $host .log`: $fatal fatals found, $error errors found, $warning warnings found" >> $statusfile
+               echo "" >> $reportappend
+               echo "`basename $host .log` log entries since last ninjareport" >> $reportappend
+               echo "---------" >> $reportappend
+               cat $logupdates >> $reportappend
+               rm $logupdates
+       fi
+)
+
+}
+
+generatereport() {
+
+reportfile=`maketemp ninjareport`
+
+# Generate a report, only if there are failures
+if [ -s $statusfile ]; then
+       echo "         backupninja mission failures - `date`" >> $reportfile
+       echo "       --------------------------------------------------------------" >> $reportfile
+       echo "" >> $reportfile
+       cat $statusfile | column -t >> $reportfile
+       echo "" >> $reportfile
+       echo "         log entries from failed reports" >> $reportfile
+       echo "       -----------------------------------" >> $reportfile
+       cat $reportappend >> $reportfile
+fi
+
+}
+
+usage() {
+       cat << EOF
+This script generates a backupninja status report for all configured
+systems. It requires that each status report is placed in a spot where
+ninjareport can read it, reports are mailed to the reportemail
+configured in @CFGDIR@/backupninja.conf.
+
+The following options are available:
+-h, --help             This usage message
+-f, --conffile FILE    Use FILE for the configuration instead
+                       of @CFGDIR@/backupninja.conf
+-m, --mail <email>     Mail the report to this address
+-o, --out              Don't mail the report, just display it
+
+EOF
+}
+
+#####################################################
+## MAIN
+
+conffile="@CFGDIR@/backupninja.conf"
+
+## process command line options
+
+while [ $# -ge 1 ]; do
+       case $1 in
+               -h|--help) 
+                        usage
+                       exit 0
+                       ;;
+               -f|--conffile)
+                       if [ -f $2 ]; then
+                               conffile=$2
+                       else
+                               echo "-f|--conffile option must be followed by an existing filename"
+                               fatal "-f|--conffile option must be followed by an existing filename"
+                               usage
+                       fi
+                       # we shift here to avoid processing the file path 
+                       shift
+                       ;;
+               -m|--mail)
+                       reportemail=$2
+                       shift
+                       ;;
+               -o|--out)
+                       mail=0
+                       display=1
+                       ;;
+               *)
+                       echo "Unknown option $1"
+                       usage
+                       exit
+                       ;;
+       esac
+       shift
+done                                                                                                                                                                                                           
+
+## Load and confirm basic configuration values
+
+# bootstrap
+if [ ! -r "$conffile" ]; then
+       echo "Configuration file $conffile not found." 
+       fatal "Configuration file $conffile not found."
+fi
+
+# find $libdirectory
+libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'`
+if [ -z "$libdirectory" ]; then
+   if [ -d "@libdir@" ]; then
+      libdirectory="@libdir@"
+   else
+      echo "Could not find entry 'libdirectory' in $conffile." 
+      exit 1
+   fi
+else
+   if [ ! -d "$libdirectory" ]; then
+      echo "Lib directory $libdirectory not found." 
+      exit 1
+   fi
+fi
+
+# include shared functions
+. $libdirectory/tools
+
+setfile $conffile
+
+getconf reportdirectory
+getconf reportemail
+
+## Process each configuration file
+
+hosts=`find $reportdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '*.offset' | sort -n`
+
+if [ -z "$hosts" ]; then
+       echo "Fatal: No backupninja reports found in '$reportdirectory'!"
+       mail=0
+fi
+
+statusfile=`maketemp ninjastatus`
+reportappend=`maketemp ninjaappend`
+
+for host in $hosts; do
+       [ -f "$host" ] || continue
+       # Check somehow that the file is a valid report file
+       process $host
+done
+
+generatereport
+
+## mail the report to the report address or display it
+
+if [ -s $reportfile ]; then
+    if [ $mail == 1 ]; then
+       mail -s "backupninja mission failure report" $reportemail < $reportfile
+    fi
+fi
+
+if [ $display == 1 ]; then
+       cat $reportfile
+fi
+