#!/usr/bin/env python # # Copyright (C) 2013 Eric Schultz # Modified version of check_zaptel originally by Ezio Vernacotola # # 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Nagios plugin to check the status of dahdi devices and channels, mainly used in asterisk pbxs Usage: check_dahdi [-v] -s span[,span[...]] [-e chan[,chan[...]]] -s n[,n[...]] Spans to check -e n[,n[...]] Channels to exclude examples: check_zaptel -s 1,2,3 check_zaptel -s 1,2 -e 5,34,40 CHANGES 2013-03-18 version 1.0: initial release """ import sys import os from optparse import OptionParser import re status_msg = ['OK', 'Warning', 'Critical', 'Unknown'] class NagiosPlugin: """Nagios plugin superclass""" service = None def __init__(self): self.status = None self.info = None self.verbose = 0 self.excludes = [] def check(self): self.status = 3 self.info = '' def printstatus(self): print '%s %s: %s' % (self.service, status_msg[self.status], self.info) class DahdiNagiosPlugin(NagiosPlugin): """Dahdi Nagios plugin class""" service = 'DAHDI' def __init__(self): self.excldes = [] def check_span(self, span): """check the status of a span""" procfn = '/proc/dahdi/%d' % span if not os.path.isfile(procfn): return ('NO SPAN', '', 'Span: %s' %span, 'Span: %s' % span, 'Span: %d No such file or directory: %s' % (span, procfn), 0, 0, '') zapst = file('/proc/dahdi/%d' % span) firstline = zapst.readline().strip() spanre = 'Span (?P\d+): (?P\S+) "(?P.+)" ?(?P\S*) ?(?P.*)' m = re.compile(spanre).match(firstline) rest = m.group('rest') restflds = rest.split() alarm = '' warning = '' for rfld in restflds: if rfld in ['BLUE', 'YELLOW', 'RED']: # error alarm = rfld break elif rfld in ['NOTOPEN', 'RECOVERING', 'LOOPBACK']: # warning warning = rfld else: pass # ci frega poco calarm = [] cwarn = [] lre = re.compile('^\s*(\d+)\s+.*?(RED|YELLOW|BLUE|NOTOPEN|RECOVERING|LOOPBACK)') for cline in zapst: cline = cline.strip() lm = lre.match(cline) if lm and not lm.group(1) in self.excludes: if lm.group(2) in ['RED','YELLOW','BLUE']: calarm.append(lm.group(1)+':'+lm.group(2)) else: cwarn.append(lm.group(1)+':'+lm.group(2)) chan = '' if len(calarm) > 0: chan = "Alarm - " + ','.join(calarm) if len(cwarn) > 0: chan = "Warning - " + ','.join(cwarn) return (alarm, warning, m.group('spname'), m.group('descr'), firstline, len(calarm), len(cwarn), chan) def check(self): """execute the checks requested""" warnings = 0 errors = 0 exceptions = 0 msg = [] # Check all the spans and all the channels for sp in self.spans: try: alarm, warning, spname, descr, firstline, calarm, cwarn, channels = self.check_span(int(sp)) except Exception, E: alarm, warning, spname, descr, firstline, calarm, cwarn, channels = '', '', str(E), str(E), str(E), 0, 0, str(E) exceptions += 1 if alarm: errors += 1 if warning: warnings += 1 if calarm: errors += calarm if cwarn: earnings += cwarn ss = '' if self.verbose == 0: if alarm: ss = spname+':'+alarm else: ss = spname elif self.verbose == 1: if alarm: ss = descr+':'+alarm else: ss = descr else: ss = firstline if channels != '': msg.append(ss+' '+channels) else: msg.append(ss) if exceptions > 0: self.status = 3 elif errors > 0: self.status = 2 elif warnings > 0: self.status = 1 else: self.status = 0 self.info = ', '.join(msg) def main(): uso = """%prog [-v] -s span[,span[...]] [-e chan[,chan[...]]] -s n[,n[...]] Spans to check -e n[,n[...]] Channels to exclude examples: check_zaptel -s 1,2,3 check_zaptel -s 1,2 -e 5,34,40 """ opt = OptionParser(uso) opt.set_defaults(verbose=0) opt.add_option('-v', '--verbose', dest="verbose", action="count" ) opt.add_option('-e', dest="exclude", default=[], action="append", help="Exclude Channel (multiple allowed)") opt.add_option('-s', dest="span", default=[], action="append", help="Spans (multiple allowed)") (options, args) = opt.parse_args() spans = [] for s in options.span: spans = spans + s.split(',') if len(spans) == 0: opt.error('No span specified!') excludes = [] for e in options.exclude: excludes = excludes + e.split(',') CheckDahdi = DahdiNagiosPlugin() CheckDahdi.verbose = options.verbose CheckDahdi.excludes = excludes CheckDahdi.spans = spans CheckDahdi.check() CheckDahdi.printstatus() sys.exit(CheckDahdi.status) main()