OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Launches a daemon to monitor android device temperaures. |
| 7 |
| 8 This script will repeatedly poll the given devices for their |
| 9 temperatures every 60 seconds via adb and uploads them for monitoring |
| 10 through infra's ts_mon. |
| 11 """ |
| 12 |
| 13 import json |
| 14 import logging |
| 15 import os |
| 16 import optparse |
| 17 import re |
| 18 import signal |
| 19 import subprocess |
| 20 import sys |
| 21 import time |
| 22 |
| 23 # Common name of sensor found in nexus devices to measure cpu (core0) temp. |
| 24 _CPU_TEMP_SENSOR = 'tsens_tz_sensor0' |
| 25 |
| 26 # TODO(bpastene): change the following if infra.git becomes a checked |
| 27 # out repo on slaves instead of a cipd managed package. |
| 28 |
| 29 # Location of the infra-python package's run script. |
| 30 _RUN_PY = '/opt/infra-python/run.py' |
| 31 |
| 32 |
| 33 def get_device_args(adb_path, slave_name, device): |
| 34 bat_temp = None |
| 35 cpu_temp = None |
| 36 # Search for the file that the _CPU_TEMP_SENSOR dumps to and cat it. |
| 37 cmd = [adb_path, '-s', device, 'shell', |
| 38 'grep -l "%s" /sys/class/thermal/thermal_zone*/type' |
| 39 % (_CPU_TEMP_SENSOR)] |
| 40 try: |
| 41 cpu_temp_files = subprocess.check_output(cmd) |
| 42 if (len(cpu_temp_files.splitlines()) == 1): |
| 43 cpu_temp_file = re.sub('type$', 'temp', cpu_temp_files.strip()) |
| 44 cmd = [adb_path, '-s', device, 'shell', |
| 45 'cat %s' % (cpu_temp_file)] |
| 46 file_contents = subprocess.check_output(cmd) |
| 47 cpu_temp = int(file_contents) |
| 48 except (subprocess.CalledProcessError, TypeError, ValueError): |
| 49 cpu_temp = None |
| 50 |
| 51 # Dump system battery info and grab the temp. |
| 52 cmd = [adb_path, '-s', device, 'shell', 'dumpsys battery'] |
| 53 try: |
| 54 battery_info = subprocess.check_output(cmd) |
| 55 for line in battery_info.splitlines(): |
| 56 m = re.match('^\s*temperature: ([0-9]+)\s*$', line) |
| 57 if m: |
| 58 bat_temp = int(m.group(1)) |
| 59 except (subprocess.CalledProcessError, TypeError, ValueError): |
| 60 bat_temp = None |
| 61 |
| 62 cpu_dict = {'name': "dev/cpu/temperature", |
| 63 'value': cpu_temp, |
| 64 'device_id': device, |
| 65 'slave': slave_name} |
| 66 cpu_temp_args = ['--float', json.dumps(cpu_dict)] if cpu_temp else [] |
| 67 battery_dict = {'name': 'dev/battery/temperature', |
| 68 'value': bat_temp, |
| 69 'device_id': device, |
| 70 'slave': slave_name} |
| 71 bat_temp_args = ['--float', |
| 72 json.dumps(battery_dict)] if bat_temp else [] |
| 73 return cpu_temp_args + bat_temp_args |
| 74 |
| 75 |
| 76 def main(adb_path, |
| 77 devices_json, |
| 78 slave_name): |
| 79 """Launches the device temperature monitor. |
| 80 |
| 81 Polls the devices for their battery and cpu temperatures |
| 82 every 60 seconds and uploads them for monitoring through infra's |
| 83 ts_mon. Fully qualified, the metric names would be |
| 84 /chrome/infra/dev/(cpu|battery)/temperature |
| 85 |
| 86 Args: |
| 87 adb_path: Path to adb binary. |
| 88 devices_json: Json list of device serials to poll. |
| 89 slave_name: Name of the buildbot slave. |
| 90 """ |
| 91 |
| 92 devices = json.loads(devices_json) |
| 93 while True: |
| 94 upload_cmd_args = [] |
| 95 for device in devices: |
| 96 upload_cmd_args += get_device_args(adb_path, slave_name, device) |
| 97 |
| 98 cmd = [_RUN_PY, 'infra.tools.send_ts_mon_values'] + upload_cmd_args |
| 99 try: |
| 100 subprocess.Popen(cmd) |
| 101 except OSError: |
| 102 logging.exception('Unable to call %s', _RUN_PY) |
| 103 |
| 104 time.sleep(60) |
| 105 |
| 106 |
| 107 if __name__ == '__main__': |
| 108 sys.exit(main(*sys.argv[1:])) |
OLD | NEW |