blob: 4f38afc65d39c8befdddb40b8cba04f9f744dc3d [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2014 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.
# This file defines script for getting host_history for DUTs in Autotest.
"""Script for checking host history for a selected group of hosts.
Currently only supports aggregating stats for each host.
Example usage:
python host_history.py --index=cautotest -n 10000 \
-l 24 --board=daisy
Output:
trying to get all duts...
making the query...
found all duts. Time to get host_history.
usage stats for host: chromeos2-row5-rack1-host6
2014-07-24 10:24:07 - 2014-07-25 10:24:07
Verifying: 0.00 %
Running: 0.00 %
Ready: 100.00 %
Repairing: 0.00 %
Repair Failed: 0.00 %
Cleaning: 0.00 %
Pending: 0.00 %
Resetting: 0.00 %
Provisioning: 0.00 %
Locked: 0.00 %
- -- --- ---- ----- ---- --- -- -
Example usage2: more than one host:
python host_history.py --index=cautotest -n 1000 -l 2 \
--hosts chromeos2-row5-rack4-host6 chromeos4-row12-rack11-host2
['chromeos2-row5-rack4-host6', 'chromeos4-row12-rack11-host2']
found all duts. Time to get host_history.
usage stats for host: chromeos2-row5-rack4-host6
2014-07-25 13:02:22 - 2014-07-25 15:02:22
Num entries found in this interval: 0
Verifying: 0.00 %
Running: 0.00 %
Ready: 100.00 %
Repairing: 0.00 %
Repair Failed: 0.00 %
Cleaning: 0.00 %
Pending: 0.00 %
Resetting: 0.00 %
Provisioning: 0.00 %
Locked: 0.00 %
- -- --- ---- ----- ---- --- -- -
usage stats for host: chromeos4-row12-rack11-host2
2014-07-25 13:02:22 - 2014-07-25 15:02:22
Num entries found in this interval: 138
Verifying: 0.00 %
Running: 70.45 %
Ready: 17.79 %
Repairing: 0.00 %
Repair Failed: 0.00 %
Cleaning: 0.00 %
Pending: 1.24 %
Resetting: 10.78 %
Provisioning: 0.00 %
Locked: 0.00 %
- -- --- ---- ----- ---- --- -- -
"""
import argparse
import datetime
import multiprocessing
import multiprocessing.pool
import time
import traceback
import common
from autotest_lib.client.common_lib.cros.graphite import es_utils
from autotest_lib.server import frontend
from autotest_lib.site_utils import host_history_utils
def should_care(board, pool, dut):
"""Whether we should care to print stats for this dut out
@param board: board we want, i.e. 'daisy'
@param pool: pool we want, i.e. 'bvt'
@param dut: Host object representing DUT.
@returns: True if the dut's stats should be counted.
"""
if not board and not pool:
return True
found_board = False if board else True
found_pool = False if pool else True
for label in dut.labels:
if label.startswith('pool:%s' % (pool)):
found_pool = True
if label.startswith('board:%s' % (board)):
found_board = True
return found_board and found_pool
def print_all_stats(results, labels, t_start, t_end):
"""Prints overall stats followed by stats for each host.
@param results: A list of tuples of two elements.
1st element: String representing report for individual host.
2nd element: An ordered dictionary with
key being (ti, tf) and value being (status, dbg_str)
status = status of the host. e.g. 'Repair Failed'
ti is the beginning of the interval where the DUT's has that status
tf is the end of the interval where the DUT has that status
dbg_str is the self.dbg_str from the host. An example would be:
'Special Task 18858263 (host 172.22.169.106,
task Repair,
time 2014-07-27 20:01:15)'
@param labels: A list of labels useful for describing the group
of hosts these overall stats represent.
@param t_start: beginning of time period we are interested in.
@param t_end: end of time period we are interested in.
"""
result_strs, stat_intervals_lst = zip(*results)
overall_report_str = host_history_utils.get_overall_report(
labels, t_start, t_end, stat_intervals_lst)
# Print the overall stats
print overall_report_str
# Print the stats for each individual host.
for result_str in result_strs:
print result_str
def get_host_history(input):
"""Gets the host history.
@param input: A dictionary of input arguments to
host_history_utils.host_history_stats.
Must contain these keys:
't_start',
't_end',
'hostname',
'size,'
'print_each_interval'
@returns:
result_str: String reporting history for specific host.
stat_intervals: A ordered dictionary with
key being (ti, tf) and value being (status, dbg_str)
status = status of the host. e.g. 'Repair Failed'
ti is the beginning of the interval where the DUT's has that status
tf is the end of the interval where the DUT has that status
dbg_str is the self.dbg_str from the host. An example would be:
'Special Task 18858263 (host 172.22.169.106,
task Repair,
time 2014-07-27 20:01:15)'
"""
try:
result_str, stat_intervals = host_history_utils.get_report_for_host(
t_start=input['t_start'],
t_end=input['t_end'],
hostname=input['hostname'],
size=input['size'],
print_each_interval=input['print_each_interval'],
index=input['index'])
return result_str, stat_intervals
except Exception as e:
# Incase any process throws an Exception, we want to see it.
print traceback.print_exc()
return None, None
def main():
"""main script. """
t_now = time.time()
t_now_minus_one_day = t_now - 3600 * 24
parser = argparse.ArgumentParser()
parser.add_argument('--index', type=str, dest='index',
help='Enter ES index name, such as "cautotest"')
parser.add_argument('-v', action='store_true', dest='verbose',
default=False,
help='-v to print out ALL entries.')
parser.add_argument('-n', type=int, dest='size',
help='Maximum number of entries to return.',
default=10000)
parser.add_argument('-l', type=float, dest='last',
help='last hours to search results across',
default=None)
parser.add_argument('--board', type=str, dest='board',
help='restrict query by board, not implemented yet',
default=None)
parser.add_argument('--pool', type=str, dest='pool',
help='restrict query by pool, not implemented yet',
default=None)
parser.add_argument('--hosts', nargs='+', dest='hosts',
help='Enter space deliminated hostnames',
default=[])
parser.add_argument('--start', type=str, dest='start',
help=('Enter start time as: yyyy-mm-dd hh-mm-ss,'
'defualts to 24h ago.'),
default=host_history_utils.unix_time_to_readable_date(
t_now_minus_one_day))
parser.add_argument('--end', type=str, dest='end',
help=('Enter end time in as: yyyy-mm-dd hh-mm-ss,'
'defualts to current time.'),
default=host_history_utils.unix_time_to_readable_date(
t_now))
options = parser.parse_args()
if options.last:
t_start = t_now - 3600 * options.last
t_end = t_now
else:
t_start = es_utils._to_epoch_time(datetime.datetime.strptime(
options.start, '%Y-%m-%d %H:%M:%S'))
t_end = es_utils._to_epoch_time(datetime.datetime.strptime(
options.end, '%Y-%m-%d %H:%M:%S'))
if options.hosts:
hosts = options.hosts
else:
hosts = []
print 'trying to get all duts...'
afe = frontend.AFE()
print 'making the query...'
duts = afe.get_hosts()
for dut in duts:
if should_care(options.board, options.pool, dut):
hosts.append(dut.hostname)
print 'found all duts. Time to get host_history.'
args = []
for hostname in hosts:
args.append({'t_start': t_start,
't_end': t_end,
'hostname': hostname,
'size': options.size,
'print_each_interval': options.verbose,
'index': options.index})
# Parallizing this process.
pool = multiprocessing.pool.ThreadPool()
results = pool.imap_unordered(get_host_history, args)
time.sleep(3)
labels = []
if options.board:
labels.append('board:%s' % (options.board))
if options.pool:
labels.append('pool:%s' % (options.pool))
print_all_stats(results, labels, t_start, t_end)
if __name__ == '__main__':
main()