summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/lib/oe/buildstats.py43
1 files changed, 41 insertions, 2 deletions
diff --git a/meta/lib/oe/buildstats.py b/meta/lib/oe/buildstats.py
index 359ad2a460..2700245ec6 100644
--- a/meta/lib/oe/buildstats.py
+++ b/meta/lib/oe/buildstats.py
@@ -10,6 +10,7 @@
10import time 10import time
11import re 11import re
12import bb.event 12import bb.event
13from collections import deque
13 14
14class SystemStats: 15class SystemStats:
15 def __init__(self, d): 16 def __init__(self, d):
@@ -18,7 +19,8 @@ class SystemStats:
18 bb.utils.mkdirhier(bsdir) 19 bb.utils.mkdirhier(bsdir)
19 file_handlers = [('diskstats', self._reduce_diskstats), 20 file_handlers = [('diskstats', self._reduce_diskstats),
20 ('meminfo', self._reduce_meminfo), 21 ('meminfo', self._reduce_meminfo),
21 ('stat', self._reduce_stat)] 22 ('stat', self._reduce_stat),
23 ('net/dev', self._reduce_net)]
22 24
23 # Some hosts like openSUSE have readable /proc/pressure files 25 # Some hosts like openSUSE have readable /proc/pressure files
24 # but throw errors when these files are opened. Catch these error 26 # but throw errors when these files are opened. Catch these error
@@ -47,7 +49,10 @@ class SystemStats:
47 # not strictly necessary, but using it makes the class 49 # not strictly necessary, but using it makes the class
48 # more robust should two processes ever write 50 # more robust should two processes ever write
49 # concurrently. 51 # concurrently.
50 destfile = os.path.join(bsdir, '%sproc_%s.log' % ('reduced_' if handler else '', filename)) 52 if filename == 'net/dev':
53 destfile = os.path.join(bsdir, 'reduced_proc_net.log')
54 else:
55 destfile = os.path.join(bsdir, '%sproc_%s.log' % ('reduced_' if handler else '', filename))
51 self.proc_files.append((filename, open(destfile, 'ab'), handler)) 56 self.proc_files.append((filename, open(destfile, 'ab'), handler))
52 self.monitor_disk = open(os.path.join(bsdir, 'monitor_disk.log'), 'ab') 57 self.monitor_disk = open(os.path.join(bsdir, 'monitor_disk.log'), 'ab')
53 # Last time that we sampled /proc data resp. recorded disk monitoring data. 58 # Last time that we sampled /proc data resp. recorded disk monitoring data.
@@ -72,6 +77,7 @@ class SystemStats:
72 self.stat_ltimes = None 77 self.stat_ltimes = None
73 # Last time we sampled /proc/pressure. All resources stored in a single dict with the key as filename 78 # Last time we sampled /proc/pressure. All resources stored in a single dict with the key as filename
74 self.last_pressure = {"pressure/cpu": None, "pressure/io": None, "pressure/memory": None} 79 self.last_pressure = {"pressure/cpu": None, "pressure/io": None, "pressure/memory": None}
80 self.net_stats = {}
75 81
76 def close(self): 82 def close(self):
77 self.monitor_disk.close() 83 self.monitor_disk.close()
@@ -93,6 +99,39 @@ class SystemStats:
93 b' '.join([values[x] for x in 99 b' '.join([values[x] for x in
94 (b'MemTotal', b'MemFree', b'Buffers', b'Cached', b'SwapTotal', b'SwapFree')]) + b'\n') 100 (b'MemTotal', b'MemFree', b'Buffers', b'Cached', b'SwapTotal', b'SwapFree')]) + b'\n')
95 101
102 def _reduce_net(self, time, data, filename):
103 data = data.split(b'\n')
104 for line in data[2:]:
105 if b":" not in line:
106 continue
107 try:
108 parts = line.split()
109 iface = (parts[0].strip(b':')).decode('ascii')
110 receive_bytes = int(parts[1])
111 transmit_bytes = int(parts[9])
112 except Exception:
113 continue
114
115 if iface not in self.net_stats:
116 self.net_stats[iface] = deque(maxlen=2)
117 self.net_stats[iface].append((receive_bytes, transmit_bytes, 0, 0))
118 prev = self.net_stats[iface][-1] if self.net_stats[iface] else (0, 0, 0, 0)
119 receive_diff = receive_bytes - prev[0]
120 transmit_diff = transmit_bytes - prev[1]
121 self.net_stats[iface].append((
122 receive_bytes,
123 transmit_bytes,
124 receive_diff,
125 transmit_diff
126 ))
127
128 result_str = "\n".join(
129 f"{iface}: {net_data[-1][0]} {net_data[-1][1]} {net_data[-1][2]} {net_data[-1][3]}"
130 for iface, net_data in self.net_stats.items()
131 ) + "\n"
132
133 return time, result_str.encode('ascii')
134
96 def _diskstats_is_relevant_line(self, linetokens): 135 def _diskstats_is_relevant_line(self, linetokens):
97 if len(linetokens) < 14: 136 if len(linetokens) < 14:
98 return False 137 return False