Skip to content

Commit

Permalink
tptop: Add interval stats
Browse files Browse the repository at this point in the history
Signed-off-by: iipeace <[email protected]>
  • Loading branch information
iipeace committed Sep 24, 2024
1 parent 8aaf2fb commit 3543749
Showing 1 changed file with 105 additions and 23 deletions.
128 changes: 105 additions & 23 deletions guider/guider.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
__credits__ = "Peace Lee"
__license__ = "GPLv2"
__version__ = "3.9.8"
__revision__ = "240923"
__revision__ = "240924"
__maintainer__ = "Peace Lee"
__email__ = "[email protected]"
__repository__ = "https://github.com/iipeace/guider"
Expand Down Expand Up @@ -25122,20 +25122,55 @@ def _updateBinderStat(binderStat, ctask, code):
def parseTraceData(data):
LogMgr.traceStat["cnt"] = LogMgr.traceStat.get("cnt", 0) + 1

# save count #
func = data.get("func")
if not func in LogMgr.traceStat:
LogMgr.traceStat[func] = {"cnt": 0}
LogMgr.traceStat[func]["cnt"] += 1
funcStat = LogMgr.traceStat[func]
funcStat["cnt"] += 1

# save stat #
if "PRINTSTAT" in SysMgr.environList:
ltime = float(data.get("time", 0))
last = funcStat.get("last", 0)
if last:
diff = ltime - last
if diff > 0:
funcStat["min"] = min(funcStat["min"], diff)
funcStat["max"] = max(funcStat["max"], diff)
funcStat["total"] += diff
else:
funcStat["min"] = SysMgr.maxSize
funcStat["total"] = funcStat["max"] = 0
funcStat["last"] = ltime
else:
ltime = 0

if "ONLYEVENT" in SysMgr.environList:
return

# save task count #
tid = data.get("tgid" if SysMgr.processEnable else "thread")
if tid[0] == "-":
tid = data.get("thread")
if not tid in LogMgr.traceStat[func]:
LogMgr.traceStat[func][tid] = {"cnt": 0, "comm": data.get("comm")}
LogMgr.traceStat[func][tid]["cnt"] += 1
if not tid in funcStat:
funcStat[tid] = {"cnt": 0, "comm": data.get("comm")}
taskStat = funcStat[tid]
taskStat["cnt"] += 1

# save task stat #
if "PRINTSTAT" in SysMgr.environList:
last = taskStat.get("last", 0)
if last:
diff = ltime - last
if diff > 0:
taskStat["min"] = min(taskStat["min"], diff)
taskStat["max"] = max(taskStat["max"], diff)
taskStat["total"] += diff
else:
taskStat["min"] = SysMgr.maxSize
taskStat["total"] = taskStat["max"] = 0
taskStat["last"] = ltime

@staticmethod
def atraceHandler(signum, frame):
Expand Down Expand Up @@ -25706,15 +25741,34 @@ def traceHandler(signum, frame):
)

SysMgr.addPrint(
"{2:1}\n{0:^65} | {1:^32} |\n{2:1}\n".format(
"EVENT", "TASK", twoLine
),
(
"{6:1}\n{0:^65} | {1:^32} | {2:^9} | {3:^9} | "
"{4:^9} | {5:^13} |\n{6:1}\n"
).format("EVENT", "TASK", "AVG", "MIN", "MAX", "TOTAL", twoLine),
newline=2,
force=force,
)

taskFilter = SysMgr.environList.get("TASKFILTER", [])

def _getStats(statList, totalCnt, indent=True):
statStr = ""
total = statList.get("total", 0)
if total > 0:
statStr += (
"{0:>{idlen}} {1:>9.6f} {2:>9.6f} "
"{3:>9.6f} {4:>13.6f}"
).format(
" ",
total / float(totalCnt) if totalCnt else 0,
statList.get("min"),
statList.get("max"),
total,
idlen=36 if indent else 1,
)
statStr += "\n"
return statStr

# traverse trace table #
logCnt = 0
totalCnt = float(LogMgr.traceStat.get("cnt", 0))
Expand All @@ -25731,18 +25785,19 @@ def traceHandler(signum, frame):

eventCnt = tasks.get("cnt")
eventPer = (eventCnt / totalCnt) * 100
eventStr = "{0:>49} {1:>8}({2:5.1f}%)\n".format(
eventStr = "{0:>49} {1:>8}({2:5.1f}%)".format(
event, convNum(eventCnt), eventPer
)
eventStr += _getStats(tasks, eventCnt, True)
SysMgr.addPrint(eventStr, force=force)
logCnt += 1

for task, items in sorted(
tasks.items(),
key=lambda x: x[1]["cnt"] if x[0] != "cnt" else 0,
key=lambda x: x[1]["cnt"] if x[0][0].isdigit() else 0,
reverse=True,
):
if task == "cnt":
if not task.isdigit():
continue

# check exit condition #
Expand All @@ -25769,9 +25824,10 @@ def traceHandler(signum, frame):
taskInfo = "%s(%s)" % (comm, task)
taskCnt = items["cnt"]
taskPer = (taskCnt / float(eventCnt)) * 100
taskStr = "{0:34}{1:>50} {2:>8}({3:5.1f}%)\n".format(
taskStr = "{0:34}{1:>50} {2:>8}({3:5.1f}%)".format(
" ", taskInfo, convNum(taskCnt), taskPer
)
taskStr += _getStats(items, taskCnt, False)
SysMgr.addPrint(taskStr, force=force)

if logCnt == 0:
Expand Down Expand Up @@ -38644,6 +38700,9 @@ def printHelp(force=False, isExit=True):
- {2:1} except for load plots including CPU and I/O usage
# {0:1} {1:1} {4:1} -q NOLOADPLOT

- {2:1} including core usage
# {0:1} {1:1} {4:1} -q COREPLOT

- {2:1} except for PSI plots
# {0:1} {1:1} {4:1} -q NOPSIPLOT

Expand Down Expand Up @@ -40760,13 +40819,21 @@ def _getDesc(s, t=0):
Examples:
- {2:1}
# {0:1} {1:1} {3:1}
# {0:1} {1:1} syscalls

- {2:1} only having specific words
# {0:1} {1:1} {3:1} -g test, kworker

- {2:1} only for specific tasks
# {0:1} {1:1} {3:1} -q TASKFILTER:"test*"

- {2:1} with interval stats
# {0:1} {1:1} {3:1} -q PRINTSTAT

- {2:1} after applying filters
# {0:1} {1:1} {3:1} -q TPFILTER:"sched:common_pid==895"
# {0:1} {1:1} {3:1} -q TPFILTER:"sched/sched_switch:prev_comm==\\"yes\\""

- {2:1} with control for specific trace points
# {0:1} {1:1} {3:1} "irq/softirq*, sched"
# {0:1} {1:1} {3:1} "sched/sched_blocked_reason"
Expand Down Expand Up @@ -43593,6 +43660,7 @@ def _getDesc(s, t=0):

- {2:1} after applying filters
# {0:1} {1:1} "*" -q TPFILTER:"sched:common_pid==895"
# {0:1} {1:1} "*" -q TPFILTER:"sched/sched_switch:prev_comm==\\"yes\\""

- Print tracepoint list
# {0:1} {1:1} -l
Expand Down Expand Up @@ -120310,8 +120378,9 @@ def getStatsFile(
# Core #
elif context == "Core":
if slen == 3:
gname = sline[0].strip()
intervalList = sline[2]
if not sline[0].startswith("Core"):
gname = sline[0].strip()
intervalList = sline[2]
elif slen == 2:
if intervalList:
intervalList += sline[1]
Expand Down Expand Up @@ -123885,6 +123954,18 @@ def _drawCpu(graphStats, xtype, pos, size, delay=False):
(cpuUsage, "red", "CPU(%s)" % conv(maxCore), bold, ""),
]

# add core stat #
if "COREPLOT" in SysMgr.environList:
coreUsage = graphStats["%scoreUsage" % fname]
for corenum, ulist in sorted(
coreUsage.items(), key=lambda x: long(x[0])
):
ulist = list(map(long, ulist.split()))
cname = "Core/%s" % corenum
coreStatList.append(
(ulist, None, cname, bold, cname + " | ")
)

# process PSI stats #
psiStats = (
{}
Expand Down Expand Up @@ -132324,10 +132405,11 @@ def parseProcLine(index, procLine):

# split stats #
tokens = procLine.split("|")
lenToken = len(tokens)

# total #
if "total" not in procIntData and tokens[0].startswith("Total"):
if len(tokens) < 2:
if lenToken < 2:
return

# parse CPU & BLOCK stat #
Expand Down Expand Up @@ -132468,7 +132550,7 @@ def parseProcLine(index, procLine):
return

# PSI #
elif len(tokens) == 1 and tokens[0].startswith(" "):
elif lenToken == 1 and tokens[0].startswith(" "):
# parse PSI stat #
m = re.match(
(
Expand All @@ -132489,7 +132571,7 @@ def parseProcLine(index, procLine):
TA.procTempData["psi"] = psiStats

# GPU #
elif len(tokens) == 5:
elif lenToken == 5:
m = re.match(
r"\s*(?P<gpu>.+)\s*\(\s*(?P<usage>[0-9]+)\s*%\)", tokens[0]
)
Expand Down Expand Up @@ -132525,7 +132607,7 @@ def parseProcLine(index, procLine):
return

# storage #
elif len(tokens) == 12 and tokens[0][0] == "/":
elif lenToken == 12 and tokens[0][0] == "/":
procIntData["total"].setdefault("storage", {})
TA.procTotData["total"].setdefault("storage", {})

Expand Down Expand Up @@ -132593,7 +132675,7 @@ def parseProcLine(index, procLine):
return

# network #
elif len(tokens) == 13 and not tokens[0].startswith("Total"):
elif lenToken == 13 and not tokens[0].startswith("Total"):
# check condition #
if tokens[0].strip() in ("ID", "Dev"):
return
Expand Down Expand Up @@ -132631,9 +132713,9 @@ def parseProcLine(index, procLine):
return

# cgroup #
elif len(tokens) == 10 and "/" in tokens[8]:
elif lenToken == 10 and "/" in tokens[8]:
tokens = UtilMgr.cleanItem(tokens, False)
if len(tokens) != 9:
if lenToken != 9:
return

try:
Expand Down Expand Up @@ -132714,7 +132796,7 @@ def parseProcLine(index, procLine):
return

# core #
elif len(tokens) == 6 and tokens[0].startswith("Core/"):
elif lenToken in (6, 7) and tokens[0].startswith("Core/"):
m = re.findall(
r"Core/\s*(?P<core>\d+)\|\s*(?P<usage>\d+)\s*%", procLine
)
Expand All @@ -132736,7 +132818,7 @@ def parseProcLine(index, procLine):
procIntData["total"]["core"][core] = usage

# WARN: each tab's the number of tokens #
# task(10), GPU(5), storage(12), network(13), cgroup(10), core(6)
# task(10), GPU(5), storage(12), network(13), cgroup(10), core(6/7)

# check return condition #
if "ONLYTOTAL" in SysMgr.environList:
Expand Down

0 comments on commit 3543749

Please sign in to comment.