summaryrefslogtreecommitdiffstats
path: root/scripts/pybootchartgui/pybootchartgui/samples.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/pybootchartgui/pybootchartgui/samples.py')
-rw-r--r--scripts/pybootchartgui/pybootchartgui/samples.py226
1 files changed, 142 insertions, 84 deletions
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 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16
1class DiskStatSample: 17class DiskStatSample:
2 def __init__(self, time): 18 def __init__(self, time):
3 self.time = time 19 self.time = time
4 self.diskdata = [0, 0, 0] 20 self.diskdata = [0, 0, 0]
5 def add_diskdata(self, new_diskdata): 21 def add_diskdata(self, new_diskdata):
6 self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ] 22 self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ]
7 23
8class CPUSample: 24class CPUSample:
9 def __init__(self, time, user, sys, io): 25 def __init__(self, time, user, sys, io = 0.0, swap = 0.0):
10 self.time = time 26 self.time = time
11 self.user = user 27 self.user = user
12 self.sys = sys 28 self.sys = sys
13 self.io = io 29 self.io = io
14 30 self.swap = swap
15 def __str__(self): 31
16 return str(self.time) + "\t" + str(self.user) + "\t" + str(self.sys) + "\t" + str(self.io); 32 @property
17 33 def cpu(self):
34 return self.user + self.sys
35
36 def __str__(self):
37 return str(self.time) + "\t" + str(self.user) + "\t" + \
38 str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap)
39
40class MemSample:
41 used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',)
42
43 def __init__(self, time):
44 self.time = time
45 self.records = {}
46
47 def add_value(self, name, value):
48 if name in MemSample.used_values:
49 self.records[name] = value
50
51 def valid(self):
52 keys = self.records.keys()
53 # discard incomplete samples
54 return [v for v in MemSample.used_values if v not in keys] == []
55
18class ProcessSample: 56class ProcessSample:
19 def __init__(self, time, state, cpu_sample): 57 def __init__(self, time, state, cpu_sample):
20 self.time = time 58 self.time = time
21 self.state = state 59 self.state = state
22 self.cpu_sample = cpu_sample 60 self.cpu_sample = cpu_sample
23 61
24 def __str__(self): 62 def __str__(self):
25 return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample); 63 return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample)
26 64
27class ProcessStats: 65class ProcessStats:
28 def __init__(self, process_list, sample_period, start_time, end_time): 66 def __init__(self, writer, process_map, sample_count, sample_period, start_time, end_time):
29 self.process_list = process_list 67 self.process_map = process_map
30 self.sample_period = sample_period 68 self.sample_count = sample_count
31 self.start_time = start_time 69 self.sample_period = sample_period
32 self.end_time = end_time 70 self.start_time = start_time
33 71 self.end_time = end_time
34class Process: 72 writer.info ("%d samples, avg. sample length %f" % (self.sample_count, self.sample_period))
35 def __init__(self, pid, cmd, ppid, start_time): 73 writer.info ("process list size: %d" % len (self.process_map.values()))
36 self.pid = pid
37 self.cmd = cmd.strip('(').strip(')')
38 self.ppid = ppid
39 self.start_time = start_time
40 self.samples = []
41 self.parent = None
42 self.child_list = []
43
44 self.duration = 0
45 self.active = None
46
47 self.last_user_cpu_time = None
48 self.last_sys_cpu_time = None
49
50 def __str__(self):
51 return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ])
52
53 def calc_stats(self, samplePeriod):
54 if self.samples:
55 firstSample = self.samples[0]
56 lastSample = self.samples[-1]
57 self.start_time = min(firstSample.time, self.start_time)
58 self.duration = lastSample.time - self.start_time + samplePeriod
59
60 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] )
61 activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] )
62 self.active = (activeCount>2)
63
64 def calc_load(self, userCpu, sysCpu, interval):
65
66 userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval
67 sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval
68 cpuLoad = userCpuLoad + sysCpuLoad
69 # normalize
70 if cpuLoad > 1.0:
71 userCpuLoad = userCpuLoad / cpuLoad;
72 sysCpuLoad = sysCpuLoad / cpuLoad;
73 return (userCpuLoad, sysCpuLoad)
74
75 def set_parent(self, processMap):
76 if self.ppid != None:
77 self.parent = processMap.get(self.ppid)
78 if self.parent == None and self.pid > 1:
79 print "warning: no parent for pid '%i' with ppid '%i'" % (self.pid,self.ppid)
80 def get_end_time(self):
81 return self.start_time + self.duration
82 74
83class DiskSample: 75class Process:
84 def __init__(self, time, read, write, util): 76 def __init__(self, writer, pid, cmd, ppid, start_time):
85 self.time = time 77 self.writer = writer
86 self.read = read 78 self.pid = pid
87 self.write = write 79 self.cmd = cmd
88 self.util = util 80 self.exe = cmd
89 self.tput = read + write 81 self.args = []
82 self.ppid = ppid
83 self.start_time = start_time
84 self.duration = 0
85 self.samples = []
86 self.parent = None
87 self.child_list = []
88
89 self.active = None
90 self.last_user_cpu_time = None
91 self.last_sys_cpu_time = None
92
93 self.last_cpu_ns = 0
94 self.last_blkio_delay_ns = 0
95 self.last_swapin_delay_ns = 0
96
97 # split this process' run - triggered by a name change
98 def split(self, writer, pid, cmd, ppid, start_time):
99 split = Process (writer, pid, cmd, ppid, start_time)
100
101 split.last_cpu_ns = self.last_cpu_ns
102 split.last_blkio_delay_ns = self.last_blkio_delay_ns
103 split.last_swapin_delay_ns = self.last_swapin_delay_ns
104
105 return split
106
107 def __str__(self):
108 return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ])
90 109
91 def __str__(self): 110 def calc_stats(self, samplePeriod):
92 return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)]) 111 if self.samples:
112 firstSample = self.samples[0]
113 lastSample = self.samples[-1]
114 self.start_time = min(firstSample.time, self.start_time)
115 self.duration = lastSample.time - self.start_time + samplePeriod
116
117 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] )
118 activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] )
119 self.active = (activeCount>2)
120
121 def calc_load(self, userCpu, sysCpu, interval):
122 userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval
123 sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval
124 cpuLoad = userCpuLoad + sysCpuLoad
125 # normalize
126 if cpuLoad > 1.0:
127 userCpuLoad = userCpuLoad / cpuLoad
128 sysCpuLoad = sysCpuLoad / cpuLoad
129 return (userCpuLoad, sysCpuLoad)
130
131 def set_parent(self, processMap):
132 if self.ppid != None:
133 self.parent = processMap.get (self.ppid)
134 if self.parent == None and self.pid // 1000 > 1 and \
135 not (self.ppid == 2000 or self.pid == 2000): # kernel threads: ppid=2
136 self.writer.warn("Missing CONFIG_PROC_EVENTS: no parent for pid '%i' ('%s') with ppid '%i'" \
137 % (self.pid,self.cmd,self.ppid))
138
139 def get_end_time(self):
140 return self.start_time + self.duration
141
142class DiskSample:
143 def __init__(self, time, read, write, util):
144 self.time = time
145 self.read = read
146 self.write = write
147 self.util = util
148 self.tput = read + write
93 149
150 def __str__(self):
151 return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)])