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

Unified Diff: chromecast/tools/trace.py

Issue 962063002: Chromecast: tracing script to use for Linux-based cast_shell. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromecast/tools/trace.py
diff --git a/chromecast/tools/trace.py b/chromecast/tools/trace.py
new file mode 100755
index 0000000000000000000000000000000000000000..bf93611e0bae34344435424b64f8d85bd4165305
--- /dev/null
+++ b/chromecast/tools/trace.py
@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+#
+# Copyright 2015 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.
+#
+# This script was originally written by Alok Priyadarshi (alokp@)
+# with some minor local modifications.
+
+import contextlib
+import json
+import logging
+import math
+import optparse
+import os
+import sys
+import websocket
+
+
+class TracingClient(object):
+ def BufferUsage(self, buffer_usage):
+ percent = int(math.floor(buffer_usage * 100))
+ logging.debug('Buffer Usage: %i', percent)
+
+
+class TracingBackend(object):
+ def __init__(self, devtools_port):
+ self._socket = None
+ self._next_request_id = 0
+ self._tracing_client = None
+ self._tracing_data = []
+
+ def Connect(self, device_ip, devtools_port, timeout=10):
+ assert not self._socket
+ url = 'ws://%s:%i/devtools/browser' % (device_ip, devtools_port)
+ print('Connect to %s ...' % url)
+ self._socket = websocket.create_connection(url, timeout=timeout)
+ self._next_request_id = 0
+
+ def Disconnect(self):
+ if self._socket:
+ self._socket.close()
+ self._socket = None
+
+ def StartTracing(self,
+ tracing_client=None,
+ custom_categories=None,
+ record_continuously=False,
+ buffer_usage_reporting_interval=0,
+ timeout=10):
+ self._tracing_client = tracing_client
+ self._socket.settimeout(timeout)
+ req = {
+ 'method': 'Tracing.start',
+ 'params': {
+ 'categories': custom_categories,
+ 'bufferUsageReportingInterval': buffer_usage_reporting_interval,
+ 'options': 'record-continuously' if record_continuously else
+ 'record-until-full'
+ }
+ }
+ self._SendRequest(req)
+
+ def StopTracing(self, timeout=30):
+ self._socket.settimeout(timeout)
+ req = {'method': 'Tracing.end'}
+ self._SendRequest(req)
+ while self._socket:
+ res = self._ReceiveResponse()
+ if 'method' in res and self._HandleResponse(res):
+ self._tracing_client = None
+ result = self._tracing_data
+ self._tracing_data = []
+ return result
+
+ def _SendRequest(self, req):
+ req['id'] = self._next_request_id
+ self._next_request_id += 1
+ data = json.dumps(req)
+ self._socket.send(data)
+
+ def _ReceiveResponse(self):
+ while self._socket:
+ data = self._socket.recv()
+ res = json.loads(data)
+ return res
+
+ def _HandleResponse(self, res):
+ method = res.get('method')
+ value = res.get('params', {}).get('value')
+ if 'Tracing.dataCollected' == method:
+ if type(value) in [str, unicode]:
+ self._tracing_data.append(value)
+ elif type(value) is list:
+ self._tracing_data.extend(value)
+ else:
+ logging.warning('Unexpected type in tracing data')
+ elif 'Tracing.bufferUsage' == method and self._tracing_client:
+ self._tracing_client.BufferUsage(value)
+ elif 'Tracing.tracingComplete' == method:
+ return True
+
+
+@contextlib.contextmanager
+def Connect(device_ip, devtools_port):
+ backend = TracingBackend(devtools_port)
+ try:
+ backend.Connect(device_ip, devtools_port)
+ yield backend
+ finally:
+ backend.Disconnect()
+
+
+def DumpTrace(trace, options):
+ filepath = os.path.expanduser(options.output) if options.output \
+ else os.path.join(os.getcwd(), 'trace.json')
+
+ dirname = os.path.dirname(filepath)
+ if dirname:
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ else:
+ filepath = os.path.join(os.getcwd(), filepath)
+
+ with open(filepath, "w") as f:
+ json.dump(trace, f)
+ return filepath
+
+
+def _CreateOptionParser():
+ parser = optparse.OptionParser(description='Record about://tracing profiles '
+ 'from any running instance of Chrome.')
+ parser.add_option(
+ '-v', '--verbose', help='Verbose logging.', action='store_true')
+ parser.add_option(
+ '-p', '--port', help='Remote debugging port.', type="int", default=9222)
+ parser.add_option(
+ '-d', '--device', help='Device ip address.', type='string',
+ default='127.0.0.1')
+
+ tracing_opts = optparse.OptionGroup(parser, 'Tracing options')
+ tracing_opts.add_option(
+ '-c', '--category-filter',
+ help='Apply filter to control what category groups should be traced.',
+ type='string')
+ tracing_opts.add_option(
+ '--record-continuously',
+ help='Keep recording until stopped. The trace buffer is of fixed size '
+ 'and used as a ring buffer. If this option is omitted then '
+ 'recording stops when the trace buffer is full.',
+ action='store_true')
+ parser.add_option_group(tracing_opts)
+
+ output_options = optparse.OptionGroup(parser, 'Output options')
+ output_options.add_option(
+ '-o', '--output',
+ help='Save trace output to file.')
+ parser.add_option_group(output_options)
+
+ return parser
+
+
+def _ProcessOptions(options):
+ websocket.enableTrace(options.verbose)
+
+
+def main():
+ parser = _CreateOptionParser()
+ options, _args = parser.parse_args()
+ _ProcessOptions(options)
+
+ with Connect(options.device, options.port) as tracing_backend:
+ tracing_backend.StartTracing(TracingClient(),
+ options.category_filter,
+ options.record_continuously)
+ raw_input('Capturing trace. Press Enter to stop...')
+ trace = tracing_backend.StopTracing()
+
+ filepath = DumpTrace(trace, options)
+ print('Done')
+ print('Trace written to file://%s' % filepath)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698