'''Command: %(cmdName)s.py Role: Process a perfservlet XML document, and display results. Usage: python %(cmdName)s.py filename\n Where: filename is a valid path to a perfservlet XML document.\n Example: python %(cmdName)s.py beanModule.xml''' import os, re, os.path, sys, types; from xml.dom import *; from xml.dom import minidom; from time import gmtime, localtime, strftime; __DEBUG__ = False; timestats_line_msg = """INFO|%(jvmname)s:%(nodename)s:%(statname)s:%(stattype)s:%(lastSampleTime)s:%(max)s:%(min)s:%(name)s:%(startTime)s:%(totalTime)s:%(unit)s """ timestats_nagios_msg = """%(lastSampleTime)s:%(max)s:%(min)s:%(name)s:%(startTime)s:%(totalTime)s:%(unit)s """ time_stat_fields = { "ID" : "", "lastSampleTime" : "", "max" : "", "min" : "", "name" : "", "startTime" : "", "totalTime" : "", "unit" : "" }; rangestats_line_msg = """INFO|%(jvmname)s:%(nodename)s:%(statname)s:%(stattype)s:%(highWaterMark)s:%(integral)s:%(lastSampleTime)s:%(lowWaterMark)s:%(mean)s:%(name)s:%(startTime)s:%(unit)s:%(value)s """ rangestats_nagios_msg = """%(highWaterMark)s:%(integral)s:%(lastSampleTime)s:%(lowWaterMark)s:%(mean)s:%(name)s:%(startTime)s:%(unit)s:%(value)s """ range_stat_fields = { "ID" : "", "highWaterMark" : "", "integral" : "", "lastSampleTime" : "", "lowWaterMark" : "", "mean" : "", "name" : "", "startTime" : "", "unit" : "", "value" : "" }; countstats_line_msg = """INFO|%(jvmname)s:%(nodename)s:%(statname)s:%(stattype)s:%(count)s:%(lastSampleTime)s:%(name)s:%(startTime)s:%(unit)s """ countstats_nagios_msg = """%(count)s:%(lastSampleTime)s:%(name)s:%(startTime)s:%(unit)s """ count_stat_fields = { "ID" : "", "count" : "", "lastSampleTime" : "", "name" : "", "startTime" : "", "unit" : "" }; averagestats_line_msg = """INFO|%(jvmname)s:%(nodename)s:%(statname)s:%(stattype)s:%(count)s:%(lastSampleTime)s:%(max)s:%(mean)s:%(min)s:%(name)s:%(startTime)s:%(sumOfSquares)s:%(total)s:%(unit)s """ averagestats_nagios_msg = """%(count)s:%(lastSampleTime)s:%(max)s:%(mean)s:%(min)s:%(name)s:%(startTime)s:%(sumOfSquares)s:%(total)s:%(unit)s """ average_stat_fields = { "ID" : "", "count" : "", "lastSampleTime" : "", "max" : "", "mean" : "", "min" : "", "name" : "", "startTime" : "", "sumOfSquares" : "", "total" : "", "unit" : "" }; brstats_line_msg = """INFO|%(jvmname)s:%(nodename)s:%(statname)s:%(stattype)s:%(highWaterMark)s:%(integral)s:%(lastSampleTime)s:%(lowWaterMark)s:%(lowerBound)s:%(mean)s:%(name)s:%(startTime)s:%(unit)s:%(upperBound)s:%(value)s """ brstats_nagios_msg = """%(highWaterMark)s:%(integral)s:%(lastSampleTime)s:%(lowWaterMark)s:%(lowerBound)s:%(mean)s:%(startTime)s:%(upperBound)s:%(value)s:%(unit)s """ boundaryrange_stat_fields = { "ID" : "", "highWaterMark" : "", "integral" : "", "lastSampleTime" : "", "lowWaterMark" : "", "lowerBound" : "", "mean" : "", "name" : "", "startTime" : "", "unit" : "", "upperBound" : "", "value" : "" }; """ protected double calcRatio(long value, long max) { return ((double)value)/max * 100; } protected boolean isCritical(double ratio, long critical) { return ratio >= critical; } protected boolean isWarning(double ratio, long warning) { return ratio >= warning; } protected ResultLevel checkResult(double ratio, int critical, int warning) { if(isCritical(ratio, critical)) { return ResultLevel.CRITICAL; } else if(isWarning(ratio, warning)) { return ResultLevel.WARNING; } else { return ResultLevel.OK; } } """ #------------------------------------------------------------------------------- # Name: analyze() # Role: Analyze the user specified document #------------------------------------------------------------------------------- def analyze( xmldoc ) : nodes = getNodeList( xmldoc ); """ + + - = crit; def isWarning( ratio, warn ) : return ratio >= warn; #------------------------------------------------------------------------------- # Name: log() # Role: Display the specified message iff global __DEBUG__ is True #------------------------------------------------------------------------------- def log( msg ) : if __DEBUG__ : print msg; def formatNagiosOutputString( node, server, statname, stattype, statdata, statfmtstr, calcdata ) : tmpdict = {}; prefix = "CHECK|%s:%s:%s:%s:%s:%d/%d:(%d%%)" % ( calcdata[ 'check_result' ], statdata[ 'name' ], node.getAttribute( "name" ), server.getAttribute( "name" ), stattype, calcdata[ 'current_value' ], calcdata[ 'max_value' ], calcdata[ 'threshhold_calculation' ] ); suffix = statfmtstr % statdata; finalmsg = prefix + "|" + suffix; return finalmsg; def showBoundaryRangeNagiosStats( node, server, statname, warnval, critval, data ) : s = getBoundaryRangeStatsDict( data ) c = calcNagiosThreshhold( s['value'], s['upperBound'], warnval, critval ) o = formatNagiosOutputString( node, server, s['name'], statname, s, brstats_nagios_msg, c ) print o, def statsToDict( stats, fields ) : retdict = {} for name in fields.keys() : if stats.hasAttribute( name ) : retdict[ name ] = stats.getAttribute( name ) return retdict def showRangeStats( server, node, statname, d ) : prettyPrintStatsLine( server.getAttribute("name"), node.getAttribute("name"), statname, "RangeStatistic", rangestats_line_msg, getRangeStatsDict( d ) ) def showTimeStats( server, node, statname, d ) : prettyPrintStatsLine( server.getAttribute("name"), node.getAttribute("name"), statname, "TimeStatistic", timestats_line_msg, getTimeStatsDict( d ) ) def showAverageStats( server, node, statname, d ) : prettyPrintStatsLine( server.getAttribute("name"), node.getAttribute("name"), statname, "AverageStatistic", averagestats_line_msg, getAverageStatsDict( d ) ) def showBoundaryRangeStats( server, node, statname, d ) : prettyPrintStatsLine( server.getAttribute("name"), node.getAttribute("name"), statname, "BoundedRangeStatistic", brstats_line_msg, getBoundaryRangeStatsDict( d ) ) def showCountStats( server, node, statname, d ) : prettyPrintStatsLine( server.getAttribute("name"), node.getAttribute("name"), statname, "CountStatistic", countstats_line_msg, getCountStatsDict( d ) ) def getRangeList( root ) : retlist = getElementsByType( root, "RangeStatistic" ) return retlist def getRangeByName( root, name ) : retval = getElementByName( root, "RangeStatistic", name ) return retval def getCountList( root ) : retlist = getElementsByType( root, "CountStatistic" ) return retlist def getCountByName( root, name ) : retval = getElementByName( root, "CountStatistic", name ) return retval def getTimeList( root ) : retlist = getElementsByType( root, "TimeStatistic" ) return retlist def getTimeByName( root, name ) : retval = getElementByName( root, "TimeStatistic", name ) return retval def getAverageList( root ) : retlist = getElementsByType( root, "AverageStatistic" ) return retlist def getAverageByName( root, name ) : retval = getElementByName( root, "AverageStatistic", name ) return retval def getBoundaryRangeList( root ) : retlist = getElementsByType( root, "BoundedRangeStatistic" ) return retlist def getBoundaryRangeByName( root, name ) : retval = getElementByName( root, "BoundedRangeStatistic", name ) return retval def prettyPrintStatsLine( jvm, node, statname, stattype, msgtemplate, d ) : table = d table[ 'jvmname' ] = jvm table[ 'nodename' ] = node table[ 'statname' ] = statname table[ 'stattype' ] = stattype msg = msgtemplate % ( table ) print msg, def getThreadPoolByName( root, name ) : retnode = getStatByName( root, name ) return retnode def getThreadPoolList( root ) : retlist = [] retlist = getStatList( root ) return retlist def format_timemillis( t ) : """ 't' is in milliseconds and will be devided by 1000 """ import types if type(t) == types.StringType : val = long(t) else : val = t return strftime("%a, %d %b %Y %H:%M:%S +0000", localtime(val/1000) ) def getElementByName( root, nodetype, name ) : retval = None regex = "[ \t]*%s[ \t]*" % name rx = re.compile( regex ) elements = getElementsByType( root, nodetype ) if len(elements) <= 0 : return retval for item in elements : if item.nodeType == Node.ELEMENT_NODE : if item.hasAttribute("name") and rx.match( item.getAttribute("name") ) : retval = item break return retval def getElementsByType( root, nodetype ) : retlist = []; try : items = root.getElementsByTagName( nodetype ); log( 'getElementsByType( "%s" ) - ok' % nodetype ); for item in items : if item.nodeType == Node.ELEMENT_NODE : retlist.append( item ); except : log( 'getElementsByType( "%s" ) - fail' % nodetype ); return retlist def getStatList( root ) : try : retlist = getElementsByType( root, "Stat" ); log( 'getStatList() - ok' ); except : retlist = None; log( 'getStatList() - None' ); return retlist def getStatByName( root, name ) : try : retval = getElementByName( root, "Stat", name ); log( 'getStatByName( "%s" ) - ok' % name ); except : retval = None; log( 'getStatByName( "%s" ) - None' % name ); return retval def getNodeByName(root, name) : try : retval = getElementByName( root, "Node", name ); log( 'getNodeByName( "%s" ) - ok' % name ); except : retval = None; log( 'getNodeByName( "%s" ) - None' % name ); return retval def getNodeList( xmldoc ) : try : retlist = getElementsByType( xmldoc, "Node" ); log( 'getNodeList() - ok' ); except : retlist = None; log( 'getNodeList() - None' ); return retlist def getServerByName( node, server ) : try : retval = getElementByName( node, "Server", server ); log( 'getServerByName( "%s" ) - ok' % name ); except : retval = None; log( 'getServerByName( "%s" ) - None' % name ); return retval def getServerList( node ) : try : retlist = getElementsByType( node, 'Server' ); log( 'getServerList() - ok' ); except : retlist = None; log( 'getServerList() - None' ); return retlist #------------------------------------------------------------------------------- # Name: isAppServer() # Role: Use Regular Expressions (RegExp) to determine if the specified name is # either "nodeagent" or "dmgr". # Return: True : name isn't "nodeagent" or "dmgr" # False : name is "nodeagent" or "dmgr" #------------------------------------------------------------------------------- def isAppServer( name ) : return re.compile( '\s*(nodeagent|dmgr)\s*$' ).match( name ) == None; #------------------------------------------------------------------------------- # Name: Usage # Role: Display usage information, and terminate #------------------------------------------------------------------------------- def Usage( cmdName = None ) : if not cmdName : cmdName = 'wasstats'; print __doc__ % locals(); sys.exit( -1 ); #------------------------------------------------------------------------------- # Name: none # Role: Main execution point of script #------------------------------------------------------------------------------- if __name__ == '__main__' : # the program name and the two arguments # stop the program and print an error message if len( sys.argv ) != 2 : print 'Error - unexpected execution.\n'; Usage(); filename = sys.argv[ 1 ]; log( 'Checking: ' + filename ); if not os.path.exists( filename ) : print 'Filename "%s" does not exist or is inaccessible.\n' % filename; Usage(); log( 'Loading: ' + filename ); xmldoc = minidom.parse( filename ); log( 'Loaded' ); print 'Processing: ' + filename; analyze( xmldoc ); else : print 'Error - script must be executed, not imported.\n'; Usage( __name__ );