main.py.in 6.5 KB

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