OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2014 The Chromium Authors. All rights reserved. | 3 # Copyright 2014 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 import logging | 7 import logging |
8 import optparse | 8 import optparse |
9 import os | 9 import os |
10 import sys | 10 import sys |
11 import webbrowser | 11 import webbrowser |
12 | 12 |
13 from chrome_profiler import chrome_controller | 13 from chrome_profiler import chrome_controller |
| 14 from chrome_profiler import perf_controller |
14 from chrome_profiler import profiler | 15 from chrome_profiler import profiler |
15 from chrome_profiler import systrace_controller | 16 from chrome_profiler import systrace_controller |
16 from chrome_profiler import ui | 17 from chrome_profiler import ui |
17 | 18 |
18 from pylib import android_commands | 19 from pylib import android_commands |
19 from pylib.device import device_utils | 20 from pylib.device import device_utils |
20 | 21 |
21 | 22 |
22 _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' | 23 _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' |
23 | 24 |
(...skipping 14 matching lines...) Expand all Loading... |
38 categories += options.chrome_categories.split(',') | 39 categories += options.chrome_categories.split(',') |
39 return categories | 40 return categories |
40 | 41 |
41 | 42 |
42 def _ComputeSystraceCategories(options): | 43 def _ComputeSystraceCategories(options): |
43 if not options.systrace_categories: | 44 if not options.systrace_categories: |
44 return [] | 45 return [] |
45 return options.systrace_categories.split(',') | 46 return options.systrace_categories.split(',') |
46 | 47 |
47 | 48 |
| 49 def _ComputePerfCategories(options): |
| 50 if not options.perf_categories: |
| 51 return [] |
| 52 return options.perf_categories.split(',') |
| 53 |
| 54 |
| 55 def _OptionalValueCallback(default_value): |
| 56 def callback(option, _, __, parser): |
| 57 value = default_value |
| 58 if parser.rargs and not parser.rargs[0].startswith('-'): |
| 59 value = parser.rargs.pop(0) |
| 60 setattr(parser.values, option.dest, value) |
| 61 return callback |
| 62 |
| 63 |
48 def _CreateOptionParser(): | 64 def _CreateOptionParser(): |
49 parser = optparse.OptionParser(description='Record about://tracing profiles ' | 65 parser = optparse.OptionParser(description='Record about://tracing profiles ' |
50 'from Android browsers. See http://dev.' | 66 'from Android browsers. See http://dev.' |
51 'chromium.org/developers/how-tos/trace-event-' | 67 'chromium.org/developers/how-tos/trace-event-' |
52 'profiling-tool for detailed instructions for ' | 68 'profiling-tool for detailed instructions for ' |
53 'profiling.') | 69 'profiling.') |
54 | 70 |
55 timed_options = optparse.OptionGroup(parser, 'Timed tracing') | 71 timed_options = optparse.OptionGroup(parser, 'Timed tracing') |
56 timed_options.add_option('-t', '--time', help='Profile for N seconds and ' | 72 timed_options.add_option('-t', '--time', help='Profile for N seconds and ' |
57 'download the resulting trace.', metavar='N', | 73 'download the resulting trace.', metavar='N', |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 systrace_opts = optparse.OptionGroup(parser, 'Systrace tracing options') | 113 systrace_opts = optparse.OptionGroup(parser, 'Systrace tracing options') |
98 systrace_opts.add_option('-s', '--systrace', help='Capture a systrace with ' | 114 systrace_opts.add_option('-s', '--systrace', help='Capture a systrace with ' |
99 'the chosen comma-delimited systrace categories. You ' | 115 'the chosen comma-delimited systrace categories. You ' |
100 'can also capture a combined Chrome + systrace by ' | 116 'can also capture a combined Chrome + systrace by ' |
101 'enable both types of categories. Use "list" to see ' | 117 'enable both types of categories. Use "list" to see ' |
102 'the available categories. Systrace is disabled by ' | 118 'the available categories. Systrace is disabled by ' |
103 'default.', metavar='SYS_CATEGORIES', | 119 'default.', metavar='SYS_CATEGORIES', |
104 dest='systrace_categories', default='') | 120 dest='systrace_categories', default='') |
105 parser.add_option_group(systrace_opts) | 121 parser.add_option_group(systrace_opts) |
106 | 122 |
| 123 if perf_controller.PerfProfilerController.IsSupported(): |
| 124 perf_opts = optparse.OptionGroup(parser, 'Perf profiling options') |
| 125 perf_opts.add_option('-p', '--perf', help='Capture a perf profile with ' |
| 126 'the chosen comma-delimited event categories. ' |
| 127 'Samples CPU cycles by default. Use "list" to see ' |
| 128 'the available sample types.', action='callback', |
| 129 default='', callback=_OptionalValueCallback('cycles'), |
| 130 metavar='PERF_CATEGORIES', dest='perf_categories') |
| 131 parser.add_option_group(perf_opts) |
| 132 |
107 output_options = optparse.OptionGroup(parser, 'Output options') | 133 output_options = optparse.OptionGroup(parser, 'Output options') |
108 output_options.add_option('-o', '--output', help='Save trace output to file.') | 134 output_options.add_option('-o', '--output', help='Save trace output to file.') |
109 output_options.add_option('--json', help='Save trace as raw JSON instead of ' | 135 output_options.add_option('--json', help='Save trace as raw JSON instead of ' |
110 'HTML.', action='store_true') | 136 'HTML.', action='store_true') |
111 output_options.add_option('--view', help='Open resulting trace file in a ' | 137 output_options.add_option('--view', help='Open resulting trace file in a ' |
112 'browser.', action='store_true') | 138 'browser.', action='store_true') |
113 parser.add_option_group(output_options) | 139 parser.add_option_group(output_options) |
114 | 140 |
115 browsers = sorted(profiler.GetSupportedBrowsers().keys()) | 141 browsers = sorted(profiler.GetSupportedBrowsers().keys()) |
116 parser.add_option('-b', '--browser', help='Select among installed browsers. ' | 142 parser.add_option('-b', '--browser', help='Select among installed browsers. ' |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 ui.PrintMessage('\n'.join('\t%s' % item \ | 188 ui.PrintMessage('\n'.join('\t%s' % item \ |
163 for item in sorted(disabled_by_default_categories))) | 189 for item in sorted(disabled_by_default_categories))) |
164 | 190 |
165 return 0 | 191 return 0 |
166 | 192 |
167 if options.systrace_categories in ['list', 'help']: | 193 if options.systrace_categories in ['list', 'help']: |
168 ui.PrintMessage('\n'.join( | 194 ui.PrintMessage('\n'.join( |
169 systrace_controller.SystraceController.GetCategories(device))) | 195 systrace_controller.SystraceController.GetCategories(device))) |
170 return 0 | 196 return 0 |
171 | 197 |
| 198 if options.perf_categories in ['list', 'help']: |
| 199 ui.PrintMessage('\n'.join( |
| 200 perf_controller.PerfProfilerController.GetCategories(device))) |
| 201 return 0 |
| 202 |
172 if not options.time and not options.continuous: | 203 if not options.time and not options.continuous: |
173 ui.PrintMessage('Time interval or continuous tracing should be specified.') | 204 ui.PrintMessage('Time interval or continuous tracing should be specified.') |
174 return 1 | 205 return 1 |
175 | 206 |
176 chrome_categories = _ComputeChromeCategories(options) | 207 chrome_categories = _ComputeChromeCategories(options) |
177 systrace_categories = _ComputeSystraceCategories(options) | 208 systrace_categories = _ComputeSystraceCategories(options) |
| 209 perf_categories = _ComputePerfCategories(options) |
178 | 210 |
179 if chrome_categories and 'webview' in systrace_categories: | 211 if chrome_categories and 'webview' in systrace_categories: |
180 logging.warning('Using the "webview" category in systrace together with ' | 212 logging.warning('Using the "webview" category in systrace together with ' |
181 'Chrome tracing results in duplicate trace events.') | 213 'Chrome tracing results in duplicate trace events.') |
182 | 214 |
183 enabled_controllers = [] | 215 enabled_controllers = [] |
184 if chrome_categories: | 216 if chrome_categories: |
185 enabled_controllers.append( | 217 enabled_controllers.append( |
186 chrome_controller.ChromeTracingController(device, | 218 chrome_controller.ChromeTracingController(device, |
187 package_info, | 219 package_info, |
188 chrome_categories, | 220 chrome_categories, |
189 options.ring_buffer, | 221 options.ring_buffer, |
190 options.trace_memory)) | 222 options.trace_memory)) |
191 if systrace_categories: | 223 if systrace_categories: |
192 enabled_controllers.append( | 224 enabled_controllers.append( |
193 systrace_controller.SystraceController(device, | 225 systrace_controller.SystraceController(device, |
194 systrace_categories, | 226 systrace_categories, |
195 options.ring_buffer)) | 227 options.ring_buffer)) |
196 | 228 |
| 229 if perf_categories: |
| 230 enabled_controllers.append( |
| 231 perf_controller.PerfProfilerController(device, |
| 232 perf_categories)) |
| 233 |
197 if not enabled_controllers: | 234 if not enabled_controllers: |
198 ui.PrintMessage('No trace categories enabled.') | 235 ui.PrintMessage('No trace categories enabled.') |
199 return 1 | 236 return 1 |
200 | 237 |
201 if options.output: | 238 if options.output: |
202 options.output = os.path.expanduser(options.output) | 239 options.output = os.path.expanduser(options.output) |
203 result = profiler.CaptureProfile( | 240 result = profiler.CaptureProfile( |
204 enabled_controllers, | 241 enabled_controllers, |
205 options.time if not options.continuous else 0, | 242 options.time if not options.continuous else 0, |
206 output=options.output, | 243 output=options.output, |
207 compress=options.compress, | 244 compress=options.compress, |
208 write_json=options.json) | 245 write_json=options.json) |
209 if options.view: | 246 if options.view: |
210 if sys.platform == 'darwin': | 247 if sys.platform == 'darwin': |
211 os.system('/usr/bin/open %s' % os.path.abspath(result)) | 248 os.system('/usr/bin/open %s' % os.path.abspath(result)) |
212 else: | 249 else: |
213 webbrowser.open(result) | 250 webbrowser.open(result) |
214 | |
215 | |
216 if __name__ == '__main__': | |
217 sys.exit(main()) | |
OLD | NEW |