diff options
Diffstat (limited to 'meta/lib/buildstats.py')
-rw-r--r-- | meta/lib/buildstats.py | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/meta/lib/buildstats.py b/meta/lib/buildstats.py new file mode 100644 index 0000000000..8ce4112c2d --- /dev/null +++ b/meta/lib/buildstats.py | |||
@@ -0,0 +1,47 @@ | |||
1 | # Implements system state sampling. Called by buildstats.bbclass. | ||
2 | # Because it is a real Python module, it can hold persistent state, | ||
3 | # like open log files and the time of the last sampling. | ||
4 | |||
5 | import time | ||
6 | |||
7 | class SystemStats: | ||
8 | def __init__(self, d): | ||
9 | bn = d.getVar('BUILDNAME', True) | ||
10 | bsdir = os.path.join(d.getVar('BUILDSTATS_BASE', True), bn) | ||
11 | bb.utils.mkdirhier(bsdir) | ||
12 | |||
13 | self.proc_files = [] | ||
14 | for filename in ('diskstats', 'meminfo', 'stat'): | ||
15 | # In practice, this class gets instantiated only once in | ||
16 | # the bitbake cooker process. Therefore 'append' mode is | ||
17 | # not strictly necessary, but using it makes the class | ||
18 | # more robust should two processes ever write | ||
19 | # concurrently. | ||
20 | self.proc_files.append((filename, | ||
21 | open(os.path.join(bsdir, 'proc_%s.log' % filename), 'ab'))) | ||
22 | # Last time that we sampled data. | ||
23 | self.last = 0 | ||
24 | # Minimum number of seconds between recording a sample. This | ||
25 | # becames relevant when we get called very often while many | ||
26 | # short tasks get started. Sampling during quiet periods | ||
27 | # depends on the heartbeat event, which fires less often. | ||
28 | self.min_seconds = 1 | ||
29 | |||
30 | def close(self): | ||
31 | self.monitor_disk.close() | ||
32 | for _, output, _ in self.proc_files: | ||
33 | output.close() | ||
34 | |||
35 | def sample(self, force): | ||
36 | now = time.time() | ||
37 | if (now - self.last > self.min_seconds) or force: | ||
38 | for filename, output in self.proc_files: | ||
39 | with open(os.path.join('/proc', filename), 'rb') as input: | ||
40 | data = input.read() | ||
41 | # Unbuffered raw write, less overhead and useful | ||
42 | # in case that we end up with concurrent writes. | ||
43 | os.write(output.fileno(), | ||
44 | ('%.0f\n' % now).encode('ascii') + | ||
45 | data + | ||
46 | b'\n') | ||
47 | self.last = now | ||