1# Copyright 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import collections 6 7from telemetry.core import exceptions 8 9class Profiler(object): 10 """A sampling profiler provided by the platform. 11 12 A profiler is started on its constructor, and should 13 gather data until CollectProfile(). 14 The life cycle is normally tied to a single page, 15 i.e., multiple profilers will be created for a page set. 16 WillCloseBrowser() is called right before the browser 17 is closed to allow any further cleanup. 18 """ 19 20 def __init__(self, browser_backend, platform_backend, output_path, state): 21 self._browser_backend = browser_backend 22 self._platform_backend = platform_backend 23 self._output_path = output_path 24 self._state = state 25 26 @classmethod 27 def name(cls): 28 """User-friendly name of this profiler.""" 29 raise NotImplementedError() 30 31 @classmethod 32 def is_supported(cls, browser_type): 33 """True iff this profiler is currently supported by the platform.""" 34 raise NotImplementedError() 35 36 @classmethod 37 def CustomizeBrowserOptions(cls, browser_type, options): 38 """Override to customize the Browser's options before it is created.""" 39 pass 40 41 @classmethod 42 def WillCloseBrowser(cls, browser_backend, platform_backend): 43 """Called before the browser is stopped.""" 44 pass 45 46 def _GetProcessOutputFileMap(self): 47 """Returns a dict with pid: output_file.""" 48 all_pids = ([self._browser_backend.pid] + 49 self._platform_backend.GetChildPids(self._browser_backend.pid)) 50 51 process_name_counts = collections.defaultdict(int) 52 process_output_file_map = {} 53 for pid in all_pids: 54 try: 55 cmd_line = self._platform_backend.GetCommandLine(pid) 56 process_name = self._browser_backend.GetProcessName(cmd_line) 57 output_file = '%s.%s%s' % (self._output_path, process_name, 58 process_name_counts[process_name]) 59 process_name_counts[process_name] += 1 60 process_output_file_map[pid] = output_file 61 except exceptions.ProcessGoneException: 62 # Ignore processes that disappeared since calling GetChildPids(). 63 continue 64 return process_output_file_map 65 66 def CollectProfile(self): 67 """Collect the profile from the profiler.""" 68 raise NotImplementedError() 69