From: Martin Zobel-Helas Date: Fri, 8 Feb 2013 16:33:26 +0000 (+0100) Subject: add dsa-check-bacula X-Git-Url: https://wiki.adam-barratt.org.uk/gitweb/?a=commitdiff_plain;h=3c650660fea8ff03e462daef4dc52cf26e1a98c0;p=mirror%2Fdsa-nagios.git add dsa-check-bacula Signed-off-by: Martin Zobel-Helas --- diff --git a/dsa-nagios-checks/dsa-check-bacula b/dsa-nagios-checks/dsa-check-bacula new file mode 100755 index 0000000..69988fe --- /dev/null +++ b/dsa-nagios-checks/dsa-check-bacula @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# +# check_bacula_client Nagios plugin to check Bacula client backups +# Copyright (C) 2010 Tom Payne +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from datetime import datetime, timedelta +from optparse import OptionParser, OptionValueError +import re +import sys +import time + +import pexpect + + +OK, WARNING, CRITICAL, UNKNOWN = xrange(0, 4) +status_message = 'OK WARNING CRITICAL UNKNOWN'.split() + +MULTIPLIERS = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400, 'w': 604800} +DIVISORS = ((60, 'minutes'), (60, 'hours'), (24, 'days'), (7, 'weeks')) + + +def parse_period(option, opt_str, value, parser): + m = re.match(r'(\d+(?:\.\d+)?)(%s)\Z' % '|'.join(MULTIPLIERS.keys()), value) + if not m: + raise OptionValueError('invalid period - %s' % value) + setattr(parser.values, option.dest, timedelta(seconds=float(m.group(1)) * MULTIPLIERS[m.group(2)])) + + +def main(argv): + parser = OptionParser() + parser.add_option('-H', metavar='ADDRESS', dest='host', help='client name') + parser.add_option('-w', metavar='PERIOD', type=str, dest='warning', action='callback', callback=parse_period, help='generate warning if last successful backup older than PERIOD') + parser.add_option('-c', metavar='PERIOD', type=str, dest='critical', action='callback', callback=parse_period, help='generate critical if last successful backup older than PERIOD') + parser.add_option('-b', metavar='PATH', dest='bconsole', help='path to bconsole') + parser.set_defaults(bconsole='/usr/bin/bconsole') + options, args = parser.parse_args(argv[1:]) + exit_status, message = OK, None + child = pexpect.spawn(options.bconsole, ['-n']) + try: + child.expect(r'\n\*') + child.sendline('status client=%s.debian.org-fd' % options.host) + if child.expect_list([re.compile(r'Terminated Jobs:'), re.compile(r'Error: Client resource .* does not exist.')]): + raise RuntimeError('unknown client %s' % options.host) + child.expect(r'\n\*') + r = re.compile(r'\s*(\d+)\s+(\S+)\s+(\S+)\s+(\d+\.\d+\s+[KMGTP]|0)\s+OK\s+(\S+\s+\S+)') + job_id = level = files = bytes = finished = None + for line in child.before.splitlines(): + m = r.match(line) + if m: + job_id = int(m.group(1)) + level = m.group(2) + files = int(re.sub(r',', '', m.group(3))) + bytes = re.sub(r'\s+', '', m.group(4)) + finished = datetime(*(time.strptime(m.group(5), '%d-%b-%y %H:%M')[0:6])) + if job_id is None: + raise RuntimeError('no terminated jobs') + age = datetime.now() - finished + if options.warning and age > options.warning: + exit_status = WARNING + if options.critical and age > options.critical: + exit_status = CRITICAL + age, units = 24.0 * 60 * 60 * age.days + age.seconds, 'seconds' + for d, u in DIVISORS: + if age < d: + break + else: + age /= d + units = u + message = '%s, %d files, %sB, %s (%.1f %s ago)' % (level, files, bytes, finished, age, units) + except RuntimeError: + exit_status, message = (CRITICAL, str(sys.exc_info()[1])) + child.sendeof() + child.expect(pexpect.EOF) + print '%s: %s' % (status_message[exit_status], message) + sys.exit(exit_status) + + +if __name__ == '__main__': + main(sys.argv)