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

Side by Side Diff: tools/android/loading/pull_sandwich_metrics.py

Issue 1707793002: sandwich: Refactor to use more existing code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 unified diff | Download patch
OLDNEW
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # Copyright 2016 The Chromium Authors. All rights reserved. 2 # Copyright 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Pull a sandwich run's output directory's metrics from traces into a CSV. 6 """Pull a sandwich run's output directory's metrics from traces into a CSV.
7 7
8 python pull_sandwich_metrics.py -h 8 python pull_sandwich_metrics.py -h
9 """ 9 """
10 10
11 import argparse 11 import argparse
12 import csv 12 import csv
13 import json 13 import json
14 import logging 14 import logging
15 import os 15 import os
16 import sys 16 import sys
17 17
18 import loading_trace as loading_trace_module
19 import tracing
20
18 21
19 CATEGORIES = ['blink.user_timing', 'disabled-by-default-memory-infra'] 22 CATEGORIES = ['blink.user_timing', 'disabled-by-default-memory-infra']
20 23
21 _CSV_FIELD_NAMES = [ 24 _CSV_FIELD_NAMES = [
22 'id', 25 'id',
23 'url', 26 'url',
24 'total_load', 27 'total_load',
25 'onload', 28 'onload',
26 'browser_malloc_avg', 29 'browser_malloc_avg',
27 'browser_malloc_max'] 30 'browser_malloc_max']
28 31
29 _TRACKED_EVENT_NAMES = set(['requestStart', 'loadEventStart', 'loadEventEnd']) 32 _TRACKED_EVENT_NAMES = set(['requestStart', 'loadEventStart', 'loadEventEnd'])
30 33
31 34
32 def _GetBrowserPID(trace): 35 def _GetBrowserPID(tracing_track):
33 """Get the browser PID from a trace. 36 """Get the browser PID from a trace.
34 37
35 Args: 38 Args:
36 trace: The cached trace. 39 tracing_track: The tracing.TracingTrack.
37 40
38 Returns: 41 Returns:
39 The browser's PID as an integer. 42 The browser's PID as an integer.
40 """ 43 """
41 for event in trace['traceEvents']: 44 assert type(tracing_track) == tracing.TracingTrack
42 if event['cat'] != '__metadata' or event['name'] != 'process_name': 45 for event in tracing_track.GetEvents():
46 if event.category != '__metadata' or event.name != 'process_name':
43 continue 47 continue
44 if event['args']['name'] == 'Browser': 48 if event.args['name'] == 'Browser':
45 return event['pid'] 49 return event.pid
46 raise ValueError('couldn\'t find browser\'s PID') 50 raise ValueError('couldn\'t find browser\'s PID')
47 51
48 52
49 def _GetBrowserDumpEvents(trace): 53 def _GetBrowserDumpEvents(tracing_track):
50 """Get the browser memory dump events from a trace. 54 """Get the browser memory dump events from a tracing track.
51 55
52 Args: 56 Args:
53 trace: The cached trace. 57 tracing_track: The tracing.TracingTrack.
54 58
55 Returns: 59 Returns:
56 List of memory dump events. 60 List of memory dump events.
57 """ 61 """
58 browser_pid = _GetBrowserPID(trace) 62 assert type(tracing_track) == tracing.TracingTrack
63 browser_pid = _GetBrowserPID(tracing_track)
59 browser_dumps_events = [] 64 browser_dumps_events = []
60 for event in trace['traceEvents']: 65 for event in tracing_track.GetEvents():
61 if event['cat'] != 'disabled-by-default-memory-infra': 66 if event.category != 'disabled-by-default-memory-infra':
62 continue 67 continue
63 if event['ph'] != 'v' or event['name'] != 'periodic_interval': 68 if event.type != 'v' or event.name != 'periodic_interval':
64 continue 69 continue
65 # Ignore dump events for processes other than the browser process 70 # Ignore dump events for processes other than the browser process
66 if event['pid'] != browser_pid: 71 if event.pid != browser_pid:
67 continue 72 continue
68 browser_dumps_events.append(event) 73 browser_dumps_events.append(event)
69 if len(browser_dumps_events) == 0: 74 if len(browser_dumps_events) == 0:
70 raise ValueError('No browser dump events found.') 75 raise ValueError('No browser dump events found.')
71 return browser_dumps_events 76 return browser_dumps_events
72 77
73 78
74 def _GetWebPageTrackedEvents(trace): 79 def _GetWebPageTrackedEvents(tracing_track):
75 """Get the web page's tracked events from a trace. 80 """Get the web page's tracked events from a tracing track.
76 81
77 Args: 82 Args:
78 trace: The cached trace. 83 tracing_track: The tracing.TracingTrack.
79 84
80 Returns: 85 Returns:
81 Dictionary all tracked events. 86 Dictionary all tracked events.
82 """ 87 """
88 assert type(tracing_track) == tracing.TracingTrack
83 main_frame = None 89 main_frame = None
84 tracked_events = {} 90 tracked_events = {}
85 for event in trace['traceEvents']: 91 for event in tracing_track.GetEvents():
86 if event['cat'] != 'blink.user_timing': 92 if event.category != 'blink.user_timing':
87 continue 93 continue
88 event_name = event['name'] 94 event_name = event.name
89 # Ignore events until about:blank's unloadEventEnd that give the main 95 # Ignore events until about:blank's unloadEventEnd that give the main
90 # frame id. 96 # frame id.
91 if not main_frame: 97 if not main_frame:
92 if event_name == 'unloadEventEnd': 98 if event_name == 'unloadEventEnd':
93 main_frame = event['args']['frame'] 99 main_frame = event.args['frame']
94 logging.info('found about:blank\'s event \'unloadEventEnd\'') 100 logging.info('found about:blank\'s event \'unloadEventEnd\'')
95 continue 101 continue
96 # Ignore sub-frames events. requestStart don't have the frame set but it 102 # Ignore sub-frames events. requestStart don't have the frame set but it
97 # is fine since tracking the first one after about:blank's unloadEventEnd. 103 # is fine since tracking the first one after about:blank's unloadEventEnd.
98 if 'frame' in event['args'] and event['args']['frame'] != main_frame: 104 if 'frame' in event.args and event.args['frame'] != main_frame:
99 continue 105 continue
100 if event_name in _TRACKED_EVENT_NAMES and event_name not in tracked_events: 106 if event_name in _TRACKED_EVENT_NAMES and event_name not in tracked_events:
101 logging.info('found url\'s event \'%s\'' % event_name) 107 logging.info('found url\'s event \'%s\'' % event_name)
102 tracked_events[event_name] = event 108 tracked_events[event_name] = event
103 assert len(tracked_events) == len(_TRACKED_EVENT_NAMES) 109 assert len(tracked_events) == len(_TRACKED_EVENT_NAMES)
104 return tracked_events 110 return tracked_events
105 111
106 112
107 def _PullMetricsFromTrace(trace): 113 def _PullMetricsFromLoadingTrace(loading_trace):
108 """Pulls all the metrics from a given trace. 114 """Pulls all the metrics from a given trace.
109 115
110 Args: 116 Args:
111 trace: The cached trace. 117 loading_trace: loading_trace_module.LoadingTrace.
112 118
113 Returns: 119 Returns:
114 Dictionary with all _CSV_FIELD_NAMES's field set (except the 'id'). 120 Dictionary with all _CSV_FIELD_NAMES's field set (except the 'id').
115 """ 121 """
116 browser_dump_events = _GetBrowserDumpEvents(trace) 122 assert type(loading_trace) == loading_trace_module.LoadingTrace
mattcary 2016/02/19 14:41:05 This sort of check seems overly fussy. Worse, it p
gabadie 2016/02/19 15:04:35 Done.
117 web_page_tracked_events = _GetWebPageTrackedEvents(trace) 123 browser_dump_events = _GetBrowserDumpEvents(loading_trace.tracing_track)
124 web_page_tracked_events = _GetWebPageTrackedEvents(
125 loading_trace.tracing_track)
118 126
119 browser_malloc_sum = 0 127 browser_malloc_sum = 0
120 browser_malloc_max = 0 128 browser_malloc_max = 0
121 for dump_event in browser_dump_events: 129 for dump_event in browser_dump_events:
122 attr = dump_event['args']['dumps']['allocators']['malloc']['attrs']['size'] 130 attr = dump_event.args['dumps']['allocators']['malloc']['attrs']['size']
123 assert attr['units'] == 'bytes' 131 assert attr['units'] == 'bytes'
124 size = int(attr['value'], 16) 132 size = int(attr['value'], 16)
125 browser_malloc_sum += size 133 browser_malloc_sum += size
126 browser_malloc_max = max(browser_malloc_max, size) 134 browser_malloc_max = max(browser_malloc_max, size)
127 135
128 return { 136 return {
129 'total_load': (web_page_tracked_events['loadEventEnd']['ts'] - 137 'total_load': (web_page_tracked_events['loadEventEnd'].start_msec -
130 web_page_tracked_events['requestStart']['ts']), 138 web_page_tracked_events['requestStart'].start_msec),
131 'onload': (web_page_tracked_events['loadEventEnd']['ts'] - 139 'onload': (web_page_tracked_events['loadEventEnd'].start_msec -
132 web_page_tracked_events['loadEventStart']['ts']), 140 web_page_tracked_events['loadEventStart'].start_msec),
133 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)), 141 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)),
134 'browser_malloc_max': browser_malloc_max 142 'browser_malloc_max': browser_malloc_max
135 } 143 }
136 144
137 145
138 def _PullMetricsFromOutputDirectory(output_directory_path): 146 def _PullMetricsFromOutputDirectory(output_directory_path):
139 """Pulls all the metrics from all the traces of a sandwich run directory. 147 """Pulls all the metrics from all the traces of a sandwich run directory.
140 148
141 Args: 149 Args:
142 output_directory_path: The sandwich run's output directory to pull the 150 output_directory_path: The sandwich run's output directory to pull the
(...skipping 12 matching lines...) Expand all
155 if not os.path.isdir(os.path.join(output_directory_path, node_name)): 163 if not os.path.isdir(os.path.join(output_directory_path, node_name)):
156 continue 164 continue
157 try: 165 try:
158 page_id = int(node_name) 166 page_id = int(node_name)
159 except ValueError: 167 except ValueError:
160 continue 168 continue
161 trace_path = os.path.join(output_directory_path, node_name, 'trace.json') 169 trace_path = os.path.join(output_directory_path, node_name, 'trace.json')
162 if not os.path.isfile(trace_path): 170 if not os.path.isfile(trace_path):
163 continue 171 continue
164 logging.info('processing \'%s\'' % trace_path) 172 logging.info('processing \'%s\'' % trace_path)
165 with open(trace_path) as trace_file: 173 loading_trace = loading_trace_module.LoadingTrace.FromJsonFile(trace_path)
166 trace = json.load(trace_file) 174 trace_metrics = _PullMetricsFromLoadingTrace(loading_trace)
167 trace_metrics = _PullMetricsFromTrace(trace) 175 trace_metrics['id'] = page_id
168 trace_metrics['id'] = page_id 176 trace_metrics['url'] = run_infos['urls'][page_id]
169 trace_metrics['url'] = run_infos['urls'][page_id] 177 metrics.append(trace_metrics)
170 metrics.append(trace_metrics)
171 assert len(metrics) > 0, ('Looks like \'{}\' was not a sandwich ' + 178 assert len(metrics) > 0, ('Looks like \'{}\' was not a sandwich ' +
172 'run directory.').format(output_directory_path) 179 'run directory.').format(output_directory_path)
173 return metrics 180 return metrics
174 181
175 182
176 def main(): 183 def main():
177 logging.basicConfig(level=logging.INFO) 184 logging.basicConfig(level=logging.INFO)
178 185
179 parser = argparse.ArgumentParser() 186 parser = argparse.ArgumentParser()
180 parser.add_argument('output', type=str, 187 parser.add_argument('output', type=str,
181 help='Output directory of run_sandwich.py command.') 188 help='Output directory of run_sandwich.py command.')
182 args = parser.parse_args() 189 args = parser.parse_args()
183 190
184 trace_metrics_list = _PullMetricsFromOutputDirectory(args.output) 191 trace_metrics_list = _PullMetricsFromOutputDirectory(args.output)
185 trace_metrics_list.sort(key=lambda e: e['id']) 192 trace_metrics_list.sort(key=lambda e: e['id'])
186 cs_file_path = os.path.join(args.output, 'trace_analysis.csv') 193 cs_file_path = os.path.join(args.output, 'trace_analysis.csv')
187 with open(cs_file_path, 'w') as csv_file: 194 with open(cs_file_path, 'w') as csv_file:
188 writer = csv.DictWriter(csv_file, fieldnames=_CSV_FIELD_NAMES) 195 writer = csv.DictWriter(csv_file, fieldnames=_CSV_FIELD_NAMES)
189 writer.writeheader() 196 writer.writeheader()
190 for trace_metrics in trace_metrics_list: 197 for trace_metrics in trace_metrics_list:
191 writer.writerow(trace_metrics) 198 writer.writerow(trace_metrics)
192 return 0 199 return 0
193 200
194 201
195 if __name__ == '__main__': 202 if __name__ == '__main__':
196 sys.exit(main()) 203 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698