Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Unified Diff: systrace/systrace/systrace_tracing_controller.py

Issue 1776013005: [DO NOT COMMIT] Refactor systrace to support new clock sync design (Closed) Base URL: git@github.com:catapult-project/catapult@master
Patch Set: fix categories issue Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « systrace/systrace/systrace_agent.py ('k') | systrace/systrace/systrace_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: systrace/systrace/systrace_tracing_controller.py
diff --git a/systrace/systrace/systrace_tracing_controller.py b/systrace/systrace/systrace_tracing_controller.py
new file mode 100644
index 0000000000000000000000000000000000000000..15ca56e4688523696d41925d52b9e952e1c9e987
--- /dev/null
+++ b/systrace/systrace/systrace_tracing_controller.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 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.
+
+'''Implementation of tracing controller for systrace. This class creates the
+necessary tracing agents for systrace, runs them, and outputs the results
+as an HTML file.'''
+
+import imp
+import json
+import os
+
+from systrace import tracing_controller
+
+# The default agent directory.
+DEFAULT_AGENT_DIR = 'tracing_agents'
+
+# TODO(alexandermont): Current version of trace viewer does not support
+# the controller tracing agent output. Thus we use this variable to
+# suppress this tracing agent's output. This should be removed once
+# trace viewer is working again.
+OUTPUT_CONTROLLER_TRACE_ = False
+
+
+class SystraceTracingController(tracing_controller.TracingController):
+ def __init__(self, script_dir, options, categories):
+ """Set up the SystraceTracingController.
+
+ Args:
+ script_dir: Directory containing the trace viewer script
+ (systrace_trace_viewer.html)
+ options: List of command line options.
+ categories: List of trace categories to capture.
+ """
+ # Parse command line arguments and create agents
+ self._script_dir = script_dir
+ self._out_filename = options.output_file
+ agents = CreateAgents(options, categories)
+
+ # Error if no agents are available
+ if not agents:
+ dirs = DEFAULT_AGENT_DIR
+ if options.agent_dirs:
+ dirs += ',' + options.agent_dirs
+ raise RuntimeError('No systrace agent is available'
+ 'in directories |%s|.\n' % dirs)
+
+ # Update trace viewer if necessary
+ try:
+ from systrace import update_systrace_trace_viewer
+ except ImportError:
+ pass
+ else:
+ update_systrace_trace_viewer.update(dest=script_dir)
+
+ super(SystraceTracingController, self).__init__(options,
+ categories,
+ agents)
+
+ def SupportsExplicitClockSync(self):
+ return False
+
+ def RecordClockSyncMarker(self, sync_id, callback):
+ raise NotImplementedError
+
+ def OutputSystraceResults(self, write_json=False):
+ """Output the results of systrace to a file.
+
+ If output is necessary, then write the results of systrace to either (a)
+ a standalone HTML file, or (b) a json file which can be read by the
+ trace viewer.
+
+ Args:
+ write_json: Whether to output to a json file (if false, use HTML file)
+ """
+ print 'Tracing complete, writing results'
+ if write_json:
+ self._WriteTraceJSON(self._all_results)
+ else:
+ self._WriteTraceHTML(self._all_results)
+
+ def _WriteTraceJSON(self, results):
+ """Write the results of systrace as a JSON file.
+
+ Args:
+ results: Results to write.
+ """
+ print 'Writing trace JSON'
+ results['controllerTraceDataKey'] = 'traceEvents'
+ if not OUTPUT_CONTROLLER_TRACE_:
+ results['traceEvents'] = []
+ with open(self._out_filename, 'w') as json_file:
+ json.dump(results, json_file)
+ print '\n wrote file://%s\n' % os.path.abspath(self._out_filename)
+
+ def _WriteTraceHTML(self, results):
+ """Write the results of systrace to an HTML file.
+
+ Args:
+ results: Results to write.
+ """
+ def _read_asset(src_dir, filename):
+ return open(os.path.join(src_dir, filename)).read()
+
+ # Get the trace viewer code and the prefix and suffix for the HTML.
+ print 'Writing trace HTML'
+ systrace_dir = os.path.abspath(os.path.dirname(__file__))
+ html_prefix = _read_asset(systrace_dir, 'prefix.html')
+ html_suffix = _read_asset(systrace_dir, 'suffix.html')
+ trace_viewer_html = _read_asset(self._script_dir,
+ 'systrace_trace_viewer.html')
+
+ # Open the file in binary mode to prevent python from changing the
+ # line endings, then write the prefix.
+ html_file = open(self._out_filename, 'wb')
+ html_file.write(html_prefix.replace('{{SYSTRACE_TRACE_VIEWER_HTML}}',
+ trace_viewer_html))
+
+ # Write the trace data itself. There is a separate section of the form
+ # <script class="trace-data" type="application/text"> ... </script>
+ # for each tracing agent (including the controller tracing agent).
+ html_file.write('<!-- BEGIN TRACE -->\n')
+ for (name, data) in results.iteritems():
+ if name == 'traceEvents' and not OUTPUT_CONTROLLER_TRACE_:
+ continue
+ html_file.write(' <script class="')
+ html_file.write('trace-data')
+ html_file.write('" type="application/text">\n')
+ html_file.write(convert(data))
+ html_file.write(' </script>\n')
+ html_file.write('<!-- END TRACE -->\n')
+
+ # Write the suffix and finish.
+ html_file.write(html_suffix)
+ html_file.close()
+ print '\n wrote file://%s\n' % os.path.abspath(self._out_filename)
+
+def convert(data):
+ """Convert a data element to the format to be output into HTML.
+
+ If the data element is a dictionary or list, JSON-encode it.
+ If the data element is a string, leave it unchanged.
+
+ Args:
+ data: Data to convert.
+
+ Returns:
+ String to be output into the HTML file.
+ """
+ if isinstance(data, dict) or isinstance(data, list):
+ return json.dumps(data)
+ elif isinstance(data, str):
+ return data
+ else:
+ raise ValueError('Invalid data format for HTML output')
+
+def CreateAgents(options, categories):
+ """Create systrace agents.
+
+ This function will search systrace agent modules in agent directories and
+ create the corresponding systrace agents.
+ Args:
+ options: The command-line options.
+ categories: The trace categories to capture.
+ Returns:
+ The list of systrace agents.
+ """
+ agent_dirs = [os.path.join(os.path.dirname(__file__),
+ DEFAULT_AGENT_DIR)]
+ if options.agent_dirs:
+ agent_dirs.extend(options.agent_dirs.split(','))
+
+ agents = []
+ for agent_dir in agent_dirs:
+ if not agent_dir:
+ continue
+ for filename in os.listdir(agent_dir):
+ (module_name, ext) = os.path.splitext(filename)
+ if (ext != '.py' or module_name == '__init__'
+ or module_name.endswith('_unittest')):
+ continue
+ (f, pathname, data) = imp.find_module(module_name, [agent_dir])
+ try:
+ module = imp.load_module(module_name, f, pathname, data)
+ finally:
+ if f:
+ f.close()
+ if module:
+ agent = module.try_create_agent(options, categories)
+ if not agent:
+ continue
+ agents.append(agent)
+ return agents
« no previous file with comments | « systrace/systrace/systrace_agent.py ('k') | systrace/systrace/systrace_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698