#
|
# ***********************************************************************
|
# Warning: This file is auto-generated from main.py.in - edit it there.
|
# ***********************************************************************
|
#
|
# pybootchartgui is free software: you can redistribute it and/or modify
|
# it under the terms of the GNU General Public License as published by
|
# the Free Software Foundation, either version 3 of the License, or
|
# (at your option) any later version.
|
|
# pybootchartgui is distributed in the hope that it will be useful,
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# GNU General Public License for more details.
|
|
# You should have received a copy of the GNU General Public License
|
# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
|
|
import sys
|
import os
|
import optparse
|
|
from . import parsing
|
from . import batch
|
|
def _mk_options_parser():
|
"""Make an options parser."""
|
usage = "%prog [options] /path/to/tmp/buildstats/<recipe-machine>/<BUILDNAME>/"
|
version = "%prog v1.0.0"
|
parser = optparse.OptionParser(usage, version=version)
|
parser.add_option("-i", "--interactive", action="store_true", dest="interactive", default=False,
|
help="start in active mode")
|
parser.add_option("-f", "--format", dest="format", default="png", choices=["png", "svg", "pdf"],
|
help="image format (png, svg, pdf); default format png")
|
parser.add_option("-o", "--output", dest="output", metavar="PATH", default=None,
|
help="output path (file or directory) where charts are stored")
|
parser.add_option("-s", "--split", dest="num", type=int, default=1,
|
help="split the output chart into <NUM> charts, only works with \"-o PATH\"")
|
parser.add_option("-m", "--mintime", dest="mintime", type=int, default=8,
|
help="only tasks longer than this time will be displayed")
|
parser.add_option("-M", "--minutes", action="store_true", dest="as_minutes", default=False,
|
help="display time in minutes instead of seconds")
|
# parser.add_option("-n", "--no-prune", action="store_false", dest="prune", default=True,
|
# help="do not prune the process tree")
|
parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False,
|
help="suppress informational messages")
|
# parser.add_option("-t", "--boot-time", action="store_true", dest="boottime", default=False,
|
# help="only display the boot time of the boot in text format (stdout)")
|
parser.add_option("--very-quiet", action="store_true", dest="veryquiet", default=False,
|
help="suppress all messages except errors")
|
parser.add_option("--verbose", action="store_true", dest="verbose", default=False,
|
help="print all messages")
|
# parser.add_option("--profile", action="store_true", dest="profile", default=False,
|
# help="profile rendering of chart (only useful when in batch mode indicated by -f)")
|
# parser.add_option("--show-pid", action="store_true", dest="show_pid", default=False,
|
# help="show process ids in the bootchart as 'processname [pid]'")
|
parser.add_option("--show-all", action="store_true", dest="show_all", default=False,
|
help="show all processes in the chart")
|
# parser.add_option("--crop-after", dest="crop_after", metavar="PROCESS", default=None,
|
# help="crop chart when idle after PROCESS is started")
|
# parser.add_option("--annotate", action="append", dest="annotate", metavar="PROCESS", default=None,
|
# help="annotate position where PROCESS is started; can be specified multiple times. " +
|
# "To create a single annotation when any one of a set of processes is started, use commas to separate the names")
|
# parser.add_option("--annotate-file", dest="annotate_file", metavar="FILENAME", default=None,
|
# help="filename to write annotation points to")
|
parser.add_option("-T", "--full-time", action="store_true", dest="full_time", default=False,
|
help="display the full time regardless of which processes are currently shown")
|
return parser
|
|
class Writer:
|
def __init__(self, write, options):
|
self.write = write
|
self.options = options
|
|
def error(self, msg):
|
self.write(msg)
|
|
def warn(self, msg):
|
if not self.options.quiet:
|
self.write(msg)
|
|
def info(self, msg):
|
if self.options.verbose:
|
self.write(msg)
|
|
def status(self, msg):
|
if not self.options.quiet:
|
self.write(msg)
|
|
def _mk_writer(options):
|
def write(s):
|
print(s)
|
return Writer(write, options)
|
|
def _get_filename(path):
|
"""Construct a usable filename for outputs"""
|
dname = "."
|
fname = "bootchart"
|
if path != None:
|
if os.path.isdir(path):
|
dname = path
|
else:
|
fname = path
|
return os.path.join(dname, fname)
|
|
def main(argv=None):
|
try:
|
if argv is None:
|
argv = sys.argv[1:]
|
|
parser = _mk_options_parser()
|
options, args = parser.parse_args(argv)
|
|
# Default values for disabled options
|
options.prune = True
|
options.boottime = False
|
options.profile = False
|
options.show_pid = False
|
options.crop_after = None
|
options.annotate = None
|
options.annotate_file = None
|
|
writer = _mk_writer(options)
|
|
if len(args) == 0:
|
print("No path given, trying /var/log/bootchart.tgz")
|
args = [ "/var/log/bootchart.tgz" ]
|
|
res = parsing.Trace(writer, args, options)
|
|
if options.interactive or options.output == None:
|
from . import gui
|
gui.show(res, options)
|
elif options.boottime:
|
import math
|
proc_tree = res.proc_tree
|
if proc_tree.idle:
|
duration = proc_tree.idle
|
else:
|
duration = proc_tree.duration
|
dur = duration / 100.0
|
print('%02d:%05.2f' % (math.floor(dur/60), dur - 60 * math.floor(dur/60)))
|
else:
|
if options.annotate_file:
|
f = open (options.annotate_file, "w")
|
try:
|
for time in res[4]:
|
if time is not None:
|
# output as ms
|
f.write(time * 10)
|
finally:
|
f.close()
|
filename = _get_filename(options.output)
|
res_list = parsing.split_res(res, options)
|
n = 1
|
width = len(str(len(res_list)))
|
s = "_%%0%dd." % width
|
for r in res_list:
|
if len(res_list) == 1:
|
f = filename + "." + options.format
|
else:
|
f = filename + s % n + options.format
|
n = n + 1
|
def render():
|
batch.render(writer, r, options, f)
|
if options.profile:
|
import cProfile
|
import pstats
|
profile = '%s.prof' % os.path.splitext(filename)[0]
|
cProfile.runctx('render()', globals(), locals(), profile)
|
p = pstats.Stats(profile)
|
p.strip_dirs().sort_stats('time').print_stats(20)
|
else:
|
render()
|
|
return 0
|
except parsing.ParseError as ex:
|
print(("Parse error: %s" % ex))
|
return 2
|
|
|
if __name__ == '__main__':
|
sys.exit(main())
|