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

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: Addresses benoit's comments 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 for event in tracing_track.GetEvents():
42 if event['cat'] != '__metadata' or event['name'] != 'process_name': 45 if event.category != '__metadata' or event.name != 'process_name':
43 continue 46 continue
44 if event['args']['name'] == 'Browser': 47 if event.args['name'] == 'Browser':
45 return event['pid'] 48 return event.pid
46 raise ValueError('couldn\'t find browser\'s PID') 49 raise ValueError('couldn\'t find browser\'s PID')
47 50
48 51
49 def _GetBrowserDumpEvents(trace): 52 def _GetBrowserDumpEvents(tracing_track):
50 """Get the browser memory dump events from a trace. 53 """Get the browser memory dump events from a tracing track.
51 54
52 Args: 55 Args:
53 trace: The cached trace. 56 tracing_track: The tracing.TracingTrack.
54 57
55 Returns: 58 Returns:
56 List of memory dump events. 59 List of memory dump events.
57 """ 60 """
58 browser_pid = _GetBrowserPID(trace) 61 browser_pid = _GetBrowserPID(tracing_track)
59 browser_dumps_events = [] 62 browser_dumps_events = []
60 for event in trace['traceEvents']: 63 for event in tracing_track.GetEvents():
61 if event['cat'] != 'disabled-by-default-memory-infra': 64 if event.category != 'disabled-by-default-memory-infra':
62 continue 65 continue
63 if event['ph'] != 'v' or event['name'] != 'periodic_interval': 66 if event.type != 'v' or event.name != 'periodic_interval':
64 continue 67 continue
65 # Ignore dump events for processes other than the browser process 68 # Ignore dump events for processes other than the browser process
66 if event['pid'] != browser_pid: 69 if event.pid != browser_pid:
67 continue 70 continue
68 browser_dumps_events.append(event) 71 browser_dumps_events.append(event)
69 if len(browser_dumps_events) == 0: 72 if len(browser_dumps_events) == 0:
70 raise ValueError('No browser dump events found.') 73 raise ValueError('No browser dump events found.')
71 return browser_dumps_events 74 return browser_dumps_events
72 75
73 76
74 def _GetWebPageTrackedEvents(trace): 77 def _GetWebPageTrackedEvents(tracing_track):
75 """Get the web page's tracked events from a trace. 78 """Get the web page's tracked events from a tracing track.
76 79
77 Args: 80 Args:
78 trace: The cached trace. 81 tracing_track: The tracing.TracingTrack.
79 82
80 Returns: 83 Returns:
81 Dictionary all tracked events. 84 Dictionary all tracked events.
82 """ 85 """
83 main_frame = None 86 main_frame = None
84 tracked_events = {} 87 tracked_events = {}
85 for event in trace['traceEvents']: 88 for event in tracing_track.GetEvents():
86 if event['cat'] != 'blink.user_timing': 89 if event.category != 'blink.user_timing':
87 continue 90 continue
88 event_name = event['name'] 91 event_name = event.name
89 # Ignore events until about:blank's unloadEventEnd that give the main 92 # Ignore events until about:blank's unloadEventEnd that give the main
90 # frame id. 93 # frame id.
91 if not main_frame: 94 if not main_frame:
92 if event_name == 'unloadEventEnd': 95 if event_name == 'unloadEventEnd':
93 main_frame = event['args']['frame'] 96 main_frame = event.args['frame']
94 logging.info('found about:blank\'s event \'unloadEventEnd\'') 97 logging.info('found about:blank\'s event \'unloadEventEnd\'')
95 continue 98 continue
96 # Ignore sub-frames events. requestStart don't have the frame set but it 99 # 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. 100 # is fine since tracking the first one after about:blank's unloadEventEnd.
98 if 'frame' in event['args'] and event['args']['frame'] != main_frame: 101 if 'frame' in event.args and event.args['frame'] != main_frame:
99 continue 102 continue
100 if event_name in _TRACKED_EVENT_NAMES and event_name not in tracked_events: 103 if event_name in _TRACKED_EVENT_NAMES and event_name not in tracked_events:
101 logging.info('found url\'s event \'%s\'' % event_name) 104 logging.info('found url\'s event \'%s\'' % event_name)
102 tracked_events[event_name] = event 105 tracked_events[event_name] = event
103 assert len(tracked_events) == len(_TRACKED_EVENT_NAMES) 106 assert len(tracked_events) == len(_TRACKED_EVENT_NAMES)
104 return tracked_events 107 return tracked_events
105 108
106 109
107 def _PullMetricsFromTrace(trace): 110 def _PullMetricsFromLoadingTrace(loading_trace):
108 """Pulls all the metrics from a given trace. 111 """Pulls all the metrics from a given trace.
109 112
110 Args: 113 Args:
111 trace: The cached trace. 114 loading_trace: loading_trace_module.LoadingTrace.
112 115
113 Returns: 116 Returns:
114 Dictionary with all _CSV_FIELD_NAMES's field set (except the 'id'). 117 Dictionary with all _CSV_FIELD_NAMES's field set (except the 'id').
115 """ 118 """
116 browser_dump_events = _GetBrowserDumpEvents(trace) 119 browser_dump_events = _GetBrowserDumpEvents(loading_trace.tracing_track)
117 web_page_tracked_events = _GetWebPageTrackedEvents(trace) 120 web_page_tracked_events = _GetWebPageTrackedEvents(
121 loading_trace.tracing_track)
118 122
119 browser_malloc_sum = 0 123 browser_malloc_sum = 0
120 browser_malloc_max = 0 124 browser_malloc_max = 0
121 for dump_event in browser_dump_events: 125 for dump_event in browser_dump_events:
122 attr = dump_event['args']['dumps']['allocators']['malloc']['attrs']['size'] 126 attr = dump_event.args['dumps']['allocators']['malloc']['attrs']['size']
123 assert attr['units'] == 'bytes' 127 assert attr['units'] == 'bytes'
124 size = int(attr['value'], 16) 128 size = int(attr['value'], 16)
125 browser_malloc_sum += size 129 browser_malloc_sum += size
126 browser_malloc_max = max(browser_malloc_max, size) 130 browser_malloc_max = max(browser_malloc_max, size)
127 131
128 return { 132 return {
129 'total_load': (web_page_tracked_events['loadEventEnd']['ts'] - 133 'total_load': (web_page_tracked_events['loadEventEnd'].start_msec -
130 web_page_tracked_events['requestStart']['ts']), 134 web_page_tracked_events['requestStart'].start_msec),
131 'onload': (web_page_tracked_events['loadEventEnd']['ts'] - 135 'onload': (web_page_tracked_events['loadEventEnd'].start_msec -
132 web_page_tracked_events['loadEventStart']['ts']), 136 web_page_tracked_events['loadEventStart'].start_msec),
133 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)), 137 'browser_malloc_avg': browser_malloc_sum / float(len(browser_dump_events)),
134 'browser_malloc_max': browser_malloc_max 138 'browser_malloc_max': browser_malloc_max
135 } 139 }
136 140
137 141
138 def _PullMetricsFromOutputDirectory(output_directory_path): 142 def _PullMetricsFromOutputDirectory(output_directory_path):
139 """Pulls all the metrics from all the traces of a sandwich run directory. 143 """Pulls all the metrics from all the traces of a sandwich run directory.
140 144
141 Args: 145 Args:
142 output_directory_path: The sandwich run's output directory to pull the 146 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)): 159 if not os.path.isdir(os.path.join(output_directory_path, node_name)):
156 continue 160 continue
157 try: 161 try:
158 page_id = int(node_name) 162 page_id = int(node_name)
159 except ValueError: 163 except ValueError:
160 continue 164 continue
161 trace_path = os.path.join(output_directory_path, node_name, 'trace.json') 165 trace_path = os.path.join(output_directory_path, node_name, 'trace.json')
162 if not os.path.isfile(trace_path): 166 if not os.path.isfile(trace_path):
163 continue 167 continue
164 logging.info('processing \'%s\'' % trace_path) 168 logging.info('processing \'%s\'' % trace_path)
165 with open(trace_path) as trace_file: 169 loading_trace = loading_trace_module.LoadingTrace.FromJsonFile(trace_path)
166 trace = json.load(trace_file) 170 trace_metrics = _PullMetricsFromLoadingTrace(loading_trace)
167 trace_metrics = _PullMetricsFromTrace(trace) 171 trace_metrics['id'] = page_id
168 trace_metrics['id'] = page_id 172 trace_metrics['url'] = run_infos['urls'][page_id]
169 trace_metrics['url'] = run_infos['urls'][page_id] 173 metrics.append(trace_metrics)
170 metrics.append(trace_metrics)
171 assert len(metrics) > 0, ('Looks like \'{}\' was not a sandwich ' + 174 assert len(metrics) > 0, ('Looks like \'{}\' was not a sandwich ' +
172 'run directory.').format(output_directory_path) 175 'run directory.').format(output_directory_path)
173 return metrics 176 return metrics
174 177
175 178
176 def main(): 179 def main():
177 logging.basicConfig(level=logging.INFO) 180 logging.basicConfig(level=logging.INFO)
178 181
179 parser = argparse.ArgumentParser() 182 parser = argparse.ArgumentParser()
180 parser.add_argument('output', type=str, 183 parser.add_argument('output', type=str,
181 help='Output directory of run_sandwich.py command.') 184 help='Output directory of run_sandwich.py command.')
182 args = parser.parse_args() 185 args = parser.parse_args()
183 186
184 trace_metrics_list = _PullMetricsFromOutputDirectory(args.output) 187 trace_metrics_list = _PullMetricsFromOutputDirectory(args.output)
185 trace_metrics_list.sort(key=lambda e: e['id']) 188 trace_metrics_list.sort(key=lambda e: e['id'])
186 cs_file_path = os.path.join(args.output, 'trace_analysis.csv') 189 cs_file_path = os.path.join(args.output, 'trace_analysis.csv')
187 with open(cs_file_path, 'w') as csv_file: 190 with open(cs_file_path, 'w') as csv_file:
188 writer = csv.DictWriter(csv_file, fieldnames=_CSV_FIELD_NAMES) 191 writer = csv.DictWriter(csv_file, fieldnames=_CSV_FIELD_NAMES)
189 writer.writeheader() 192 writer.writeheader()
190 for trace_metrics in trace_metrics_list: 193 for trace_metrics in trace_metrics_list:
191 writer.writerow(trace_metrics) 194 writer.writerow(trace_metrics)
192 return 0 195 return 0
193 196
194 197
195 if __name__ == '__main__': 198 if __name__ == '__main__':
196 sys.exit(main()) 199 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/android/loading/loading_trace.py ('k') | tools/android/loading/pull_sandwich_metrics_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698