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'
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)
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)
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)
"(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)
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: