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

Side by Side Diff: 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: changes from code review Created 4 years, 8 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 unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2
3 # Copyright (c) 2016 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 '''Tracing controller class. This class manages
8 multiple tracing agents and collects data from all of them. It also
9 manages the clock sync process.
10 '''
11
12 import ast
13 import tempfile
14 import uuid
15 import sys
16
17 import trace_event
18 from devil.utils import reraiser_thread
19 from devil.utils import timeout_retry
20 from systrace.tracing_agents import TracingAgent
21 from systrace.tracing_agents import TraceResults
22
23 # TODO(alexandermont): Current version of trace viewer does not support
24 # the controller tracing agent output. Thus we use this variable to
25 # suppress this tracing agent's output. This should be removed once
26 # trace viewer is working again.
27 output_controller_tracing_agent = False
Zhen Wang 2016/03/30 18:11:16 s/output_controller_tracing_agent/OUTPUT_CONTROLLE
28
29 class TracingController(TracingAgent):
30 def __init__(self, options, categories, agents):
31 """Create tracing controller.
32
33 Create a tracing controller object. Note that the tracing
34 controller is also a tracing agent.
35
36 Args:
37 options: Tracing options.
38 categories: Categories of trace events to record.
39 agents: List of tracing agents for this controller.
40 """
41 super(TracingController, self).__init__()
42 self._agents = agents
43 self._options = options
44 self._categories = categories
45 self._trace_in_progress = False
46 self._clock_sync_markers = []
47 self._log_path = None
48 self._all_results = None
49
50 def _StartAgentTracing_func(self):
Zhen Wang 2016/03/30 16:14:08 nit: is this name following the style? Why not jus
alexandermont 2016/03/30 19:33:25 Done. Changed to _StartAgentTracingImpl. (Don't wa
51 """Start tracing for the controller tracing agent.
52
53 Start tracing for the controller tracing agent. Note that
54 the tracing controller records the "controller side"
55 of the clock sync records, and nothing else.
56 """
57 if not trace_event.trace_can_enable():
58 raise RuntimeError, ('Cannot enable trace_event;'
59 ' ensure catapult_base is in PYTHONPATH')
60
61 controller_log_file = tempfile.NamedTemporaryFile(delete=False)
62 self._log_path = controller_log_file.name
63 controller_log_file.close()
64 trace_event.trace_enable(self._log_path)
65 return True
66
67 def StartAgentTracing(self, options, categories, timeout=10):
68 # pylint: disable=unused-argument
69 # don't need the options and categories arguments in this
70 # case, but including them for consistency with the
71 # function prototypes for other TracingAgents
72 return timeout_retry.Run(self._StartAgentTracing_func,
73 timeout, 1)
74
75 @property
76 def trace_in_progress(self):
77 return self._trace_in_progress
78
79 def _StopAgentTracing_func(self):
80 """Stops tracing for the controller tracing agent.
81 """
82 # pylint: disable=no-self-use
83 # This function doesn't use self, but making it a member function
84 # for consistency with the other TracingAgents
85 trace_event.trace_disable()
86 return True
87
88 def StopAgentTracing(self, timeout=10):
89 return timeout_retry.Run(self._StopAgentTracing_func,
90 timeout, 1)
91
92 def _GetResults_func(self):
93 """Gets the log output from the controller tracing agent.
94
95 This output only contains the "controller side" of the clock sync records.
96 """
97 if self._trace_in_progress:
98 raise RuntimeError, 'Cannot get results while trace is in progress'
99 with open(self._log_path, 'r') as outfile:
100 result = outfile.read() + ']'
101 return TraceResults('traceEvents', ast.literal_eval(result))
102
103 def GetResults(self, timeout=30):
104 return timeout_retry.Run(self._GetResults_func,
105 timeout, 1)
106
107 def StartTracing(self):
108 """Start tracing for all tracing agents.
109
110 This function starts tracing for both the controller tracing agent
111 and the child tracing agents.
112
113 Returns:
114 Boolean indicating whether or not the start tracing succeeded
115 for all agents.
116 """
117 assert not self._trace_in_progress, 'Trace already in progress.'
118 self._trace_in_progress = True
119 if not self.StartAgentTracing(self._options,
120 self._categories,
121 timeout=self._options.timeout):
122 print 'Unable to start controller tracing agent.'
123 return False
124 succ_agents = []
125 for agent in self._agents:
126 if agent.StartAgentTracing(self._options,
127 self._categories,
128 timeout=self._options.timeout):
129 succ_agents.append(agent)
130 else:
131 print 'Agent %s not started.' % str(agent)
132 na = len(self._agents)
133 ns = len(succ_agents)
134 if ns < na:
135 print 'Warning: Only %d of %d tracing agents started.' % (na, ns)
136 self._agents = succ_agents
137
138 def StopTracing(self):
139 """Issue clock sync marker and stop tracing for all tracing agents.
140
141 This function stops both the controller tracing agent
142 and the child tracing agents. It issues a clock sync marker prior
143 to stopping tracing.
144
145 Returns:
146 Boolean indicating whether or not the stop tracing succeeded
147 for all agents.
148 """
149 assert self._trace_in_progress, 'No trace in progress.'
150 self._trace_in_progress = False
151 self._IssueClockSyncMarker()
152 succ_agents = []
153 for agent in self._agents:
154 if agent.StopAgentTracing(timeout=self._options.timeout):
155 succ_agents.append(agent)
156 else:
157 print 'Agent %s not stopped.' % str(agent)
158 if not self.StopAgentTracing(timeout=self._options.timeout):
159 print 'Unable to stop controller tracing agent.'
160 return False
161 na = len(self._agents)
162 ns = len(succ_agents)
163 if ns < na:
164 print 'Warning: Only %d of %d tracing agents stopped.' % (na, ns)
165 self._agents = succ_agents
166 self._all_results = {}
167 for agent in self._agents + [self]:
168 try:
169 (key, value) = agent.GetResults(
170 timeout=self._options.collection_timeout)
171 if key in self._all_results:
172 print 'Warning: Duplicate tracing agents'
173 if (agent is not self) or output_controller_tracing_agent:
174 self._all_results[key] = value
175 except reraiser_thread.TimeoutError:
176 print 'Warning: Timeout when getting results.'
177 except:
178 print 'Warning: Other exception when getting results:'
179 print sys.exc_info()[0]
180 raise
181 return True
182
183 def SupportsExplicitClockSync(self):
184 '''Returns whether this supports explicit clock sync.
185
186 Although the tracing controller conceptually supports explicit clock
187 sync, it is not an agent controlled by other controllers so it does not
188 define RecordClockSyncMarker (rather, the recording of the "controller
189 side" of the clock sync marker is done in _IssueClockSyncMarker). Thus,
190 SupportsExplicitClockSync must return false.
191 '''
192 return False
193
194 def RecordClockSyncMarker(self, sync_id, callback):
195 raise NotImplementedError
196
197 def _IssueClockSyncMarker(self):
198 """Issue clock sync markers to all the child tracing agents."""
199 for agent in self._agents:
200 if agent.SupportsExplicitClockSync():
201 sync_id = GetUniqueSyncID()
202 callback = lambda t, s: trace_event.clock_sync(s, issue_ts=t)
203 agent.RecordClockSyncMarker(sync_id, callback)
204
205 def GetUniqueSyncID():
206 """Get a unique sync ID.
207
208 Gets a unique sync ID by generating a UUID and converting it to a string
209 (since UUIDs are not JSON serializable)
210 """
211 return str(uuid.uuid4())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698