+++ /dev/null
-#!/usr/bin/env python
-
-"""
-Small utility to continuous trace an afs-client in a files storing x mins and keep files if something has happened
-"""
-
-import subprocess, time, getopt, sys
-from multiprocessing import Process
-from shutil import copyfile
-import os, string
-
-Output="afsclient.trace"
-ProcessTableFilename="proctable"
-numTraceFiles=2
-TraceFileNames=[]
-FSTRACEBIN="/usr/sbin/fstrace"
-PSBIN="/bin/ps"
-KILLBIN="/bin/kill"
-TraceBufferSize=8192 # buffersize in k, needs to be big enough to store the data during Dumpinterval
-Dumpinterval = 1 # at what interval buffer should be dumped to file
-DumpProcs=[None, None]
-EventCheckInterval = 1 # interval for checking for an externalEvent
-RotationInterval=5 # 5 EventCheckInterval
-EventFile="./fstrace_trigger"
-verbose = False
-debug=False
-Mode="cont"
-# available Modes
-# cont(inuous)
-# single
-
-def setupFSTrace() :
- if verbose : print "Clearing log"
- try :
- subprocess.check_call([FSTRACEBIN,"clear", "cm"])
- except subprocess.CalledProcessError:
- print "Unable to run fstrace-binary at %s." % FSTRACEBIN
- sys.exit(2)
- if verbose : print "setting eventset cm active"
- subprocess.check_call([FSTRACEBIN,"setset","cm","-active"])
- if verbose : print "Setting buffersize of log cmfx"
- subprocess.check_call([FSTRACEBIN,"setlog","cmfx","-buffersize", "%s" % TraceBufferSize])
- return
-
-def dumpFSTrace(FileName) :
- subprocess.check_call([FSTRACEBIN,"dump","-follow","cmfx","-file",FileName, "-sleep", "%s" % Dumpinterval])
- return
-
-def saveLogs(ProcessTable, TraceFileNo):
- NowStr=time.strftime("%H:%M:%S_%d.%m-%Y", time.localtime())
- for counter in range(numTraceFiles) :
- thisTraceFileNo=(TraceFileNo+counter) % numTraceFiles
- print "current TraceFileNo = %s" % TraceFileNo
- if verbose : print "Saving log %s-%s to %s-%s-%s" % (Output,thisTraceFileNo, Output,counter, NowStr)
- copyfile("%s-%s" % (Output, thisTraceFileNo), "%s-%s-%s" % ( Output,counter, NowStr))
- # also save ProcessTable of this interval
- if verbose : print "Saving ProcessTable to %s-%s" % (ProcessTableFilename,NowStr)
- f=file("%s-%s" % (ProcessTableFilename,NowStr), "w+")
- _PIDs=ProcessTable.keys()
- PIDs=[]
- for pid in _PIDs :
- PIDs.append(int(pid))
- PIDs.sort()
- for pid in PIDs :
- f.write("%s %s %s\n" % (pid, ProcessTable["%s" % pid]["parentpid"],ProcessTable["%s" % pid]["cmd"]))
- f.close()
- return
-
-def updateProcessTable():
- ProcessTable={}
- call=subprocess.Popen([PSBIN, "-eaf"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- line=call.stdout.readline() # ignore headerline
- while 1:
- line=call.stdout.readline()
- if not line :break
- tokens=line.split()
- if len(tokens) < 8 : continue
- pid=tokens[1]
- parentpid=tokens[2]
- cmd=string.join(tokens[7:], " ")
- # we do make the assumption that a pid is not reused within a rotationinterval.
- ProcessTable[pid] ={"cmd" : cmd}
- ProcessTable[pid]["parentpid"] = parentpid
- return ProcessTable
-
-def getChildPid(pid,ProcessTable) :
- kids=[]
- for _pid in ProcessTable :
- if ProcessTable[_pid]["parentpid"] == "%s" % pid :
- kids.append(_pid)
- pids=ProcessTable.keys()
- pids.sort()
- if 0 :
- for p in pids :
- print "%s : %s" % (p,ProcessTable[p])
- return kids
-
-def killPid(pid,signal="TERM") :
- rc=subprocess.call([KILLBIN, "-%s" % signal,pid])
- return rc
-
-def main():
- setupFSTrace()
- TraceFileNo=0
- FileName=TraceFileNames[TraceFileNo]
- DumpProcNum=0
- if debug : print "Spawning dump-process to %s" % FileName
- DumpProcs[DumpProcNum] = Process(target=dumpFSTrace, args=(FileName,))
- DumpProcs[DumpProcNum].start()
- if Mode == "single" : # single-shot mode
- while 1 :
- if debug : print "Waiting for %s until next check for external Event." % EventCheckInterval
- ProcessTable=updateProcessTable()
- if externalEvent(EventFile) :
- DumpProcs[DumpProcNum].terminate()
- ProcessTable=updateProcessTable()
- if debug :
- print "Killing childpids of %s : %s " % (DumpProcs[DumpProcNum].pid,getChildPid("%s" % DumpProcs[DumpProcNum].pid,ProcessTable))
- for kid in getChildPid("%s" % DumpProcs[DumpProcNum].pid,ProcessTable) :
- killPid(kid)
- saveLogs(ProcessTable)
- break
- time.sleep(EventCheckInterval)
- sys.exit(0)
- # continuous run
- while 1 :
- Waited=0
- while Waited < RotationInterval :
- if debug : print "Waiting for %s until next check for external Event." % EventCheckInterval
- time.sleep(EventCheckInterval)
- Waited += 1
- ProcessTable=updateProcessTable()
- if debug :
- print "Waitcount = %s" % Waited
- print "RotationInterval %s" % RotationInterval
- print "ProcessTable :"
- print len(ProcessTable)
- if externalEvent(EventFile) :
- saveLogs(ProcessTable, TraceFileNo)
- if debug : print "Rotating Logs"
- TraceFileNo = (TraceFileNo+1) % (numTraceFiles)
- FileName=TraceFileNames[TraceFileNo]
- newDumpProcNum= (DumpProcNum +1) % 2
- if debug : print "Spawning next dump-process no %s to %s" % (newDumpProcNum, FileName)
- DumpProcs[newDumpProcNum] = Process(target=dumpFSTrace, args=(FileName,))
- DumpProcs[newDumpProcNum].start()
- ProcessTable=updateProcessTable()
- if debug : print "Terminating last dump-process %s" % DumpProcNum
- DumpProcs[DumpProcNum].terminate()
- if debug :
- print "Killing childpids of %s : %s " % (DumpProcs[DumpProcNum].pid,getChildPid("%s" % DumpProcs[DumpProcNum].pid,ProcessTable))
- for kid in getChildPid("%s" % DumpProcs[DumpProcNum].pid,ProcessTable) :
- if debug : print ProcessTable[kid]
- killPid(kid)
- if debug: print DumpProcs
- DumpProcNum=newDumpProcNum
- return
-
-#
-# This function has to be replaced for new debugging cases
-#
-
-def externalEvent(EventFile):
- if os.path.isfile(EventFile) :
- os.unlink(EventFile)
- if verbose : print "external event happened!"
- return True
- if debug : print "no external event"
- return False
-
-def usage():
- print "ClientTracing.py --dumpinterval=# --rotationinterval=# --buffersize=# --numfiles # --mode=[cont|single] --savemode=[lastonly|all] --verbose --debug"
- print "--dumpinterval=# / secs : interval of fstrace in secs to dump information"
- print "--eventcheckinterval=# / secs : How many secondes to wait between checking for an event"
- print "--Eventfile=<name> : file to check if an external event happened"
- print "--rotationinterval=# /units EventCheckInterval"
- print "--buffersize=# buffer of fstrace log in memory"
- print "--numfiles # how many logfiles to write"
- print "--mode=[cont|single]"
- print
- print "An event is triggered by the existance of the file %s\n" % EventFile
- print "You may also overwrite the function externalEvent()"
-
-
-if __name__ == "__main__" :
- try:
- opts, args = getopt.getopt(sys.argv[1:], "he:E:d:r:m:b:vdn:s:", ["help", "eventcheckinterval=","Eventfile=","dumpinterval=", "rotationinterval=", "mode=", "buffersize=","verbose", "debug","numfiles=", "savemode="])
- except getopt.GetoptError, err:
- # print help information and exit:
- print str(err) # will print something like "option -a not recognized"
- usage()
- sys.exit(2)
- for o, a in opts:
- if o in ("-v", "--verbose"):
- verbose = True
- elif o in ("-d", "--debug") :
- debug = True
- elif o in ("-h", "--help"):
- usage()
- sys.exit()
- elif o in ("-e", "--eventcheckinterval") :
- EventCheckInterval = int(a)
- elif o in ("-E", "--Eventfile") :
- EventFile = int(a)
- elif o in ("-d", "--dumpinterval") :
- Dumpinterval = int(a)
- elif o in ('-r', "--rotationinterval") :
- RotationInterval = int(a)
- elif o in ("-b", "--buffersize") :
- TraceBufferSize=int(a)
- elif o in ("-m", "--mode") :
- Mode=a
- if not Mode in ['cont','single'] :
- print "mode takes only >cont< or >single< "
- sys.exit(2)
- elif o in ("-o", "--output") :
- Output=a
- elif o in ("-n", "--numfiles") :
- numTraceFiles=int(a)
- else :
- print "Unknown option %s" % o
- sys.exit(2)
- for i in range(int(numTraceFiles)) :
- TraceFileNames.append("%s-%s"% (Output, i))
-
- if verbose :
- print "Buffersize: %s" % TraceBufferSize
- print "Dumpinterval: %s" % Dumpinterval
- print "number of Tracfiles : %s" % numTraceFiles
- print "TraceFilenames: %s-#" % Output
- print "Rotationinterval: %s" % RotationInterval
- print "ProcessTableFilename=%s" % ProcessTableFilename
- print "Mode: %s" % Mode
- main()