bno_plot.py: Use `with open() as ...` context manager to automatically handle close()
[blktrace.git] / btt / bno_plot.py
1 #! /usr/bin/env python
2 #
3 # btt blkno plotting interface
4 #
5 #  (C) Copyright 2008 Hewlett-Packard Development Company, L.P.
6 #
7 #  This program is free software; you can redistribute it and/or modify
8 #  it under the terms of the GNU General Public License as published by
9 #  the Free Software Foundation; either version 2 of the License, or
10 #  (at your option) any later version.
11 #
12 #  This program is distributed in the hope that it will be useful,
13 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #  GNU General Public License for more details.
16 #
17 #  You should have received a copy of the GNU General Public License
18 #  along with this program; if not, write to the Free Software
19 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 #
21 """
22 bno_plot.py
23         [ -h | --help       ]
24         [ -K | --keys-below ]
25         [ -v | --verbose    ]
26         [ <file...>         ]
27
28 Utilizes gnuplot to generate a 3D plot of the block number output
29 from btt.  If no <files> are specified, it will utilize all files
30 generated after btt was run with -B blknos (meaning: all files of the
31 form blknos*[rw].dat).
32
33 The -K option forces bno_plot.py to put the keys below the graph,
34 typically all keys for input files are put in the upper right corner
35 of the graph. If the number of devices exceed 10, then bno_plot.py will
36 automatically push the keys under the graph.
37
38 To exit the plotter, enter 'quit' or ^D at the 'gnuplot> ' prompt.
39 """
40
41 from __future__ import absolute_import
42 from __future__ import print_function
43 import getopt, glob, os, sys, tempfile, shutil
44
45 verbose = 0
46 cmds    = """
47 set title 'btt Generated Block Accesses'
48 set xlabel 'Time (secs)'
49 set ylabel 'Block Number'
50 set zlabel '# Blocks per IO'
51 set grid
52 """
53
54
55 #-----------------------------------------------------------------------------
56 def parse_args(in_args):
57         global verbose
58
59         keys_below = False
60         s_opts = 'hKv'
61         l_opts = [ 'help', 'keys-below', 'verbose' ]
62
63         try:
64                 (opts, args) = getopt.getopt(in_args, s_opts, l_opts)
65         except getopt.error as msg:
66                 print(msg, file=sys.stderr)
67                 print(__doc__, file=sys.stderr)
68                 sys.exit(1)
69
70         for (o, a) in opts:
71                 if o in ('-h', '--help'):
72                         print(__doc__)
73                         sys.exit(0)
74                 elif o in ('-v', '--verbose'):
75                         verbose += 1
76                 elif o in ('-K', '--keys-below'):
77                         keys_below = True
78
79         if len(args) > 0:       bnos = args
80         else:                   bnos = glob.glob('blknos*[rw].dat')
81
82         return (bnos, keys_below)
83
84 #-----------------------------------------------------------------------------
85 if __name__ == '__main__':
86         (bnos, keys_below) = parse_args(sys.argv[1:])
87
88         if verbose:
89                 print('Using files:', end=' ')
90                 for bno in bnos: print(bno, end=' ')
91                 if keys_below:  print('\nKeys are to be placed below graph')
92                 else:           print('')
93
94         tmpdir = tempfile.mktemp()
95         os.mkdir(tmpdir)
96
97         plot_cmd = None
98         for f in bnos:
99                 t = '%s/%s' % (tmpdir, f)
100
101                 with open(t, 'w') as fo:
102                         with open(f, 'r') as fi:
103                                 for line in fi:
104                                         fld = line.split(None)
105                                         print(fld[0], fld[1], int(fld[2])-int(fld[1]), file=fo)
106
107                 t = t[t.rfind('/')+1:]
108                 if plot_cmd == None: plot_cmd = "splot '%s'" % t
109                 else:                plot_cmd = "%s,'%s'" % (plot_cmd, t)
110
111         with open('%s/plot.cmds' % tmpdir, 'w') as fo:
112                 print(cmds, file=fo)
113                 if len(bnos) > 10 or keys_below: print('set key below', file=fo)
114                 print(plot_cmd, file=fo)
115
116         pid = os.fork()
117         if pid == 0:
118                 cmd = 'gnuplot %s/plot.cmds -' % tmpdir
119
120                 if verbose: print('Executing %s' % cmd)
121
122                 os.chdir(tmpdir)
123                 os.system(cmd)
124                 sys.exit(1)
125
126         os.waitpid(pid, 0)
127         shutil.rmtree(tmpdir)