#!/usr/bin/env python #************************************************************************** # Copyright (C) 2008-2015 by Walter Brisken * # * # 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, write to the * # Free Software Foundation, Inc., * # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #************************************************************************** #=========================================================================== # SVN properties (DO NOT CHANGE) # # $Id$ # $HeadURL: $ # $LastChangedRevision$ # $Author$ # $LastChangedDate$ # #============================================================================ from string import split, strip, find, upper, lower from sys import argv, exit from os import popen, getenv from glob import glob import socket import struct from xml.parsers import expat from copy import deepcopy from time import asctime import signal program = 'errormon' author = 'Walter Brisken' version = '0.8' verdate = '20150811' alertLevels = ['FATAL', 'SEVERE', 'ERROR', 'WARNING', 'INFO', 'VERBOSE', 'DEBUG', 'IGNORE'] def signal_handler(signal, frame): print('You pressed Ctrl+C!') exit(0) def usage(prog): print '%s ver. %s %s %s\n' % (program, version, author, verdate) print 'Usage: %s [options] []\n' % prog print 'options can include:' print ' --help' print ' -h print help information and quit\n' print ' is the max alert error level to print. The levels are:' for level in range(len(alertLevels)): print ' %d = %s' % (level, alertLevels[level]) print '' class Parser: def __init__(self): self._parser = expat.ParserCreate() self._parser.StartElementHandler = self.start self._parser.EndElementHandler = self.end self._parser.CharacterDataHandler = self.data self.message = '' self.severity = -1 self.tmp = '' self.ok = False self.unit = '' self.mpiid = -1 self.id = '' self.tag = '' def feed(self, data): self._parser.Parse(data, 0) def close(self): self._parser.Parse("", 1) # end of data del self._parser # get rid of circular references def start(self, tag, attrs): self.tag = tag self.tmp = '' if tag == 'difxAlert': self.ok = True def end(self, tag): if tag == 'alertMessage' and self.ok: self.message = self.tmp elif tag == 'severity': self.severity = int(self.tmp) elif tag == 'from': self.unit = lower(self.tmp) elif tag == 'identifier': self.id = self.tmp elif tag == 'mpiProcessId': self.mpiid = int(self.tmp) def data(self, data): if self.tag == 'alertMessage': self.tmp = self.tmp + data else: self.tmp = data def getinfo(self): if self.ok: return 'MPI[%2d] %-9s %-12s %-7s %s' % (self.mpiid, self.unit, self.id, alertLevels[self.severity], self.message) else: return '' def run(maxlevel): port = getenv('DIFX_MESSAGE_PORT') if port == None: print 'DIFX_MESSAGE_PORT needs to be defined' exit(0) else: port = int(port) group = getenv('DIFX_MESSAGE_GROUP') if group == None: print 'DIFX_MESSAGE_GROUP needs to be defined' exit(0) # Is this a multicast IP address? groupint = struct.unpack("!I", socket.inet_aton(group))[0] if (groupint>>28==14): multicast = True else: multicast = False s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 768000) s.bind(('', port)) if (multicast): mreq = struct.pack("4sl", socket.inet_aton(group), socket.INADDR_ANY) s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) #s.settimeout(dt) try: while 1: try: message = s.recv(1500) if len(message) > 0 and message[0] == '<': p = Parser() p.feed(message) info = p.getinfo() p.close() if len(info) > 0 and p.severity <= maxlevel: print asctime(), info except socket.timeout: pass except expat.ExpatError: print asctime(), '*** Unparsable message received ***' print message except KeyboardInterrupt: pass signal.signal(signal.SIGINT, signal_handler) if len(argv) > 1: if argv[1] in ['-h', '--help']: usage(argv[0]) exit(0) maxlevel = int(argv[1]) else: maxlevel = 8 run(maxlevel) # Play nice with emacs # Local Variables: # indent-tabs-mode: 1 # tab-width: 4 # End: