From 7fc5542c6536e29b9feb703daf4e33e9199601f1 Mon Sep 17 00:00:00 2001 From: iipeace Date: Tue, 15 Oct 2024 23:32:11 +0900 Subject: [PATCH] report: Add DRAWFLAME options Signed-off-by: iipeace --- guider/guider.py | 162 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 117 insertions(+), 45 deletions(-) diff --git a/guider/guider.py b/guider/guider.py index c0218d69..473cc5e2 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "241014" +__revision__ = "241015" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -20230,14 +20230,18 @@ def printCpuUsage(self): if self.periodicContEventCnt > 0: self.periodicEventInterval /= self.periodicContEventCnt + # define sample list for flame graph # + callList = {} + drawflame = "DRAWFLAME" in SysMgr.environList + # Print CPU usage in user space # if SysMgr.userEnable: SysMgr.clearPrint() title = "Function CPU-Tick Info" - SysMgr.printPipe( - "[%s] [Cnt: %s] [Interval: %dms] (USER)" - % (title, tCnt, self.periodicEventInterval * 1000) + titleStr = "[%s] [Cnt: %s] [Interval: %dms] (USER)" % ( + title, tCnt, self.periodicEventInterval * 1000 ) + SysMgr.printPipe(titleStr) # Print call stack # SysMgr.printPipe( @@ -20294,6 +20298,11 @@ def printCpuUsage(self): ilen = len("\t" * 16) symbolStack = self.makeUserSymList(subStack, ilen) + # add a sample for flame graph # + if drawflame: + fstack = " <- ".join([ r.strip() for r in symbolStack.split("<-") if r.strip()]) + callList[fstack] = cpuCnt + SysMgr.printPipe( "\t +{0:7.1f}% |{1:32}".format(cpuPer, symbolStack) ) @@ -20303,14 +20312,18 @@ def printCpuUsage(self): if self.periodicEventCnt == 0: SysMgr.printPipe(" None\n%s" % oneLine) + # draw flame graph # + if drawflame and callList: + Debugger.drawFlameFile(callList, titleStr, ".cpu.user") + SysMgr.printPipe("\n") # Print per-symbol # title = "Function CPU-Tick Symbol Info" - SysMgr.printPipe( - "[%s] [Cnt: %s] [Interval: %dms] (USER)\n%s" - % (title, tCnt, self.periodicEventInterval * 1000, twoLine) + titleStr = "[%s] [Cnt: %s] [Interval: %dms] (USER)" % ( + title, tCnt, self.periodicEventInterval * 1000 ) + SysMgr.printPipe(titleStr + "\n%s" % twoLine) SysMgr.printPipe( "{0:_^9}|{1:_^47}|{2:_^96}\n{3:1}".format( @@ -20323,12 +20336,11 @@ def printCpuUsage(self): key=lambda e: e[1]["totalTickCnt"], reverse=True, ): - if value["totalTickCnt"] == 0: + totalTick = value["totalTickCnt"] + if totalTick == 0: break - cpuPer = ( - value["totalTickCnt"] / float(self.periodicEventCnt) - ) * 100 + cpuPer = (totalTick / float(self.periodicEventCnt)) * 100 if cpuPer < 1 and not SysMgr.showAll: break @@ -20506,23 +20518,8 @@ def printCpuUsage(self): SysMgr.printPipe(" None\n%s" % oneLine) # draw flame graph # - if drawflame: - # make out path # - if SysMgr.outPath: - if os.path.isdir(SysMgr.outPath): - outFile = os.path.join( - SysMgr.outPath, "guider.cpu.kernel" - ) - else: - outFile = SysMgr.outPath + ".cpu.kernel" - else: - outFile = "guider.cpu.kernel" - - Debugger.drawFlame( - callList=callList, - title=titleStr, - outFile=outFile, - ) + if drawflame and callList: + Debugger.drawFlameFile(callList, titleStr, ".cpu.kernel") SysMgr.printPipe("\n\n") @@ -21662,13 +21659,17 @@ def printBlockWrUsage(self): convNum = UtilMgr.convNum size = convSize(self.blockWrUsageCnt << 9) + # define sample list for flame graph # + callList = {} + drawflame = "DRAWFLAME" in SysMgr.environList + # Print block write in user space # if SysMgr.userEnable: SysMgr.clearPrint() - SysMgr.printPipe( - "[%s] [Size: %s] [Cnt: %s] (USER)\n%s" - % (title, size, convNum(self.blockWrEventCnt), twoLine) + titleStr = "[%s] [Size: %s] [Cnt: %s] (USER)" % ( + title, size, convNum(self.blockWrEventCnt) ) + SysMgr.printPipe(titleStr + "\n%s" % twoLine) SysMgr.printPipe( "{0:_^9}|{1:_^47}|{2:_^49}|{3:_^46}\n{4:1}".format( @@ -21686,9 +21687,10 @@ def printBlockWrUsage(self): binary = self.posData[value["pos"]]["origBin"] source = self.posData[value["pos"]]["src"] + blkWrKB = value["blockWrCnt"] << 9 SysMgr.printPipe( "{0:>8} |{1:^47}| {2:48}| {3:37}".format( - convSize(value["blockWrCnt"] << 9), idx, binary, source + convSize(blkWrKB), idx, binary, source ) ) @@ -21709,6 +21711,11 @@ def printBlockWrUsage(self): ilen = len("\t" * 16) symbolStack = self.makeUserSymList(subStack, ilen) + # add a sample for flame graph # + if drawflame: + fstack = " <- ".join([ r.strip() for r in symbolStack.split("<-") if r.strip()]) + callList[fstack] = blkWrKB + SysMgr.printPipe( "\t+ {0:>8} |{1:32}".format( convSize(blockWrCnt << 9), symbolStack @@ -21720,14 +21727,22 @@ def printBlockWrUsage(self): if self.blockWrUsageCnt == 0: SysMgr.printPipe(" None\n%s" % oneLine) + # draw flame graph # + if drawflame and callList: + Debugger.drawFlameFile(callList, titleStr, ".blkwr.user") + SysMgr.printPipe("\n") + # define sample list for flame graph # + callList = {} + drawflame = "DRAWFLAME" in SysMgr.environList + # Print block write in kernel space # SysMgr.clearPrint() - SysMgr.printPipe( - "[%s] [Size: %s] [Cnt: %s] (KERNEL)\n%s" - % (title, size, convNum(self.blockWrEventCnt), twoLine) + titleStr = "[%s] [Size: %s] [Cnt: %s] (KERNEL)" % ( + title, size, convNum(self.blockWrEventCnt) ) + SysMgr.printPipe(titleStr + "\n%s" % twoLine) SysMgr.printPipe( "{0:_^9}|{1:_^144}\n{2:1}".format("Usage", "Function", twoLine) @@ -21742,9 +21757,10 @@ def printBlockWrUsage(self): if value["blockWrCnt"] == 0: break + blkWrKB = value["blockWrCnt"] << 9 SysMgr.printPipe( "{0:>8} |{1:^134}".format( - convSize(value["blockWrCnt"] << 9), idx + convSize(blkWrKB), idx ) ) @@ -21767,6 +21783,11 @@ def printBlockWrUsage(self): ilen = len("\t" * 16) symbolStack = self.makeKernelSymList(subStack, ilen) + # add a sample for flame graph # + if drawflame: + fstack = " <- ".join([ r.strip() for r in symbolStack.split("<-") if r.strip()]) + callList[fstack] = blkWrKB + SysMgr.printPipe( "\t+ {0:>8} |{1:32}".format( convSize(blockWrCnt << 9), symbolStack @@ -21778,6 +21799,10 @@ def printBlockWrUsage(self): if self.blockWrUsageCnt == 0: SysMgr.printPipe(" None\n%s" % oneLine) + # draw flame graph # + if drawflame and callList: + Debugger.drawFlameFile(callList, titleStr, ".blkwr.kernel") + SysMgr.printPipe("\n\n") def getExceptionList(self): @@ -21824,13 +21849,17 @@ def printBlockRdUsage(self): convNum = UtilMgr.convNum size = convSize(self.blockRdUsageCnt << 9) + # define sample list for flame graph # + callList = {} + drawflame = "DRAWFLAME" in SysMgr.environList + # Print block read in user space # if SysMgr.userEnable: SysMgr.clearPrint() - SysMgr.printPipe( - "[%s] [Size: %s] [Cnt: %s] (USER)\n%s" - % (title, size, convNum(self.blockRdEventCnt), twoLine) + titleStr = "[%s] [Size: %s] [Cnt: %s] (USER)" % ( + title, size, convNum(self.blockRdEventCnt) ) + SysMgr.printPipe(titleStr + "\n%s" % twoLine) SysMgr.printPipe( "{0:_^9}|{1:_^47}|{2:_^49}|{3:_^46}\n{4:1}".format( @@ -21848,9 +21877,10 @@ def printBlockRdUsage(self): binary = self.posData[value["pos"]]["origBin"] source = self.posData[value["pos"]]["src"] + blkRdKB = value["blockRdCnt"] << 9 SysMgr.printPipe( "{0:>8} |{1:^47}| {2:48}| {3:37}".format( - convSize(value["blockRdCnt"] << 9), idx, binary, source + convSize(blkRdKB), idx, binary, source ) ) @@ -21871,6 +21901,11 @@ def printBlockRdUsage(self): ilen = len("\t" * 16) symbolStack = self.makeUserSymList(subStack, ilen) + # add a sample for flame graph # + if drawflame: + fstack = " <- ".join([ r.strip() for r in symbolStack.split("<-") if r.strip()]) + callList[fstack] = blkRdKB + SysMgr.printPipe( "\t+ {0:8} |{1:32}".format( convSize(blockRdCnt << 9), symbolStack @@ -21879,14 +21914,22 @@ def printBlockRdUsage(self): SysMgr.printPipe(oneLine) + # draw flame graph # + if drawflame and callList: + Debugger.drawFlameFile(callList, titleStr, ".blkrd.user") + SysMgr.printPipe("\n") + # define sample list for flame graph # + callList = {} + drawflame = "DRAWFLAME" in SysMgr.environList + # Print block read in kernel space # SysMgr.clearPrint() - SysMgr.printPipe( - "[%s] [Size: %s] [Cnt: %s] (KERNEL)\n%s" - % (title, size, convNum(self.blockRdEventCnt), twoLine) + titleStr = "[%s] [Size: %s] [Cnt: %s] (KERNEL)" % ( + title, size, convNum(self.blockRdEventCnt) ) + SysMgr.printPipe(titleStr + "\n%s" % twoLine) SysMgr.printPipe( "{0:_^9}|{1:_^144}\n{2:1}".format("Usage", "Function", twoLine) @@ -21901,9 +21944,10 @@ def printBlockRdUsage(self): if value["blockRdCnt"] == 0: break + blkRdKB = value["blockRdCnt"] << 9 SysMgr.printPipe( "{0:>8} |{1:^144}".format( - convSize(value["blockRdCnt"] << 9), idx + convSize(blkRdKB), idx ) ) @@ -21926,6 +21970,11 @@ def printBlockRdUsage(self): ilen = len("\t" * 16) symbolStack = self.makeKernelSymList(subStack, ilen) + # add a sample for flame graph # + if drawflame: + fstack = " <- ".join([ r.strip() for r in symbolStack.split("<-") if r.strip()]) + callList[fstack] = blkRdKB + SysMgr.printPipe( "\t+ {0:>8} |{1:32}".format( convSize(blockRdCnt << 9), symbolStack @@ -21934,6 +21983,10 @@ def printBlockRdUsage(self): SysMgr.printPipe(oneLine) + # draw flame graph # + if drawflame and callList: + Debugger.drawFlameFile(callList, titleStr, ".blkrd.kernel") + SysMgr.printPipe("\n\n") @@ -78779,7 +78832,7 @@ def _startFuncGraph(self): if long(SysMgr.bufferSize) != setBufferSize: SysMgr.printWarn( "failed to set buffer size to %s KB, now is %s KB" - % (SysMgr.bufferSize, setBufferSize), + % (UtilMgr.convNum(SysMgr.bufferSize), UtilMgr.convNum(setBufferSize)), True, ) @@ -97079,6 +97132,25 @@ def _iterNode( _iterNode(tagList, callTree, callCnt) return "\n".join(tagList) + @staticmethod + def drawFlameFile(callList, titleStr, suffix): + # make out path # + if SysMgr.outPath: + if os.path.isdir(SysMgr.outPath): + outFile = os.path.join( + SysMgr.outPath, "guider" + suffix + ) + else: + outFile = SysMgr.outPath + suffix + else: + outFile = "guider" + suffix + + Debugger.drawFlame( + callList=callList, + title=titleStr, + outFile=outFile, + ) + @staticmethod def drawFlame( inputFile=None,