#!/usr/bin/python import sys import getopt import os import os.path import re ## ## Declares the wcvException class for the scripts ## class wcvException(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) class wcvParamException(wcvException): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) class wcvTypeException(wcvException): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) ## ## Returns the date as YYYYmmdd ## def wcvGetDate(sep=""): return str(time.strftime("%Y"+ sep + "%m" + sep +"%d")) ## ## Returns the time as hhmmss ## def wcvGetTime(sep=""): return str(time.strftime("%H" + sep + "%M" + sep + "%S")) ## ## Checks is Debugging is set ## def wcvSetDebugSwitch(): if os.environ.keys().count('WCV_DEBUG') != 1: print "DEBUG: Debugging is disabled" return 0 else: print "DEBUG: Debugging is enabled" return 1 ## ## Returns the templateFile name specified in the command line options ## def wcvSetFile (opts): if WCV_DEBUG: print "In function wcvSetFile opts:", opts for option, value in opts: if option == "--file": return value return "" ## ## Returns the ip address specified in the command line options ## def wcvSetIp (opts): if WCV_DEBUG: print "In function wcvSetIp opts:", opts for option, value in opts: if option == "--ip": return value return ".*" ## ## Returns the process id specified in the command line options ## def wcvSetPid (opts): if WCV_DEBUG: print "In function wcvSetPid opts:", opts for option, value in opts: if option == "--pid": return value return ".*" ## ## Returns the request id specified in the command line options ## def wcvSetReqId (opts): if WCV_DEBUG: print "In function wcvSetReqId opts:", opts for option, value in opts: if option == "--reqid": return value return ".*" ## ## Check if help option is requested ## def wcvCheckHelp (opts): if WCV_DEBUG: print "In function wcvCheckHelp opts:", opts for option, value in opts: if option in ("-?", "--help"): return 1 return 0 ## ## build the regex pattern for a parent line to search for ## def getParentRegExPattern(wcvPid=".*", wcvIp=".*", wcvReqId=".*"): if WCV_DEBUG: print "In function getParentRegExPattern wcvPid:", wcvPid print "In function getParentRegExPattern wcvIp:", wcvIp print "In function getParentRegExPattern wcvReqId:", wcvReqId regExPattern = ".*\ PMRM0003I:\ \ parent:ver=1,ip=" + wcvIp + ",time=.*,pid=" + wcvPid + ",reqid=" + wcvReqId + ".*" return regExPattern ## ## build the regex pattern for a current line to search for ## def getBaseCurrentRegExPattern(): if WCV_DEBUG: print "In function getBaseCurrentRegExPattern ...." regExPattern = ".*\ PMRM0003I:\ \ parent:ver=1,ip=.*current:ver=1.*" return regExPattern ## ## Prints a formatted line ## def printFormattedLine(wcvLevel, wcvIp, wcvPid, wcvReqId, wcvElapsed, wcvType, wcvDetail): if WCV_DEBUG: print "In function printFormattedLine wcvLevel:", wcvLevel print "In function printFormattedLine wcvPid:", wcvPid print "In function printFormattedLine wcvIp:", wcvIp print "In function printFormattedLine wcvReqId:", wcvReqId print "In function printFormattedLine wcvElapsed:", wcvElapsed print "In function printFormattedLine wcvType:", wcvType print "In function printFormattedLine wcvDetail:", wcvDetail print "|{0:>{col0}}|{1:>{col1}}|{2:>{col2}}|{3:>{col3}}|{4:>{col4}}|{5:<{col5}}|{6:<{col6}}|".format(wcvLevel, wcvIp, wcvPid, wcvReqId, wcvElapsed, wcvType, wcvDetail, col0=3, col1=16, col2=9,col3=9, col4=9, col5=9, col6=35) ##### print ("|%3s|%16s|%9s|%9s|%9s|%9s}|%35s|") % (wcvLevel, wcvIp, wcvPid, wcvReqId, wcvElapsed, wcvType, wcvDetail) ## ## Print header for output ## def printHeader(wcvIp, wcvPid, wcvReqId): if WCV_DEBUG: print "In function printHeader wcvPid:", wcvPid print "In function printHeader wcvIp:", wcvIp print "In function printHeader wcvReqId:", wcvReqId print ("Request metric data for parent ip=%s, parent pid=%s, parent request id =%s\n") % (wcvIp, wcvPid, wcvReqId) printFormattedLine("Lvl", "IP", "PID", "ReqId", "elapsed", "Type", "Detail") ## ## Prints a formatted output line ## def printLine(wcvLevel, wcvIp, wcvPid, wcvReqId, wcvElapsed, wcvType, wcvDetail ): if WCV_DEBUG: print "In function printLine wcvLevel:", wcvLevel print "In function printLine wcvPid:", wcvPid print "In function printLine wcvIp:", wcvIp print "In function printLine wcvReqId:", wcvReqId print "In function printLine wcvElapsed:", wcvElapsed print "In function printLine wcvType:", wcvType print "In function printLine wcvDetail:", wcvDetail printFormattedLine(wcvLevel, wcvIp, wcvPid, wcvReqId, wcvElapsed, wcvType, wcvDetail) ## ## Retrieve the current IP from the output record ## def getCurrentValue (record, key, termChar): if WCV_DEBUG: print "In function getCurrentValue for key:", key print "In function getCurrentValue for termChar:", termChar curVal = "" regExPattern = getBaseCurrentRegExPattern() regExPattern += key + "=(.*?)" + termChar curVal = re.sub(regExPattern, r"\1", record).replace("\n", "") if WCV_DEBUG: print "Returning:", curVal return curVal ## ## Usage of the script ## def printUsage (scriptName): print "Usage:", scriptName, "--help (this information) | (--ip --pid --reqid --file )" def checkParm (opts, scriptName): if WCV_DEBUG: print "In function checkParm with parameter opts=", opts print "In function checkParm with parameter scriptName=", scriptName ip = pid = reqid = file = "" for option, value in opts: print "option=" + option if option in ("-?", "--help"): printUsage (scriptName) sys.exit(0) elif (option == "--ip"): if (value == ""): raise wcvParamException, 'ip address to follow missing' else: ip = value elif (option == "--file"): if (value == ""): raise wcvParamException, 'file name missing' else: file = os.path.normpath(value) elif option == "--reqid": if (value == ""): raise wcvParamException, 'request id to follow must be specified' else: reqid = value elif option == "--pid": if (value == ""): raise wcvParamException, 'process id to follow must be specified' else: pid = value else: raise wcvParamException, 'Invalid option:', option ## ## Check for template File name ## if (not os.path.isfile(file)): raise wcvParamException, 'filename provided to follow request metric data does not exist' ## ## Can we open the file for read? ## try: inFile = open(file, "rU") inFile.close() except IOError: raise wcvParamException, '--file can not be read. Check file authorities' ## ## parent pid must be specified ## if (pid == ""): raise wcvParamException, '--pid must be specified' ## ## parent request-id must be specified ## if (reqid == ""): raise wcvParamException, '--reqid must be specified' return 0 ## ## Compiles the proxy configuration file based on the template file and processing the ## "#!/include " directives ## def printRequestMetricTreeFromList(wcvIndex, wcvLevel, wcvPid, wcvIp, wcvReqId): global WCV_FILE_DATA if WCV_DEBUG: print "Entering printRequestMetricTreeFromList using wcvIndex=", wcvIndex print "Entering printRequestMetricTreeFromList using wcvLevel=", wcvLevel print "Entering printRequestMetricTreeFromList using ", str(len(WCV_FILE_DATA)), "data records" print "Entering printRequestMetricTreeFromList using wcvPid=", wcvPid print "Entering printRequestMetricTreeFromList using wcvIp=", wcvIp print "Entering printRequestMetricTreeFromList using wcvReqId=", wcvReqId regExPattern = getParentRegExPattern(wcvPid, wcvIp, wcvReqId) regExObject=re.compile(regExPattern) while (wcvIndex >= 0): ## ## Read thru the file containing request metric data until the first record is found ## if regExObject.match(WCV_FILE_DATA[wcvIndex]): if WCV_DEBUG: print "Matching record found:", WCV_FILE_DATA[wcvIndex] curIp = getCurrentValue(WCV_FILE_DATA[wcvIndex], "ip", ",.*") curPid = getCurrentValue(WCV_FILE_DATA[wcvIndex], "pid", ",.*") curReqId = getCurrentValue(WCV_FILE_DATA[wcvIndex], "reqid", ",.*") curType = getCurrentValue(WCV_FILE_DATA[wcvIndex], "type", "\ .*") curDetail = getCurrentValue(WCV_FILE_DATA[wcvIndex], "detail", "\ .*") curElapsed = getCurrentValue(WCV_FILE_DATA[wcvIndex], "elapsed", "") printLine(str(wcvLevel), curIp, curPid, curReqId, curElapsed, curType, curDetail ) ## ## Recursion ... ## printRequestMetricTreeFromList(wcvIndex - 1, wcvLevel+1, curPid, curIp, curReqId) ## ## decrease index wcvIndex = wcvIndex - 1 ## ## Reads the file with the data and triggers processing ## def printRequestMetricTree(wcvFile, wcvPid, wcvIp, wcvReqId): if WCV_DEBUG: print "Entering printRequestMetricTree using wcvFile=", wcvFile print "Entering printRequestMetricTree using wcvPid=", wcvPid print "Entering printRequestMetricTree using wcvIp=", wcvIp print "Entering printRequestMetricTree using wcvReqId=", wcvReqId global WCV_FILE_DATA try: inFile = open(wcvFile, "rU") WCV_FILE_DATA = inFile.readlines() inFile.close() except IOError: raise wcvParamException, 'I/O exception raised while processing the input file' printRequestMetricTreeFromList (len(WCV_FILE_DATA) - 1, 0, wcvPid, wcvIp, wcvReqId) ## ## Main ## def main(): ## ## General prologue ## WCV_SCRIPTNAME = sys.argv[0] WCV_DEBUG = wcvSetDebugSwitch() if WCV_DEBUG: print "Script name=", WCV_SCRIPTNAME print "WCV_DEBUG=", WCV_DEBUG ## ## Split options ## sysArgv = sys.argv if WCV_DEBUG: print "DEBUG: sys.argv=", sys.argv print "DEBUG: sysArgv=", sysArgv try: opts, args = getopt.gnu_getopt(sysArgv, "?n:", ["ip=", "pid=", "file=", "reqid="]) except getopt.GetoptError, err: printUsage(WCV_SCRIPTNAME) print ">> Called exception: " + str(err) sys.exit(2) if WCV_DEBUG: print "DEBUG: opts after getopt.getopt =", opts print "DEBUG: args after getopt.getopt =", args ## ## Check the parameters being passed ## try: checkParm(opts, WCV_SCRIPTNAME) except (wcvParamException, wcvException), err: print ">> Caught exception: " + str(err) + " by checkParm" return 2 ## ## First check if "help" is requested ## if wcvCheckHelp (opts): printUsage(WCV_SCRIPTNAME) return 0 ## ## processing of the command. Set the input parameters. Defaut them as ".*" ## wcvFile = wcvSetFile(opts) wcvPid = wcvSetPid(opts) wcvIp = wcvSetIp(opts) wcvReqId = wcvSetReqId(opts) if WCV_DEBUG: print "wcvFile =", wcvFile print "wcvPid =", wcvPid print "wcvIp =", wcvIp print "wcvReqId =", wcvReqId printHeader(wcvIp, wcvPid, wcvReqId) printRequestMetricTree(wcvFile, wcvPid, wcvIp, wcvReqId) return 0 ###################### end of main ########################### ## ## Some globals ... ## WCV_SCRIPTNAME = "requestmetrics" WCV_DEBUG = wcvSetDebugSwitch() ## ## Using global to store file data as this can be quite big ... call by value would ## increate memory requrirements ## WCV_FILE_DATA=[] if __name__ == "__main__": main()