#!/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 -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 -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 time
import traceback
import common
from autotest_lib.client.common_lib import time_utils
from autotest_lib.site_utils import host_history_utils
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 three elements.
1st element: String representing report for individual host.
2nd element: An ordered dictionary with
key as (t_start, t_end) and value as (status, metadata)
status = status of the host. e.g. 'Repair Failed'
t_start is the beginning of the interval where the DUT's has
that status
t_end is the end of the interval where the DUT has that
status
metadata: A dictionary of other metadata, e.g.,
{'task_id':123, 'task_name':'Reset'}
3rd element: hostname of the dut.
@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, hostname = 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 as (t_start, t_end) and value as (status, metadata)
status = status of the host. e.g. 'Repair Failed'
t_start is the beginning of the interval where the DUT's has
that status
t_end is the end of the interval where the DUT has that
status
metadata: A dictionary of other metadata, e.g.,
{'task_id':123, 'task_name':'Reset'}
"""
try:
result_str, stat_intervals = host_history_utils.get_report_for_host(
**input)
return result_str, stat_intervals, input['hostname']
except Exception as e:
# In case any process throws an Exception, we want to see it.
print traceback.print_exc()
return None, None, None
def get_results(start_time, end_time, hosts=None, board=None, pool=None,
verbose=False):
"""Get history results of specified hosts or board/pool.
If hosts is set to None, all hosts are used, filtered by the board and pool
constraints. If board is not provided, all boards are included. If pool is
not provided, all pools are included.
If a list of hosts is provided, the board and pool constraints are ignored.
@param hosts: A list of hosts to search for history. Default is None.
@param board: board type of hosts. Default is None.
@param pool: pool type of hosts. Default is None.
@param start_time: start time to search for history, can be string value or
epoch time.
@param end_time: end time to search for history, can be string value or
epoch time.
@param verbose: True to print out detail intervals of host history.
@returns: A dictionary of host history.
"""
assert start_time and end_time
start_time = time_utils.to_epoch_time(start_time)
end_time = time_utils.to_epoch_time(end_time)
assert start_time < end_time
return host_history_utils.get_report(t_start=start_time, t_end=end_time,
hosts=hosts, board=board, pool=pool,
print_each_interval=verbose)
def get_history_details(start_time, end_time, hosts=None, board=None,
pool=None):
"""Get the details of host history.
The return is a dictionary of host history for each host, for example,
{'172.22.33.51': [{'status': 'Resetting'
'start_time': '2014-08-07 10:02:16',
'end_time': '2014-08-07 10:03:16',
'log_url': 'http://autotest/reset-546546/debug',
'task_id': 546546},
{'status': 'Running'
'start_time': '2014-08-07 10:03:18',
'end_time': '2014-08-07 10:13:00',
'log_url': ('http://%s/tko/retrieve_logs.cgi?job=/'
'results/16853-debug/172.22.33.51'),
'job_id': 16853}
]
}
@param start_time: start time to search for history, can be string value or
epoch time.
@param end_time: end time to search for history, can be string value or
epoch time.
@param hosts: A list of hosts to search for history. Default is None.
@param board: board type of hosts. Default is None.
@param pool: pool type of hosts. Default is None.
@returns: A dictionary of the host history details.
"""
results = get_results(start_time=start_time, end_time=end_time, hosts=hosts,
board=board, pool=pool)
if not results:
# No host found.
return None
all_history = {}
for result_str, status_intervals, hostname in results:
if hostname:
all_history[hostname] = host_history_utils.build_history(
hostname, status_intervals)
return all_history
def main():
"""main script. """
t_now = time.time()
t_now_minus_one_day = t_now - 3600 * 24
parser = argparse.ArgumentParser()
parser.add_argument('-v', action='store_true', dest='verbose',
default=False,
help='-v to print out ALL entries.')
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=time_utils.epoch_time_to_date_string(
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=time_utils.epoch_time_to_date_string(t_now))
options = parser.parse_args()
if options.last:
start_time = t_now - 3600 * options.last
end_time = t_now
else:
start_time = time_utils.to_epoch_time(options.start)
end_time = time_utils.to_epoch_time(options.end)
results = get_results(hosts=options.hosts,
board=options.board,
pool=options.pool,
start_time=start_time,
end_time=end_time,
verbose=options.verbose)
labels = []
if options.board:
labels.append('board:%s' % (options.board))
if options.pool:
labels.append('pool:%s' % (options.pool))
print_all_stats(results, labels, start_time, end_time)
if __name__ == '__main__':
main()