OILS / regtest / proc_log.py View on Github | oils.pub

130 lines, 84 significant
1#!/usr/bin/env python3
2"""
3stat_log.py - Save portions of /proc/{stat,vmstat,meminfo,diskstas}
4
5Runs in an infinite loop, until SIGTERM
6"""
7import optparse
8import os
9import signal
10import sys
11import time
12
13
14def log(msg, *args):
15 if args:
16 msg = msg % args
17 print(msg, file=sys.stderr)
18
19
20def Options():
21 """Returns an option parser instance."""
22
23 p = optparse.OptionParser()
24
25 p.add_option('--out-dir',
26 dest='out_dir',
27 default='_tmp',
28 help='Write files to this directory')
29
30 p.add_option('--sleep-secs',
31 dest='sleep_secs',
32 type='int',
33 default=1,
34 help='Seconds to sleep')
35
36 return p
37
38
39o_stat = None
40o_vm = None
41o_mem = None
42o_disk = None
43
44
45def FlushAll():
46 o_stat.flush()
47 o_vm.flush()
48 o_mem.flush()
49 o_disk.flush()
50
51
52def Handler(signum, frame):
53 log('[%s] Received SIGTERM, flushing logs and exiting ...', sys.argv[0])
54 FlushAll()
55 sys.exit(0)
56
57
58def main(argv):
59 o = Options()
60 opts, argv = o.parse_args(argv)
61
62 # Saving lines
63 stat_filename = os.path.join(opts.out_dir, 'stat.txt')
64 vmstat_filename = os.path.join(opts.out_dir, 'vmstat.txt')
65 meminfo_filename = os.path.join(opts.out_dir, 'meminfo.txt')
66 diskstats_filename = os.path.join(opts.out_dir, 'diskstats.txt')
67
68 log('[%s] Saving to files in %s every %d seconds', sys.argv[0],
69 opts.out_dir, opts.sleep_secs)
70
71 global o_stat, o_vm, o_mem, o_disk # flushed by signal handler
72
73 o_stat = open(stat_filename, 'w')
74 o_vm = open(vmstat_filename, 'w')
75 o_mem = open(meminfo_filename, 'w')
76 o_disk = open(diskstats_filename, 'w')
77
78 signal.signal(signal.SIGTERM, Handler)
79
80 i = 0
81 while True:
82 t = int(time.time()) # truncate to nearest second, to save space
83 #print(t)
84
85 with open('/proc/stat') as f:
86 for line in f:
87 # context switches
88 if line.startswith('cpu') or line.startswith('ctx'):
89 #log('line %r', line)
90 o_stat.write('%s %s' % (t, line))
91
92 with open('/proc/vmstat') as f:
93 for line in f:
94 # pgpgin and pgpgout are paging operations
95 if (line.startswith('pgfault') or
96 line.startswith('pgmajfault') or
97 line.startswith('pgpg')):
98 #log('line %r', line)
99 o_vm.write('%s %s' % (t, line))
100
101 with open('/proc/meminfo') as f:
102 for line in f:
103 if 'Total' in line: # MemTotal and SwapTotal never change
104 continue
105 if line.startswith('Mem') or line.startswith('Swap'):
106 #log('line %r', line)
107 o_mem.write('%s %s' % (t, line))
108
109 with open('/proc/diskstats') as f:
110 for line in f:
111 if 'loop' in line: # ignore loopback devices
112 continue
113 o_disk.write('%s %s' % (t, line))
114
115 # So we can tail -f
116 if i % 10 == 0:
117 FlushAll()
118
119 time.sleep(opts.sleep_secs)
120 i += 1
121
122 return 0
123
124
125if __name__ == '__main__':
126 try:
127 sys.exit(main(sys.argv))
128 except RuntimeError as e:
129 print('FATAL: %s' % e, file=sys.stderr)
130 sys.exit(1)