Add a vim modeline with indentation settings.
[matthijs/upstream/backupninja.git] / src / ninjareport.in
1 #!@BASH@
2 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
3 # vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
4 #
5 #
6 # Ninjareport - generate a single simple report for a lot of hosts
7 #
8 # requires logtail
9 #
10 # Copyright (C) 2007 - riseup.net -- property is theft.
11
12 # TODO:
13 #
14 #  . check for logs that are never updating and warn
15 #  . change constantly updating logs (maildir) to be more friendly
16 #  . documentation
17 #  . maybe make config option that lists all hosts that should report-in, and if
18 #    one doesn't then warn
19 #  . restrict rsync somehow?
20 #  . abstract path for logtail
21 #  . on the report master, the reportdirectory should be set where the reports will be going, note this
22
23 mail=1
24 display=0
25
26 process() {
27
28 # look in the logfile for any lines like the following:
29 # Jan 20 01:02:46 Info: FINISHED: 2 actions run. 0 fatal. 0 error. 0 warning.
30 #
31 # note: some backups never finish, such as the maildir one, need to handle these
32 # perhaps by looking for FAILED messages?
33 # note2: what about logs that aren't being updated? this is a failure case and
34 # should be looked for
35 # note3: there are also these entries:
36 # Jan 20 14:00:01 Fatal: No backup actions configured in '/etc/backup.d', run ninjahelper!
37
38 # The following has to be done without invoking a subshell (see BashFAQ #24)
39 logupdates=`maketemp ninjadata`
40
41 /usr/sbin/logtail -f $host > $logupdates
42 grep FINISHED $logupdates |
43 (
44    fatal=0
45    warning=0
46    error=0
47
48    while read line
49    do
50       line_array=($line)
51       fatal=$(($fatal + ${line_array[8]}))
52       error=$(($error + ${line_array[10]}))
53       warning=$(($warning + ${line_array[12]}))
54    done
55    if (( $fatal || $warning || $error )); then
56       echo "`basename $host .log`: $fatal fatals found, $error errors found, $warning warnings found" >> $statusfile
57       echo "" >> $reportappend
58       echo "`basename $host .log` log entries since last ninjareport" >> $reportappend
59       echo "---------" >> $reportappend
60       cat $logupdates >> $reportappend
61       rm $logupdates
62    fi
63 )
64
65 }
66
67 generatereport() {
68
69 reportfile=`maketemp ninjareport`
70
71 # Generate a report, only if there are failures
72 if [ -s $statusfile ]; then
73    echo "         backupninja mission failures - `date`" >> $reportfile
74    echo "       --------------------------------------------------------------" >> $reportfile
75    echo "" >> $reportfile
76    cat $statusfile | column -t >> $reportfile
77    echo "" >> $reportfile
78    echo "         log entries from failed reports" >> $reportfile
79    echo "       -----------------------------------" >> $reportfile
80    cat $reportappend >> $reportfile
81 fi
82
83 }
84
85 usage() {
86    cat << EOF
87 This script generates a backupninja status report for all configured
88 systems. It requires that each status report is placed in a spot where
89 ninjareport can read it, reports are mailed to the reportemail
90 configured in @CFGDIR@/backupninja.conf.
91
92 The following options are available:
93 -h, --help             This usage message
94 -f, --conffile FILE    Use FILE for the configuration instead
95                        of @CFGDIR@/backupninja.conf
96 -m, --mail <email>     Mail the report to this address
97 -o, --out              Don't mail the report, just display it
98
99 EOF
100 }
101
102 #####################################################
103 ## MAIN
104
105 conffile="@CFGDIR@/backupninja.conf"
106
107 ## process command line options
108
109 while [ $# -ge 1 ]; do
110    case $1 in
111       -h|--help)
112          usage
113          exit 0
114          ;;
115       -f|--conffile)
116          if [ -f $2 ]; then
117             conffile=$2
118          else
119             echo "-f|--conffile option must be followed by an existing filename"
120             fatal "-f|--conffile option must be followed by an existing filename"
121             usage
122          fi
123          # we shift here to avoid processing the file path
124          shift
125          ;;
126       -m|--mail)
127          reportemail=$2
128          shift
129          ;;
130       -o|--out)
131          mail=0
132          display=1
133          ;;
134       *)
135          echo "Unknown option $1"
136          usage
137          exit
138          ;;
139    esac
140    shift
141 done
142
143 ## Load and confirm basic configuration values
144
145 # bootstrap
146 if [ ! -r "$conffile" ]; then
147    echo "Configuration file $conffile not found."
148    fatal "Configuration file $conffile not found."
149 fi
150
151 # find $libdirectory
152 libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'`
153 if [ -z "$libdirectory" ]; then
154    if [ -d "@libdir@" ]; then
155       libdirectory="@libdir@"
156    else
157       echo "Could not find entry 'libdirectory' in $conffile."
158       exit 1
159    fi
160 else
161    if [ ! -d "$libdirectory" ]; then
162       echo "Lib directory $libdirectory not found."
163       exit 1
164    fi
165 fi
166
167 # include shared functions
168 . $libdirectory/tools
169
170 setfile $conffile
171
172 getconf reportdirectory
173 getconf reportemail
174
175 ## Process each configuration file
176
177 hosts=`find $reportdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '*.offset' | sort -n`
178
179 if [ -z "$hosts" ]; then
180    echo "Fatal: No backupninja reports found in '$reportdirectory'!"
181    mail=0
182 fi
183
184 statusfile=`maketemp ninjastatus`
185 reportappend=`maketemp ninjaappend`
186
187 for host in $hosts; do
188    [ -f "$host" ] || continue
189    # Check somehow that the file is a valid report file
190    process $host
191 done
192
193 generatereport
194
195 ## mail the report to the report address or display it
196
197 if [ -s $reportfile ]; then
198    if [ $mail == 1 ]; then
199       mail -s "backupninja mission failure report" $reportemail < $reportfile
200    fi
201 fi
202
203 if [ $display == 1 ]; then
204    cat $reportfile
205 fi