blob: a954b125da5ca75f51f80df2d5ee0212c7c3dc6a [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
2# ***********************************************************************
3# Warning: This file is auto-generated from main.py.in - edit it there.
4# ***********************************************************************
5#
6# pybootchartgui is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# pybootchartgui is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
18
Patrick Williamsc124f4f2015-09-15 14:41:29 -050019import sys
20import os
21import optparse
22
23from . import parsing
24from . import batch
25
26def _mk_options_parser():
27 """Make an options parser."""
28 usage = "%prog [options] /path/to/tmp/buildstats/<recipe-machine>/<BUILDNAME>/"
29 version = "%prog v1.0.0"
30 parser = optparse.OptionParser(usage, version=version)
31 parser.add_option("-i", "--interactive", action="store_true", dest="interactive", default=False,
32 help="start in active mode")
33 parser.add_option("-f", "--format", dest="format", default="png", choices=["png", "svg", "pdf"],
34 help="image format (png, svg, pdf); default format png")
35 parser.add_option("-o", "--output", dest="output", metavar="PATH", default=None,
36 help="output path (file or directory) where charts are stored")
37 parser.add_option("-s", "--split", dest="num", type=int, default=1,
38 help="split the output chart into <NUM> charts, only works with \"-o PATH\"")
39 parser.add_option("-m", "--mintime", dest="mintime", type=int, default=8,
40 help="only tasks longer than this time will be displayed")
41 parser.add_option("-M", "--minutes", action="store_true", dest="as_minutes", default=False,
42 help="display time in minutes instead of seconds")
43# parser.add_option("-n", "--no-prune", action="store_false", dest="prune", default=True,
44# help="do not prune the process tree")
45 parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False,
46 help="suppress informational messages")
47# parser.add_option("-t", "--boot-time", action="store_true", dest="boottime", default=False,
48# help="only display the boot time of the boot in text format (stdout)")
49 parser.add_option("--very-quiet", action="store_true", dest="veryquiet", default=False,
50 help="suppress all messages except errors")
51 parser.add_option("--verbose", action="store_true", dest="verbose", default=False,
52 help="print all messages")
53# parser.add_option("--profile", action="store_true", dest="profile", default=False,
54# help="profile rendering of chart (only useful when in batch mode indicated by -f)")
55# parser.add_option("--show-pid", action="store_true", dest="show_pid", default=False,
56# help="show process ids in the bootchart as 'processname [pid]'")
57 parser.add_option("--show-all", action="store_true", dest="show_all", default=False,
58 help="show all processes in the chart")
59# parser.add_option("--crop-after", dest="crop_after", metavar="PROCESS", default=None,
60# help="crop chart when idle after PROCESS is started")
61# parser.add_option("--annotate", action="append", dest="annotate", metavar="PROCESS", default=None,
62# help="annotate position where PROCESS is started; can be specified multiple times. " +
63# "To create a single annotation when any one of a set of processes is started, use commas to separate the names")
64# parser.add_option("--annotate-file", dest="annotate_file", metavar="FILENAME", default=None,
65# help="filename to write annotation points to")
66 parser.add_option("-T", "--full-time", action="store_true", dest="full_time", default=False,
67 help="display the full time regardless of which processes are currently shown")
68 return parser
69
70class Writer:
71 def __init__(self, write, options):
72 self.write = write
73 self.options = options
74
75 def error(self, msg):
76 self.write(msg)
77
78 def warn(self, msg):
79 if not self.options.quiet:
80 self.write(msg)
81
82 def info(self, msg):
83 if self.options.verbose:
84 self.write(msg)
85
86 def status(self, msg):
87 if not self.options.quiet:
88 self.write(msg)
89
90def _mk_writer(options):
91 def write(s):
92 print(s)
93 return Writer(write, options)
94
95def _get_filename(path):
96 """Construct a usable filename for outputs"""
97 dname = "."
98 fname = "bootchart"
99 if path != None:
100 if os.path.isdir(path):
101 dname = path
102 else:
103 fname = path
104 return os.path.join(dname, fname)
105
106def main(argv=None):
107 try:
108 if argv is None:
109 argv = sys.argv[1:]
110
111 parser = _mk_options_parser()
112 options, args = parser.parse_args(argv)
113
114 # Default values for disabled options
115 options.prune = True
116 options.boottime = False
117 options.profile = False
118 options.show_pid = False
119 options.crop_after = None
120 options.annotate = None
121 options.annotate_file = None
122
123 writer = _mk_writer(options)
124
125 if len(args) == 0:
126 print("No path given, trying /var/log/bootchart.tgz")
127 args = [ "/var/log/bootchart.tgz" ]
128
129 res = parsing.Trace(writer, args, options)
130
131 if options.interactive or options.output == None:
132 from . import gui
133 gui.show(res, options)
134 elif options.boottime:
135 import math
136 proc_tree = res.proc_tree
137 if proc_tree.idle:
138 duration = proc_tree.idle
139 else:
140 duration = proc_tree.duration
141 dur = duration / 100.0
142 print('%02d:%05.2f' % (math.floor(dur/60), dur - 60 * math.floor(dur/60)))
143 else:
144 if options.annotate_file:
145 f = open (options.annotate_file, "w")
146 try:
147 for time in res[4]:
148 if time is not None:
149 # output as ms
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600150 f.write(time * 10)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 finally:
152 f.close()
153 filename = _get_filename(options.output)
154 res_list = parsing.split_res(res, options)
155 n = 1
156 width = len(str(len(res_list)))
157 s = "_%%0%dd." % width
158 for r in res_list:
159 if len(res_list) == 1:
160 f = filename + "." + options.format
161 else:
162 f = filename + s % n + options.format
163 n = n + 1
164 def render():
165 batch.render(writer, r, options, f)
166 if options.profile:
167 import cProfile
168 import pstats
169 profile = '%s.prof' % os.path.splitext(filename)[0]
170 cProfile.runctx('render()', globals(), locals(), profile)
171 p = pstats.Stats(profile)
172 p.strip_dirs().sort_stats('time').print_stats(20)
173 else:
174 render()
175
176 return 0
177 except parsing.ParseError as ex:
178 print(("Parse error: %s" % ex))
179 return 2
180
181
182if __name__ == '__main__':
183 sys.exit(main())