aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/pybootchartgui/pybootchartgui/main.py.in
blob: cc9c40b17860445625fd444b580700a6a6d26d01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@media only all and (prefers-color-scheme: dark) {
.highlight .hll { background-color: #49483e }
.highlight .c { color: #75715e } /* Comment */
.highlight .err { color: #960050; background-color: #1e0010 } /* Error */
.highlight .k { color: #66d9ef } /* Keyword */
.highlight .l { color: #ae81ff } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #f92672 } /* Operator */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #75715e } /* Comment.Hashbang */
.highlight .cm { color: #75715e } /* Comment.Multiline */
.highlight .cp { color: #75715e } /* Comment.Preproc */
.highlight .cpf { color: #75715e } /* Comment.PreprocFile */
.highlight .c1 { color: #75715e } /* Comment.Single */
.highlight .cs { color: #75715e } /* Comment.Special */
.highlight .gd { color: #f92672 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gi { color: #a6e22e } /* Generic.Inserted */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #75715e } /* Generic.Subheading */
.highlight .kc { color: #66d9ef } /* Keyword.Constant */
.highlight .kd { color: #66d9ef } /* Keyword.Declaration */
.highlight .kn { color: #f92672 } /* Keyword.Namespace */
.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */
.highlight .kr { color: #66d9ef } /* Keyword.Reserved */
.highlight .kt { color: #66d9ef } /* Keyword.Type */
.highlight .ld { color: #e6db74 } /* Literal.Date */
.highlight .m { color: #ae81ff } /* Literal.Number */
.highlight .s { color: #e6db74 } /* Literal.String */
.highlight .na { color: #a6e22e } /* Name.Attribute */
.highlight .nb { color: #f8f8f2 } /* Name.Builtin */
.highlight .nc { color: #a6e22e } /* Name.Class */
.highlight .no { color: #66d9ef } /* Name.Constant */
.highlight .nd { color: #a6e22e } /* Name.Decorator */
.highlight .ni { color: #f8f8f2 } /* Name.Entity */
.highlight .ne { color: #a6e22e } /* Name.Exception */
.highlight .nf { color: #a6e22e } /* Name.Function */
.highlight .nl { color: #f8f8f2 } /* Name.Label */
.highlight .nn { color: #f8f8f2 } /* Name.Namespace */
.highlight .nx { color: #a6e22e } /* Name.Other */
.highlight .py { color: #f8f8f2 } /* Name.Property */
.highlight .nt { color: #f92672 } /* Name.Tag */
.highlight .nv { color: #f8f8f2 } /* Name.Variable */
.highlight .ow { color: #f92672 } /* Operator.Word */
.highlight .w { color: #f8f8f2 } /* Text.Whitespace */
.highlight .mb { color: #ae81ff } /* Literal.Number.Bin */
.highlight .mf { color: #ae81ff } /* Literal.Number.Float */
.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */
.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */
.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */
.highlight .sa { color: #e6db74 } /* Literal.String.Affix */
.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */
.highlight .sc { color: #e6db74 } /* Literal.String.Char */
.highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */
.highlight .sd { color: #e6db74 } /* Literal.String.Doc */
.highlight .s2 { color: #e6db74 } /* Literal.String.Double */
.highlight .se { color: #ae81ff } /* Literal.String.Escape */
.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */
.highlight .si { color: #e6db74 } /* Literal.String.Interpol */
.highlight .sx { color: #e6db74 } /* Literal.String.Other */
.highlight .sr { color: #e6db74 } /* Literal.String.Regex */
.highlight .s1 { color: #e6db74 } /* Literal.String.Single */
.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */
.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #a6e22e } /* Name.Function.Magic */
.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */
.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */
.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */
.highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */
.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */
}
@media (prefers-color-scheme: light) {
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { colo
#
# ***********************************************************************
#  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/>.

from __future__ import print_function

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")
	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
							print(time * 10, file=f)
						else:
							print(file=f)
				finally:
					f.close()
			filename = _get_filename(options.output)
			res_list = parsing.split_res(res, options.num)
			n = 1
			for r in res_list:
				if len(res_list) == 1:
					f = filename + "." + options.format
				else:
					f = filename + "_" + str(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())