From d0e513d4371789d59bcb902497ca7c537a94c1f0 Mon Sep 17 00:00:00 2001 From: Peter Kjellerstedt Date: Fri, 15 Nov 2013 18:08:50 +0100 Subject: pybootchartgui: Import pybootchartgui 0.14.5 This update the pybootchartgui code to the latest release from its new location at "https://github.com/mmeeks/bootchart". This only imports the relevant parts, and not all of bootchart2. (From OE-Core rev: 6f1568e54a7808b2ab568618fc5bb244249579f1) Signed-off-by: Peter Kjellerstedt Signed-off-by: Richard Purdie --- scripts/pybootchartgui/pybootchartgui/samples.py | 226 ++++++++++++++--------- 1 file changed, 142 insertions(+), 84 deletions(-) (limited to 'scripts/pybootchartgui/pybootchartgui/samples.py') diff --git a/scripts/pybootchartgui/pybootchartgui/samples.py b/scripts/pybootchartgui/pybootchartgui/samples.py index c94b30d032..015d743aa0 100644 --- a/scripts/pybootchartgui/pybootchartgui/samples.py +++ b/scripts/pybootchartgui/pybootchartgui/samples.py @@ -1,93 +1,151 @@ +# This file is part of pybootchartgui. + +# pybootchartgui is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# pybootchartgui is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with pybootchartgui. If not, see . + + class DiskStatSample: - def __init__(self, time): - self.time = time - self.diskdata = [0, 0, 0] - def add_diskdata(self, new_diskdata): - self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ] + def __init__(self, time): + self.time = time + self.diskdata = [0, 0, 0] + def add_diskdata(self, new_diskdata): + self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ] class CPUSample: - def __init__(self, time, user, sys, io): - self.time = time - self.user = user - self.sys = sys - self.io = io - - def __str__(self): - return str(self.time) + "\t" + str(self.user) + "\t" + str(self.sys) + "\t" + str(self.io); - + def __init__(self, time, user, sys, io = 0.0, swap = 0.0): + self.time = time + self.user = user + self.sys = sys + self.io = io + self.swap = swap + + @property + def cpu(self): + return self.user + self.sys + + def __str__(self): + return str(self.time) + "\t" + str(self.user) + "\t" + \ + str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap) + +class MemSample: + used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',) + + def __init__(self, time): + self.time = time + self.records = {} + + def add_value(self, name, value): + if name in MemSample.used_values: + self.records[name] = value + + def valid(self): + keys = self.records.keys() + # discard incomplete samples + return [v for v in MemSample.used_values if v not in keys] == [] + class ProcessSample: - def __init__(self, time, state, cpu_sample): - self.time = time - self.state = state - self.cpu_sample = cpu_sample - - def __str__(self): - return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample); + def __init__(self, time, state, cpu_sample): + self.time = time + self.state = state + self.cpu_sample = cpu_sample + + def __str__(self): + return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample) class ProcessStats: - def __init__(self, process_list, sample_period, start_time, end_time): - self.process_list = process_list - self.sample_period = sample_period - self.start_time = start_time - self.end_time = end_time - -class Process: - def __init__(self, pid, cmd, ppid, start_time): - self.pid = pid - self.cmd = cmd.strip('(').strip(')') - self.ppid = ppid - self.start_time = start_time - self.samples = [] - self.parent = None - self.child_list = [] - - self.duration = 0 - self.active = None - - self.last_user_cpu_time = None - self.last_sys_cpu_time = None - - def __str__(self): - return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ]) - - def calc_stats(self, samplePeriod): - if self.samples: - firstSample = self.samples[0] - lastSample = self.samples[-1] - self.start_time = min(firstSample.time, self.start_time) - self.duration = lastSample.time - self.start_time + samplePeriod - - activeCount = sum( [1 for sample in self.samples if sample.cpu_sample and sample.cpu_sample.sys + sample.cpu_sample.user + sample.cpu_sample.io > 0.0] ) - activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] ) - self.active = (activeCount>2) - - def calc_load(self, userCpu, sysCpu, interval): - - userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval - sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval - cpuLoad = userCpuLoad + sysCpuLoad - # normalize - if cpuLoad > 1.0: - userCpuLoad = userCpuLoad / cpuLoad; - sysCpuLoad = sysCpuLoad / cpuLoad; - return (userCpuLoad, sysCpuLoad) - - def set_parent(self, processMap): - if self.ppid != None: - self.parent = processMap.get(self.ppid) - if self.parent == None and self.pid > 1: - print "warning: no parent for pid '%i' with ppid '%i'" % (self.pid,self.ppid) - def get_end_time(self): - return self.start_time + self.duration + def __init__(self, writer, process_map, sample_count, sample_period, start_time, end_time): + self.process_map = process_map + self.sample_count = sample_count + self.sample_period = sample_period + self.start_time = start_time + self.end_time = end_time + writer.info ("%d samples, avg. sample length %f" % (self.sample_count, self.sample_period)) + writer.info ("process list size: %d" % len (self.process_map.values())) -class DiskSample: - def __init__(self, time, read, write, util): - self.time = time - self.read = read - self.write = write - self.util = util - self.tput = read + write +class Process: + def __init__(self, writer, pid, cmd, ppid, start_time): + self.writer = writer + self.pid = pid + self.cmd = cmd + self.exe = cmd + self.args = [] + self.ppid = ppid + self.start_time = start_time + self.duration = 0 + self.samples = [] + self.parent = None + self.child_list = [] + + self.active = None + self.last_user_cpu_time = None + self.last_sys_cpu_time = None + + self.last_cpu_ns = 0 + self.last_blkio_delay_ns = 0 + self.last_swapin_delay_ns = 0 + + # split this process' run - triggered by a name change + def split(self, writer, pid, cmd, ppid, start_time): + split = Process (writer, pid, cmd, ppid, start_time) + + split.last_cpu_ns = self.last_cpu_ns + split.last_blkio_delay_ns = self.last_blkio_delay_ns + split.last_swapin_delay_ns = self.last_swapin_delay_ns + + return split + + def __str__(self): + return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ]) - def __str__(self): - return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)]) + def calc_stats(self, samplePeriod): + if self.samples: + firstSample = self.samples[0] + lastSample = self.samples[-1] + self.start_time = min(firstSample.time, self.start_time) + self.duration = lastSample.time - self.start_time + samplePeriod + + activeCount = sum( [1 for sample in self.samples if sample.cpu_sample and sample.cpu_sample.sys + sample.cpu_sample.user + sample.cpu_sample.io > 0.0] ) + activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] ) + self.active = (activeCount>2) + + def calc_load(self, userCpu, sysCpu, interval): + userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval + sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval + cpuLoad = userCpuLoad + sysCpuLoad + # normalize + if cpuLoad > 1.0: + userCpuLoad = userCpuLoad / cpuLoad + sysCpuLoad = sysCpuLoad / cpuLoad + return (userCpuLoad, sysCpuLoad) + + def set_parent(self, processMap): + if self.ppid != None: + self.parent = processMap.get (self.ppid) + if self.parent == None and self.pid // 1000 > 1 and \ + not (self.ppid == 2000 or self.pid == 2000): # kernel threads: ppid=2 + self.writer.warn("Missing CONFIG_PROC_EVENTS: no parent for pid '%i' ('%s') with ppid '%i'" \ + % (self.pid,self.cmd,self.ppid)) + + def get_end_time(self): + return self.start_time + self.duration + +class DiskSample: + def __init__(self, time, read, write, util): + self.time = time + self.read = read + self.write = write + self.util = util + self.tput = read + write + def __str__(self): + return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)]) -- cgit v1.2.3-54-g00ecf