blob: 73d5e94ac6d328e0f8384f400ee7cd7dc17190a8 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import logging
import time
import factory_common # pylint: disable=W0611
from cros.factory import system
from cros.factory.test import factory
from cros.factory.utils import process_utils
class CPUUsageMonitor(object):
# Lines of header from 'top'.
HEADER_LINES = 6
# Maximum number of characters reported for a command.
COMMAND_LENGTH = 64
# Maximum number of processes reported.
NUM_TOP_PROCESSES = 3
# Only reports processes with CPU usage exceeding this threshold.
CPU_THRESHOLD = 10
def __init__(self, period_secs):
self._period_secs = period_secs
factory.init_logging()
def _GetLoadString(self):
return ', '.join('%.1f' % load for load in system.SystemStatus().load_avg)
def Check(self):
"""Checks the current CPU usage status.
Logs current load average and top three processes that use more than 10%
CPU.
"""
msg = []
try:
msg.append('Load average: %s' % self._GetLoadString())
# Get column legend from 'top' and throw away summary header and legend
top_output = process_utils.CheckOutput(
['top', '-b', '-c', '-n', '1']).split('\n')
column_ids = top_output[self.HEADER_LINES].split()
pid_column = column_ids.index('PID')
cpu_column = column_ids.index('%CPU')
command_column = column_ids.index('COMMAND')
top_output = top_output[self.HEADER_LINES + 1:]
# Find up to NUM_TOP_PROCESSES processes with CPU usage >= CPU_THRESHOLD
for process in top_output[0:self.NUM_TOP_PROCESSES]:
attr = process.split()
if float(attr[cpu_column]) < self.CPU_THRESHOLD:
break
command = ' '.join(attr[command_column:])[0:self.COMMAND_LENGTH]
msg.append('Process %s using %s%% CPU: %s' %
(attr[pid_column], attr[cpu_column], command))
except: # pylint: disable=W0702
logging.exception('Unable to check CPU usage')
else:
logging.info('; '.join(msg))
def CheckForever(self):
while True:
self.Check()
time.sleep(self._period_secs)
def main():
parser = argparse.ArgumentParser(description='Monitor CPU usage')
parser.add_argument('--period_secs', '-p', help='Interval between checks',
type=int, required=False, default=120)
args = parser.parse_args()
monitor = CPUUsageMonitor(args.period_secs)
monitor.CheckForever()
if __name__ == '__main__':
main()