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

Side by Side Diff: build/android/pylib/device_stats_monitor.py

Issue 10783020: Add an activity monitor which profiles IO and CPU utilization. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed review comments Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2012 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
5 """Utilities for iotop/top style profiling for android."""
6
7 import collections
8 import json
9 import os
10 import subprocess
11 import sys
12 import urllib
13
14 import constants
15 import io_stats_parser
16
17
18 class DeviceStatsMonitor(object):
19 """Class for collecting device stats such as IO/CPU usage.
20
21 Args:
22 adb: Instance of AndroidComannds.
23 hz: Frequency at which to sample device stats.
24 """
25
26 DEVICE_PATH = '/data/local/tmp/device_stats_monitor'
27 HOST_PATH = os.path.abspath(os.path.join(
28 constants.CHROME_DIR, 'out', 'Release', 'device_stats_monitor'))
29 PROFILE_PATH = '/sdcard/Download/device_stats_monitor.profile'
30 RESULT_VIEWER_PATH = os.path.abspath(os.path.join(
31 os.path.dirname(os.path.realpath(__file__)), 'device_stats_monitor.html'))
32
33 def __init__(self, adb, hz):
34 self._adb = adb
35 self._adb.PushIfNeeded(DeviceStatsMonitor.HOST_PATH,
36 DeviceStatsMonitor.DEVICE_PATH)
37 self._hz = hz
38
39 def Start(self):
40 """Starts device stats monitor on the device."""
41 self._adb.SetFileContents(DeviceStatsMonitor.PROFILE_PATH, '')
42 self._process = subprocess.Popen(
43 ['adb', 'shell', '%s --hz=%d %s' % (
44 DeviceStatsMonitor.DEVICE_PATH, self._hz,
45 DeviceStatsMonitor.PROFILE_PATH)])
46
47 def StopAndCollect(self, output_path):
48 """Stops monitoring and saves results.
49
50 Args:
51 output_path: Path to save results.
52
53 Returns:
54 String of URL to load results in browser.
55 """
56 assert self._process
57 self._adb.KillAll(DeviceStatsMonitor.DEVICE_PATH)
58 self._process.wait()
59 profile = self._adb.GetFileContents(DeviceStatsMonitor.PROFILE_PATH)
60
61 results = collections.defaultdict(list)
62 last_io_stats = None
63 last_cpu_stats = None
64 for line in profile:
65 if ' mmcblk0 ' in line:
66 stats = io_stats_parser.ParseIoStatsLine(line)
67 if last_io_stats:
68 results['sectors_read'].append(stats.num_sectors_read -
69 last_io_stats.num_sectors_read)
70 results['sectors_written'].append(stats.num_sectors_written -
71 last_io_stats.num_sectors_written)
72 last_io_stats = stats
73 elif line.startswith('cpu '):
74 stats = self._ParseCpuStatsLine(line)
75 if last_cpu_stats:
76 results['user'].append(stats.user - last_cpu_stats.user)
77 results['nice'].append(stats.nice - last_cpu_stats.nice)
78 results['system'].append(stats.system - last_cpu_stats.system)
79 results['idle'].append(stats.idle - last_cpu_stats.idle)
80 results['iowait'].append(stats.iowait - last_cpu_stats.iowait)
81 results['irq'].append(stats.irq - last_cpu_stats.irq)
82 results['softirq'].append(stats.softirq- last_cpu_stats.softirq)
83 last_cpu_stats = stats
84 units = {
85 'sectors_read': 'sectors',
86 'sectors_written': 'sectors',
87 'user': 'jiffies',
88 'nice': 'jiffies',
89 'system': 'jiffies',
90 'idle': 'jiffies',
91 'iowait': 'jiffies',
92 'irq': 'jiffies',
93 'softirq': 'jiffies',
94 }
95 with open(output_path, 'w') as f:
96 f.write('display(%d, %s, %s);' % (self._hz, json.dumps(results), units))
97 return 'file://%s?results=file://%s' % (
98 DeviceStatsMonitor.RESULT_VIEWER_PATH, urllib.quote(output_path))
99
100
101 @staticmethod
102 def _ParseCpuStatsLine(line):
103 """Parses a line of cpu stats into a CpuStats named tuple."""
104 # Field definitions: http://www.linuxhowtos.org/System/procstat.htm
105 cpu_stats = collections.namedtuple('CpuStats',
106 ['device',
107 'user',
108 'nice',
109 'system',
110 'idle',
111 'iowait',
112 'irq',
113 'softirq',
114 ])
115 fields = line.split()
116 return cpu_stats._make([fields[0]] + [int(f) for f in fields[1:8]])
OLDNEW
« no previous file with comments | « build/android/pylib/device_stats_monitor.html ('k') | build/android/pylib/test_options_parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698