| #!/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() |