aboutsummaryrefslogtreecommitdiff
path: root/src/ninjareport.in
blob: 4bc244e1da11dc0db17e1335fe84ffe3a71db90e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!@BASH@
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
# vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
#
#
# 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