# Copyright (c) 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import codecs import base64 import gzip import json import os import StringIO import tracing_project from py_vulcanize import generate def Main(argv): parser = argparse.ArgumentParser( usage='%(prog)s <options> trace_file1 [trace_file2 ...]', epilog='Takes the provided trace file and produces a standalone HTML\n' 'file that contains both the trace and the trace viewer.') project = tracing_project.TracingProject() project.AddConfigNameOptionToParser(parser) parser.add_argument( '--output', dest='output', help='Where to put the generated result. If not ' 'given, the trace filename is used, with an html suffix.') parser.add_argument( '--quiet', action='store_true', help='Dont print the output file name') parser.add_argument( '--title', type=str, help='The title to put in trace viewer top panel.') parser.add_argument('trace_files', nargs='+') args = parser.parse_args(argv[1:]) if args.output: output_filename = args.output elif len(args.trace_files) > 1: parser.error('Must specify --output if there are multiple trace files.') else: name_part = os.path.splitext(args.trace_files[0])[0] output_filename = name_part + '.html' with codecs.open(output_filename, mode='w', encoding='utf-8') as f: WriteHTMLForTracesToFile(args.trace_files, f, args.title, config_name=args.config_name) if not args.quiet: print output_filename return 0 class ViewerDataScript(generate.ExtraScript): def __init__(self, trace_data_string, mime_type): super(ViewerDataScript, self).__init__() self._trace_data_string = trace_data_string self._mime_type = mime_type def WriteToFile(self, output_file): output_file.write('<script id="viewer-data" type="%s">\n' % self._mime_type) compressed_trace = StringIO.StringIO() with gzip.GzipFile(fileobj=compressed_trace, mode='w') as f: f.write(self._trace_data_string) b64_content = base64.b64encode(compressed_trace.getvalue()) output_file.write(b64_content) output_file.write('\n</script>\n') def WriteHTMLForTraceDataToFile(trace_data_list, title, output_file, config_name=None): project = tracing_project.TracingProject() if config_name is None: config_name = project.GetDefaultConfigName() modules = [ 'tracing.trace2html', project.GetModuleNameForConfigName(config_name), ] vulcanizer = project.CreateVulcanizer() load_sequence = vulcanizer.CalcLoadSequenceForModuleNames(modules) scripts = [] for trace_data in trace_data_list: # If the object was previously decoded from valid JSON data (e.g., in # WriteHTMLForTracesToFile), it will be a JSON object at this point and we # should re-serialize it into a string. Other types of data will be already # be strings. if not isinstance(trace_data, basestring): trace_data = json.dumps(trace_data) mime_type = 'application/json' else: mime_type = 'text/plain' scripts.append(ViewerDataScript(trace_data, mime_type)) generate.GenerateStandaloneHTMLToFile( output_file, load_sequence, title, extra_scripts=scripts) def WriteHTMLForTracesToFile(trace_filenames, output_file, title='', config_name=None): trace_data_list = [] for filename in trace_filenames: with open(filename, 'r') as f: trace_data = f.read() trace_data_list.append(trace_data) if not title: title = "Trace from %s" % ','.join(trace_filenames) WriteHTMLForTraceDataToFile(trace_data_list, title, output_file, config_name)