Chromium Code Reviews| Index: systrace/systrace/tracing_controller.py |
| diff --git a/systrace/systrace/tracing_controller.py b/systrace/systrace/tracing_controller.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6858ea8644177bd5446c80ad01be75f95d1eef89 |
| --- /dev/null |
| +++ b/systrace/systrace/tracing_controller.py |
| @@ -0,0 +1,127 @@ |
| +#!/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. |
| + |
| +'''Tracing controller class. This class manages |
| +multiple tracing agents and collects data from all of them. It also |
| +manages the clock sync process. |
| +''' |
| + |
| +import tempfile |
| +import trace_event |
| +import uuid |
| +from systrace import tracing_agent |
| + |
| + |
| +TRACE_ERR = 'Cannot enable trace_event; ensure catapult_base is in PYTHONPATH' |
|
nednguyen
2016/03/14 17:48:11
It's strange that you put this as a constant. I wo
alexandermont
2016/03/14 22:19:28
Done
|
| + |
| + |
| +class TracingController(tracing_agent.TracingAgent): |
| + def __init__(self, agents): |
| + """Create tracing controller. Note that the tracing |
| + controller is also a tracing agent. |
| + |
| + Args: |
| + agents: List of tracing agents for this controller. |
| + """ |
| + super(TracingController, self).__init__() |
| + self._agents = agents |
| + self._trace_in_progress = False |
| + self._clock_sync_markers = [] |
| + self._log_path = None |
| + self._all_results = None |
| + |
| + #override |
| + def StartAgentTracing(self): |
| + """Start tracing for the controller tracing agent. Note that |
| + the tracing controller records the "controller side" |
| + of the clock sync records, and nothing else. |
| + """ |
| + if not trace_event.trace_can_enable(): |
| + raise RuntimeError, TRACE_ERR |
| + controller_log_file = tempfile.NamedTemporaryFile(delete=False) |
| + self._log_path = controller_log_file.name |
| + controller_log_file.close() |
| + trace_event.trace_enable(self._log_path) |
| + return True |
| + |
| + @property |
| + def trace_in_progress(self): |
| + return self._trace_in_progress |
| + |
| + #override |
| + def StopAgentTracing(self): |
| + """Stops tracing for the controller tracing agent. |
| + """ |
| + trace_event.trace_disable() |
| + return True |
| + |
| + #override |
| + def GetResults(self): |
| + """Gets the log output from the controller tracing agent. Again, |
| + this contains only the "controller side" of the clock sync |
| + records. |
| + """ |
| + if self._trace_in_progress: |
| + raise RuntimeError, 'Cannot get results while trace is in progress' |
| + with open(self._log_path, 'r') as outfile: |
| + result = outfile.read() + ']' |
| + return tracing_agent.TraceResults('trace-data', result, True) |
|
Zhen Wang
2016/03/14 17:11:27
s/trace-data/systrace
This will need some small t
alexandermont
2016/03/14 22:19:28
Done
|
| + |
| + #override |
| + def StartTracing(self): |
| + """Start tracing for all tracing agents (the controller tracing agent |
| + and the child tracing agents). |
| + |
| + Returns: |
| + Boolean indicating whether or not the start tracing succeeded |
| + for all agents. |
| + """ |
| + assert not self._trace_in_progress, 'Trace already in progress.' |
| + self._trace_in_progress = True |
| + all_succ = True |
| + all_succ = all_succ and self.StartAgentTracing() |
| + for agent in self._agents: |
| + all_succ = all_succ and agent.StartAgentTracing() |
| + |
| + #override |
| + def StopTracing(self): |
| + """Stop tracing for all tracing agents (the controller tracing agent |
| + and the child tracing agents). Issues clock sync marker prior |
| + to stopping tracing. |
| + |
| + Returns: |
| + Boolean indicating whether or not the stop tracing succeeded |
| + for all agents. |
| + """ |
| + assert self._trace_in_progress, 'No trace in progress.' |
| + self._trace_in_progress = False |
| + self._IssueClockSyncMarker() |
| + all_succ = True |
| + for agent in self._agents: |
| + all_succ = all_succ and agent.StopAgentTracing() |
| + all_succ = all_succ and self.StopAgentTracing() |
| + self._all_results = [agent.GetResults() for agent in self._agents + [self]] |
|
nednguyen
2016/03/14 17:48:11
this has to be a dictionary that conforms to https
Zhen Wang
2016/03/14 17:58:23
GetResults() here returns a tuple.
The old systra
alexandermont
2016/03/14 22:19:28
Changed it to use a dict. Note that I still have n
|
| + |
| + #override |
| + def SupportsExplicitClockSync(self): |
| + return False |
|
Zhen Wang
2016/03/14 17:11:27
Conceptually the controller supports explicit cloc
alexandermont
2016/03/14 22:19:28
Done
|
| + |
| + #override |
| + def RecordClockSyncMarker(self, sync_id, callback): |
| + raise NotImplementedError |
| + |
| + def _IssueClockSyncMarker(self): |
| + """Issue clock sync markers to all the child tracing agents.""" |
| + for agent in self._agents: |
| + if agent.SupportsExplicitClockSync(): |
| + sync_id = GetUniqueSyncID() |
| + callback = lambda t, s: trace_event.clock_sync(s, issue_ts=t) |
| + agent.RecordClockSyncMarker(sync_id, callback) |
| + |
| +def GetUniqueSyncID(): |
| + """Get a unique sync ID. |
| + """ |
| + return uuid.uuid4() |