Home | History | Annotate | Download | only in bootperf-bin
      1 #!/usr/bin/python
      2 
      3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 """A command to display summary statistics from runs of 'bootperf'.
      8 
      9 Command line options allow selecting from one of four sets of
     10 performance statistics:
     11  1. boot time statistics (selected by --keyset boot) measure time
     12     spent since kernel startup;
     13  2. disk statistics (selected by --keyset disk) measure total bytes
     14     read from the boot device since kernel startup;
     15  3. firmware time statistics (selected by --keyset firmware) measure
     16     time spent since CPU power on.
     17  4. reboot time statistics (selected by --keyset reboot) measure
     18     time spent since the shutdown request immediately preceding
     19     the request.
     20 
     21 The various statistics are recorded as cumulative time (or disk read)
     22 since kernel startup (or CPU power on), sampled when specific events
     23 occur during boot.  Events include such things as 'startup', (the
     24 moment when the upstart 'startup' job begins running), and 'login',
     25 (when the Chrome OS login screen is displayed).  By default, all
     26 recorded events are included in the output; command line options
     27 allow restricting the view to a selected subset of events.
     28 
     29 Separate command line options allow selecting from one of two
     30 different display modes.  When --averages is selected, the display
     31 shows the average value and sample standard deviation (as a percent
     32 of the average) for all selected events.  The --averages display
     33 also calculates the difference (in time or bytes) between adjacent
     34 events, and shows the average and sample standard deviation of the
     35 differences.
     36 
     37 The --rawdata display shows the raw data value associated with each
     38 event for each boot:  Each line of output represents the event values
     39 for one boot iteration.
     40 
     41 """
     42 
     43 import sys
     44 import optparse
     45 
     46 import perfprinter
     47 import resultsdir
     48 import resultset
     49 
     50 
     51 _USAGE = "%prog [options] [results-directory ...]"
     52 _DESCRIPTION = """\
     53 Summarize boot time performance results.  The result directory
     54 arguments are directories previously specified as output for the
     55 'bootperf' script.
     56 """
     57 
     58 
     59 def _SetupOptions():
     60   """Create an OptionParser for the command line."""
     61   optparser = optparse.OptionParser(usage=_USAGE, description=_DESCRIPTION)
     62 
     63   optgroup = optparse.OptionGroup(
     64       optparser, "Statistics selection")
     65 
     66   keyset_help = ("Selects the set of statistics to display; "
     67                     "choose one of ")
     68   keyset_help += "'" + resultset.TestResultSet.AVAILABLE_KEYSETS[0] + "'"
     69   for keyset in resultset.TestResultSet.AVAILABLE_KEYSETS[1:-1]:
     70     keyset_help += ", '" + keyset + "'"
     71   keyset_help += (", or '" +
     72                   resultset.TestResultSet.AVAILABLE_KEYSETS[-1] + "'.")
     73   keyset_default = resultset.TestResultSet.BOOTTIME_KEYSET
     74   keyset_help += "  (Default is '" + keyset_default + "'.)"
     75   optgroup.add_option(
     76       "-k", "--keyset", action="store", dest="keyset", type="choice",
     77       choices=resultset.TestResultSet.AVAILABLE_KEYSETS,
     78       help=keyset_help)
     79   optparser.add_option_group(optgroup)
     80   optparser.set_defaults(keyset=keyset_default)
     81 
     82   optgroup = optparse.OptionGroup(optparser, "Event selection")
     83   optgroup.add_option(
     84       "-e", "--event", action="append",
     85       dest="eventnames",
     86       help="Restrict statistics to the comma-separated list of events.")
     87   optparser.add_option_group(optgroup)
     88 
     89   optgroup = optparse.OptionGroup(
     90       optparser, "Display mode selection (choose one)")
     91   optgroup.add_option(
     92       "-a", "--averages", action="store_true",
     93       dest="print_averages",
     94       help="Display a summary of the averages of chosen statistics (default).")
     95   optgroup.add_option(
     96       "-r", "--rawdata", action="store_true",
     97       dest="print_raw",
     98       help="Display raw data from all boot iterations.")
     99   optparser.add_option_group(optgroup)
    100   optparser.set_defaults(print_averages=False)
    101   optparser.set_defaults(print_raw=False)
    102   return optparser
    103 
    104 
    105 def _ProcessDisplayOptions(options):
    106   """Determine options controlling the display format.
    107 
    108   Command options allow choosing either raw data format, or summary
    109   statistics format.  The default option is the summary format.
    110   It's not allowed to select both formats.
    111 
    112   @param options Parsed command line options data.
    113 
    114   """
    115   display_count = 0
    116   if options.print_averages:
    117     display_count += 1
    118     printfunc = perfprinter.PrintStatisticsSummary
    119   if options.print_raw:
    120     display_count += 1
    121     printfunc = perfprinter.PrintRawData
    122   if display_count == 0:
    123     printfunc = perfprinter.PrintStatisticsSummary
    124   elif display_count > 1:
    125     print >>sys.stderr, "Can't use -a and -r together.\n"
    126     return None
    127   return printfunc
    128 
    129 
    130 def _ProcessEventlistOptions(options):
    131   """Determine whether we'll display all events, or a subset.
    132 
    133   Command options allow restricting a chosen key set to a
    134   list of specific events.  If the option is present, return
    135   the list of events.  Otherwise, return `None`.
    136 
    137   @param options Parsed command line options data.
    138 
    139   """
    140   if not options.eventnames:
    141     return None
    142   eventlist = []
    143   for kl in options.eventnames:
    144     eventlist.extend(kl.split(','))
    145   return eventlist
    146 
    147 
    148 def main(argv):
    149   """Canonical main routine."""
    150   optparser = _SetupOptions()
    151   (options, args) = optparser.parse_args(argv)
    152   printfunc = _ProcessDisplayOptions(options)
    153   keyset_type = options.keyset
    154   eventlist = _ProcessEventlistOptions(options)
    155   if printfunc is None or keyset_type is None:
    156     optparser.print_help()
    157     sys.exit(1)
    158   if not args:
    159     args = ["."]
    160   printfunc(resultsdir.ReadResultsDirectory,
    161             args, keyset_type, eventlist)
    162 
    163 
    164 if __name__ == "__main__":
    165   main(sys.argv[1:])
    166