diff options
| -rw-r--r-- | meta/lib/oe/buildstats.py | 43 |
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 @@ | |||
| 10 | import time | 10 | import time |
| 11 | import re | 11 | import re |
| 12 | import bb.event | 12 | import bb.event |
| 13 | from collections import deque | ||
| 13 | 14 | ||
| 14 | class SystemStats: | 15 | class 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 |
