Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| 4 | # Use of this source code is governed by a BSD-style license that can be |
| 5 | # found in the LICENSE file. |
| 6 | |
| 7 | # This file defines script for getting entries from ES concerning reboot time. |
| 8 | |
| 9 | """ |
| 10 | Example usage: |
| 11 | python analyze_reboot_time.py -l 12 --server cautotest --board daisy_spring |
| 12 | |
| 13 | Usage: analyze_reboot_time.py [-h] [-l LAST] --server AUTOTEST_SERVER |
| 14 | [--board BOARD] [--pool POOL] [--start START] |
| 15 | [--end END] [--gte GTE] [--lte LTE] [-n SIZE] |
| 16 | [--hosts HOSTS [HOSTS ...]] |
| 17 | |
| 18 | optional arguments: |
| 19 | -h, --help show this help message and exit |
| 20 | -l LAST last hours to search results across |
| 21 | --server AUTOTEST_SERVER |
| 22 | Enter Autotest instance name, e.g. "cautotest". |
| 23 | --board BOARD restrict query by board, not implemented yet |
| 24 | --pool POOL restrict query by pool, not implemented yet |
| 25 | --start START Enter start time as: yyyy-mm-dd hh-mm-ss,defualts to |
| 26 | 24h ago. |
| 27 | --end END Enter end time as: yyyy-mm-dd hh-mm-ss,defualts to |
| 28 | current time. |
| 29 | --gte GTE Enter lower bound on reboot time for entries to |
| 30 | return. |
| 31 | --lte LTE Enter upper bound on reboot time for entries to |
| 32 | return. |
| 33 | -n SIZE Maximum number of entries to return. |
| 34 | --hosts HOSTS [HOSTS ...] |
| 35 | Enter space deliminated hostnames |
| 36 | """ |
| 37 | |
| 38 | import argparse |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 39 | import time |
| 40 | |
| 41 | import common |
Dan Shi | dfea368 | 2014-08-10 23:38:40 -0700 | [diff] [blame] | 42 | import host_history |
| 43 | from autotest_lib.client.common_lib import time_utils |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 44 | from autotest_lib.client.common_lib.cros.graphite import es_utils |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 45 | |
| 46 | |
| 47 | def get_entries(time_start, time_end, gte, lte, size, index, hostname): |
| 48 | """Gets all entries from es db with the given constraints. |
| 49 | |
| 50 | @param time_start: Earliest time entry was recorded |
| 51 | @param time_end: Latest time entry was recorded |
| 52 | @param gte: Lowest reboot_time to return |
| 53 | @param lte: Highest reboot_time to return |
| 54 | @param size: Max number of entries to return |
| 55 | @param index: es db index to get entries for, i.e. 'cautotest' |
| 56 | @param hostname: string representing hostname to query for |
| 57 | @returns: Entries from esdb. |
| 58 | """ |
| 59 | query = es_utils.create_range_eq_query_multiple( |
| 60 | fields_returned=['hostname', 'time_recorded', 'value'], |
| 61 | equality_constraints=[('_type', 'reboot_total'), |
| 62 | ('hostname', hostname)], |
| 63 | range_constraints=[('time_recorded', time_start, time_end), |
| 64 | ('value', gte, lte)], |
| 65 | size=size, |
| 66 | sort_specs=[{'hostname': 'asc'}, {'value': 'desc'}]) |
| 67 | results = es_utils.execute_query(query, index=index, |
| 68 | host=es_utils.METADATA_ES_SERVER, |
| 69 | port=es_utils.ES_PORT) |
| 70 | return results |
| 71 | |
| 72 | |
| 73 | def get_results_string(hostname, time_start, time_end, results): |
| 74 | """Prints entries from esdb in a readable fashion. |
| 75 | |
| 76 | @param hostname: Hostname of DUT we are printing result for. |
| 77 | @param time_start: Earliest time entry was recorded |
| 78 | @param time_end: Latest time entry was recorded |
| 79 | @param gte: Lowest reboot_time to return |
| 80 | @param lte: Highest reboot_time to return |
| 81 | @param size: Max number of entries to return |
| 82 | @returns: String reporting reboot times for this host. |
| 83 | """ |
| 84 | num_entries = results['hits']['total'] |
| 85 | return_string = ' Host: %s \n Number of entries: %s \n' % ( |
| 86 | hostname, results['hits']['total']) |
| 87 | return_string += ' %s - %s \n' % ( |
Dan Shi | dfea368 | 2014-08-10 23:38:40 -0700 | [diff] [blame] | 88 | time_utils.epoch_time_to_date_string(time_start), |
| 89 | time_utils.epoch_time_to_date_string(time_end)) |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 90 | if num_entries <= 0: |
| 91 | return return_string |
| 92 | for result in results['hits']['hits']: |
| 93 | fields = result['fields'] |
| 94 | time_recorded = fields['time_recorded'][0] |
Dan Shi | dfea368 | 2014-08-10 23:38:40 -0700 | [diff] [blame] | 95 | time_string = time_utils.epoch_time_to_date_string( |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 96 | time_recorded) |
| 97 | reboot_total = fields['value'][0] |
| 98 | spaces = (15 - len(str(time_string))) * ' ' |
| 99 | return_string += ' %s Reboot_time: %.3fs\n' % ( |
| 100 | time_string, reboot_total) |
| 101 | return return_string |
| 102 | |
| 103 | |
| 104 | if __name__ == '__main__': |
| 105 | """main script""" |
| 106 | t_now = time.time() |
| 107 | t_now_minus_one_day = t_now - 3600 * 24 |
| 108 | parser = argparse.ArgumentParser() |
| 109 | parser.add_argument('-l', type=float, dest='last', |
| 110 | help='last hours to search results across', |
| 111 | default=24) |
| 112 | parser.add_argument('--server', type=str, dest='autotest_server', |
| 113 | required=True, |
| 114 | help='Enter Autotest instance name, e.g. "cautotest".') |
| 115 | parser.add_argument('--board', type=str, dest='board', |
| 116 | help='restrict query by board, not implemented yet', |
| 117 | default=None) |
| 118 | parser.add_argument('--pool', type=str, dest='pool', |
| 119 | help='restrict query by pool, not implemented yet', |
| 120 | default=None) |
| 121 | parser.add_argument('--start', type=str, dest='start', |
| 122 | help=('Enter start time as: yyyy-mm-dd hh-mm-ss,' |
| 123 | 'defualts to 24h ago.'), |
| 124 | default=t_now_minus_one_day) |
| 125 | parser.add_argument('--end', type=str, dest='end', |
| 126 | help=('Enter end time as: yyyy-mm-dd hh-mm-ss,' |
| 127 | 'defualts to current time.'), |
| 128 | default=t_now) |
| 129 | parser.add_argument('--gte', type=float, dest='gte', |
| 130 | help=('Enter lower bound on reboot time ' |
| 131 | 'for entries to return.'), |
| 132 | default=0) |
| 133 | parser.add_argument('--lte', type=float, dest='lte', |
| 134 | help=('Enter upper bound on reboot time ' |
| 135 | 'for entries to return.'), |
| 136 | default=None) |
| 137 | parser.add_argument('-n', type=int, dest='size', |
| 138 | help='Maximum number of entries to return.', |
| 139 | default=10000) |
| 140 | parser.add_argument('--hosts', nargs='+', dest='hosts', |
| 141 | help='Enter space deliminated hostnames', |
| 142 | default=[]) |
| 143 | options = parser.parse_args() |
| 144 | |
| 145 | if options.last: |
| 146 | t_start = t_now - 3600 * options.last |
| 147 | t_end = t_now |
| 148 | else: |
Dan Shi | dfea368 | 2014-08-10 23:38:40 -0700 | [diff] [blame] | 149 | t_start = time_utils.to_epoch_time(options.start) |
| 150 | t_end = time_utils.to_epoch_time(options.end) |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 151 | if options.hosts: |
| 152 | hosts = options.hosts |
| 153 | else: |
Dan Shi | dfea368 | 2014-08-10 23:38:40 -0700 | [diff] [blame] | 154 | hosts = host_history.get_matched_hosts(options.autotest_server, |
| 155 | options.board, options.pool) |
Michael Liang | b1d6c73 | 2014-08-11 22:57:05 -0700 | [diff] [blame] | 156 | |
| 157 | for hostname in hosts: |
| 158 | results = get_entries( |
| 159 | t_start, t_end, options.gte, options.lte, options.size, |
| 160 | options.autotest_server, hostname) |
| 161 | print get_results_string(hostname, t_start, t_end, results) |