Esempio n. 1
0
def capture(opts, run_name):

    # If this is set we skip the capture
    perf_data_filename = opts.perf_data
    if perf_data_filename:
        print 'Skipping capture, using ' + perf_data_filename
    else:
        # need to capture traces
        print 'Capturing perf data for %d seconds...' % (opts.seconds)
        if not perf_record(opts):
            return
        perf_data_filename = 'perf.data'
        print 'Traces captured in perf.data'

    # collect stats
    if opts.all or opts.stats:
        if opts.perf_data:
            print 'Stats capture from provided perf data file not supported'
        else:
            stats_filename = opts.dest_folder + run_name + ".stats"
            capture_stats(opts, stats_filename)

    # create cdict from the perf data file

    if opts.all or opts.switches:
        try:
            cdict_filename = opts.dest_folder + run_name + '.cdict'
            # try to run this script through the perf tool itself as it is faster
            rc = subprocess.call([perf_binary, 'script', '-s', 'mkcdict_perf_script.py', '-i', perf_data_filename])
            if rc == 255:
                print '   ERROR: perf is not built with the python scripting extension - aborting...'
            else:
                # success result is in perf.cdict, so need to rename it
                os.rename('perf.cdict', cdict_filename)
                os.chmod(cdict_filename, 0664)
                print 'Created file: ' + cdict_filename
                # remap the task names if a mapping file was provided
                if opts.map:
                    perf_dict = perf_formatter.open_cdict(cdict_filename, opts.map)
                    perf_formatter.write_cdict(cdict_filename, perf_dict)
        except OSError:
            print 'Error: perf does not seems to be installed'
Esempio n. 2
0
def main():
    global from_time
    global cap_time

    # Suppress future warnings
    warnings.simplefilter(action='ignore', category=FutureWarning)

    parser = OptionParser(usage="usage: %prog [options] <cdict_file1> [cdict_file2...]")

    parser.add_option("-t", "--task",
                      dest="task",
                      metavar="task name (regex)",
                      help="selected task(s) (regex on task name)"
                      )
    parser.add_option("--label",
                      dest="label",
                      metavar="label",
                      help="label for the title (defaults to the cdict file name)"
                      )
    parser.add_option("--map",
                      dest="map",
                      action="store",
                      metavar="mapping csv file",
                      help="remap task names from mapping csv file"
                      )
    parser.add_option("--output-dir",
                      dest="output_dir",
                      action="store",
                      metavar="dir pathname",
                      help="output all html files to the provided directory"
                      )
    parser.add_option("--heatmaps",
                      dest="heatmaps",
                      action="store_true",
                      help="generate heatmap charts only (default: generate basic charts only)"
                      )
    parser.add_option("--headless",
                      dest="headless",
                      action="store_true",
                      help="do not show chart in the browser (default=False)"
                      )
    parser.add_option("-c", "--cap",
                      dest="cap_time",
                      help="(optional) cap the analysis to first <cap_time> msec"
                           " of capture (default=all)"
                      )
    parser.add_option("-f", "--from",
                      dest="from_time",
                      help="(optional) start the analysis after first <from_time> msec"
                           " of capture (default=0)"
                      )
    parser.add_option("--merge-sys-tasks",
                      dest="merge_sys_tasks",
                      action="store_true",
                      help="group all system tasks (e.g. swapper/0 -> swapper)"
                      )
    parser.add_option("--successors-of",
                      dest="successor_of_task",
                      help="only show list of successors of given tid or task name"
                      )
    parser.add_option("--list",
                      dest="list",
                      action="store_true",
                      default=False,
                      help="only show list of all tasks with event count"
                      )
    (options, args) = parser.parse_args()

    if options.from_time:
        from_time = int(options.from_time) * 1000
    if options.cap_time:
        # convert to usec
        cap_time = int(options.cap_time) * 1000 + from_time

    if not args:
        print 'Missing cdict file'
        sys.exit(1)

    if options.output_dir:
        if not os.path.isdir(options.output_dir):
            print('Invalid output directory: ' + options.output_dir)
            sys.exit(1)

    dfds = []
    cdict_files = args
    if len(cdict_files):
        if len(cdict_files) > 1:
            html_filename = cdict_files[0] + '-diff'
        else:
            html_filename = cdict_files[0]
    else:
        html_filename = cdict_files[0] if len(cdict_files) else 'perfwhiz'
    set_html_file(html_filename, options.headless, options.label, options.output_dir)

    # get smallest capture window of all cdicts
    min_cap_usec = 0
    for cdict_file in cdict_files:
        perf_dict = open_cdict(cdict_file, options.map)
        df = DataFrame(perf_dict)
        dfd = DfDesc(cdict_file, df, options.merge_sys_tasks)
        dfds.append(dfd)
        last_usec = df['usecs'].iloc[-1]
        if min_cap_usec == 0:
            min_cap_usec = last_usec
        else:
            min_cap_usec = min(min_cap_usec, last_usec)
    if from_time and from_time >= min_cap_usec:
        print 'Error: from time cannot be larger than %d msec' % (min_cap_usec / 1000)
        sys.exit(2)
    # if a cap time is provided, always use that value (even if it is >min_cap_usec)
    if not cap_time:
        cap_time = min_cap_usec

    # normalize all dataframes
    for dfd in dfds:
        dfd.normalize(from_time, cap_time)

    # at this point some cdict entries may have "missing" data
    # if the requested cap_time is > the cdict cap time
    # the relevant processing will extrapolate when needed (and if possible)

    # reduce all names to minimize the length o;f the cdict file name
    set_short_names(dfds)

    if not options.label:
        if len(dfds) > 1:
            options.label = 'diff'
        else:
            options.label = os.path.splitext(os.path.basename(cdict_file))[0]

    if options.list:
        print 'List of tids and task names sorted by context switches and kvm event count'
        for dfd in dfds:
            print dfd.name + ':'
            res = dfd.df.groupby(['pid', 'task_name']).size()
            res.sort_values(ascending=False, inplace=True)
            pandas.set_option('display.max_rows', len(res))
            print res
        sys.exit(0)

    if options.successor_of_task:
        for dfd in dfds:
            print dfd.name + ':'
            show_successors(dfd.df, options.successor_of_task, options.label)
        sys.exit(0)

    # These options can be cumulative and all require a --task parameter to select tasks
    if not options.task:
        print '--task <task_regex> is required'
        sys.exit(1)
    # A common mistake is to forget the head "." before a star ("*.vcpu0")
    # Better detect and fix to avoid frustration
    if options.task.startswith("*"):
        options.task = "." + options.task

    # create heatmaps only if one cdict was given
    if options.heatmaps:
        if len(dfds) == 1:
            create_heatmaps(dfds[0], cap_time, options.task, options.label)
        else:
            print 'Error: --heat-maps requires 1 cdict file only'
            sys.exit(1)
    else:
        create_charts(dfds, cap_time, options.task, options.label)
Esempio n. 3
0
def main():
    parser = OptionParser(usage="usage: %prog [options] [<run-name>]")

    parser.add_option('--stats', dest='stats',
                      action='store_true',
                      default=False,
                      help='capture context switches and kvm exit stats to <run-name>.stats')

    parser.add_option('--switches', dest='switches',
                      action='store_true',
                      default=False,
                      help='capture detailed context switch and kvm traces and create <run-name>.cdict if not none')

    parser.add_option('--all', dest='all',
                      action='store_true',
                      default=False,
                      help='capture all traces and stats into <run-name>.cdict and <run-name>.stats')

    parser.add_option('-s', '--sleep', dest='seconds',
                      action='store',
                      default=1,
                      type="int",
                      help='capture duration in seconds, defaults to 1 second',
                      metavar='<seconds>')

    parser.add_option('--dest-folder', dest='dest_folder',
                      action='store',
                      default='./',
                      help='destination folder where to store results (default: current folder)',
                      metavar='<dest folder>')

    parser.add_option('--use-perf-data', dest='perf_data',
                      action='store',
                      help='use given perf data file (do not capture)',
                      metavar='<perf data file>')

    parser.add_option("--map",
                      dest="map",
                      action="store",
                      metavar="mapping csv file",
                      help="remap task names from mapping csv file"
                      )

    parser.add_option('--use-perf', dest='perf',
                      action='store',
                      help='use given perf binary',
                      metavar='<perf binary>')

    parser.add_option("--remap",
                      dest="remap",
                      action="store",
                      metavar="cdict_file",
                      help="remap the passed cdict file using the given map file (see --map)"
                      )

    parser.add_option('-r', '--rc', dest='rc',
                      action='store',
                      help='source OpenStack credentials from rc file',
                      metavar='<openrc_file>')

    parser.add_option('-p', '--password', dest='passwordd',
                      action='store',
                      help='OpenStack password',
                      metavar='<password>')

    (opts, args) = parser.parse_args()

    if len(args) > 1:
        print 'This script requires 1 argument for the run name (any valid file name without extension)'
        sys.exit(0)
    if len(args):
        run_name = args[0]
    else:
        run_name = 'perf'

    if not os.path.isdir(opts.dest_folder):
        print 'Invalid destination folder: ' + opts.dest_folder
        sys.exit(2)
    if not opts.dest_folder.endswith('/'):
        opts.dest_folder += '/'

    # check the map file is valid if provided
    if opts.map:
        if not os.path.exists(opts.map):
            print 'ERROR: Invalid mapping file: ' + opts.map
            sys.exit(1)

    # pick at least one command
    if opts.remap:
        if not opts.map:
            print 'ERROR: remap command requires a csv mapping file (--map)'
            sys.exit(1)
        perf_dict = perf_formatter.open_cdict(opts.remap, opts.map)
        perf_formatter.write_cdict(opts.remap, perf_dict)
        sys.exit(0)

    if not (opts.all | opts.switches | opts.stats):
        print 'Pick at least one of --stats, --switches, --all'
        sys.exit(3)

    CFG_FILE = '.mkcdict.cfg'

    # check if there is a config file in the current directory
    if os.path.isfile(CFG_FILE):
        # load options from the config file if they are set to None
        print 'Loading options from ' + CFG_FILE
        opt_re = re.compile(' *(\w*) *[=:]+ *([\w/\-\.]*)')
        with open(CFG_FILE, 'r') as ff:
            for line in ff:
                m = opt_re.match(line)
                if m:
                    cfg_name = m.group(1)
                    try:
                        if getattr(opts, cfg_name) is None:
                            setattr(opts, cfg_name, m.group(2))
                    except AttributeError:
                        pass

    if opts.perf_data and not os.path.isfile(opts.perf_data):
        print 'Cannot find perf data file: ' + opts.perf_data
        sys.exit(1)

    if opts.perf:
        global perf_binary
        perf_binary = opts.perf
        print 'Overriding perf binary with: ' + perf_binary

    capture(opts, run_name)
Esempio n. 4
0
                  help="(Deprecated) migrate to new encoding with runtime aggregation into switch"
                  )
(options, args) = parser.parse_args()

if options.from_time:
    from_time = int(options.from_time) * 1000
if options.cap_time:
    # convert to usec
    cap_time = int(options.cap_time) * 1000 + from_time

if not args:
    print 'Missing cdict file'
    sys.exit(1)

cdict_file = args[0]
perf_dict = open_cdict(cdict_file, options.map)

df = DataFrame(perf_dict)
set_html_file(cdict_file, options.headless)

# filter on usecs
if from_time:
    df = df[df['usecs'] >= from_time]
if cap_time:
    df = df[df['usecs'] <= cap_time]

if not options.label:
    options.label = os.path.splitext(os.path.basename(cdict_file))[0]

if options.convert:
    convert(df, options.convert)
Esempio n. 5
0
    "(Deprecated) migrate to new encoding with runtime aggregation into switch"
)
(options, args) = parser.parse_args()

if options.from_time:
    from_time = int(options.from_time) * 1000
if options.cap_time:
    # convert to usec
    cap_time = int(options.cap_time) * 1000 + from_time

if not args:
    print 'Missing cdict file'
    sys.exit(1)

cdict_file = args[0]
perf_dict = open_cdict(cdict_file, options.map)

df = DataFrame(perf_dict)
set_html_file(cdict_file, options.headless)

# filter on usecs
if from_time:
    df = df[df['usecs'] >= from_time]
if cap_time:
    df = df[df['usecs'] <= cap_time]

if not options.label:
    options.label = os.path.splitext(os.path.basename(cdict_file))[0]

if options.convert:
    convert(df, options.convert)
Esempio n. 6
0
        sys.exit(2)
    if not opts.dest_folder.endswith('/'):
        opts.dest_folder += '/'

    # chek the map file is valid if provided
    if opts.map:
        if not os.path.exists(opts.map):
            print 'ERROR: Invalid mapping file: ' + opts.map
            sys.exit(1)

    # pick at least one command
    if opts.remap:
        if not opts.map:
            print 'ERROR: remap command requires a csv mapping file (--map)'
            sys.exit(1)
        perf_dict = perf_formatter.open_cdict(opts.remap, opts.map)
        perf_formatter.write_cdict(opts.remap, perf_dict)
        sys.exit(0)

    if not (opts.all | opts.switches | opts.stats):
        print 'Pick at least one of --stats, --switches, --all'
        sys.exit(3)

    CFG_FILE = '.mkcdict.cfg'

    # check if there is a config file in the current directory
    if os.path.isfile(CFG_FILE):
        # load options from the config file if they are set to None
        print 'Loading options from ' + CFG_FILE
        opt_re = re.compile(' *(\w*) *[=:]+ *([\w/\-\.]*)')
        with open(CFG_FILE, 'r') as ff:
Esempio n. 7
0
        sys.exit(2)
    if not opts.dest_folder.endswith('/'):
        opts.dest_folder += '/'

    # chek the map file is valid if provided
    if opts.map:
        if not os.path.exists(opts.map):
            print 'ERROR: Invalid mapping file: ' + opts.map
            sys.exit(1)

    # pick at least one command
    if opts.remap:
        if not opts.map:
            print 'ERROR: remap command requires a csv mapping file (--map)'
            sys.exit(1)
        perf_dict = perf_formatter.open_cdict(opts.remap, opts.map)
        perf_formatter.write_cdict(opts.remap, perf_dict)
        sys.exit(0)

    if not (opts.all | opts.switches | opts.stats):
        print 'Pick at least one of --stats, --switches, --all'
        sys.exit(3)

    CFG_FILE = '.mkcdict.cfg'

    # check if there is a config file in the current directory
    if os.path.isfile(CFG_FILE):
        # load options from the config file if they are set to None
        print 'Loading options from ' + CFG_FILE
        opt_re = re.compile(' *(\w*) *[=:]+ *([\w/\-\.]*)')
        with open(CFG_FILE, 'r') as ff: