blob: 81668267a1a03bc316049b4e40775c7f3faf541f [file] [log] [blame]
Dan Shi1ccb6522014-09-19 17:15:30 -07001#!/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 script is to be run daily to report machine utilization stats across
8# each board and pool.
9
10
11import argparse
12from datetime import date
13from datetime import datetime
14from datetime import timedelta
15
16import common
17from autotest_lib.client.common_lib import global_config
18from autotest_lib.client.common_lib import time_utils
19from autotest_lib.client.common_lib.cros.graphite import stats
20from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
21from autotest_lib.site_utils import host_history_utils
22
23
24INSTANCE_SERVER = global_config.global_config.get_config_value(
25 'SERVER', 'hostname', type=str)
26_AFE = frontend_wrappers.RetryingAFE(
27 server=INSTANCE_SERVER, timeout_min=60, delay_sec=0)
28
29def report_stats(board, pool, start_time, end_time, span):
30 """Report machine stats for given board, pool and time period.
31
32 @param board: Name of board.
33 @param pool: Name of pool.
34 @param start_time: start time to collect stats.
35 @param end_time: end time to collect stats.
36 @param span: Number of hours that the stats should be collected for.
37 """
38 print '================ %-12s %-12s ================' % (board, pool)
39 history = _AFE.run('get_host_history', board=board, pool=pool,
40 start_time=start_time, end_time=end_time)
41 if not history:
42 print 'No history found.'
43 return
44 status_intervals = host_history_utils.get_status_intervals(history)
45 stats_all, num_hosts = host_history_utils.aggregate_hosts(
46 status_intervals)
47 total = 0
48 total_time = span*3600*num_hosts
49 for status, interval in stats_all.iteritems():
50 total += interval
51 if abs(total - total_time) > 10:
52 print ('Status intervals do not add up. No stats will be collected for '
53 'board: %s, pool: %s, diff: %s' %
54 (board, pool, total - total_time))
55 return
56
57 mur = host_history_utils.get_machine_utilization_rate(stats_all)
58 mar = host_history_utils.get_machine_availability_rate(stats_all)
59
60 stats.Gauge('machine_utilization_rate').send('%s_hours.%s.%s' %
61 (span, board, pool), mur)
62 stats.Gauge('machine_availability_rate').send('%s_hours.%s.%s' %
63 (span, board, pool), mar)
64 stats.Gauge('machine_idle_rate').send('%s_hours.%s.%s' %
65 (span, board, pool), mar-mur)
66
67 for status, interval in stats_all.iteritems():
68 print '%-18s %-16s %-10.2f%%' % (status, interval,
69 100*interval/total_time)
70 print 'Machine utilization rate = %-4.2f%%' % (100*mur)
71 print 'Machine availability rate = %-4.2f%%' % (100*mar)
72
73
74def main():
75 """main script. """
76 parser = argparse.ArgumentParser()
77 parser.add_argument('--span', type=int, dest='span',
78 help=('Number of hours that stats should be collected. '
79 'If it is set to 24, the end time of stats being '
80 'collected will set to the mid of the night. '
81 'Default is set to 1 hour.'),
82 default=1)
83 options = parser.parse_args()
84
85 labels = _AFE.get_labels(name__startswith='board:')
86 boards = [label.name[6:] for label in labels]
87
88 pools = ['bvt', 'suites', 'try-bot', 'cq', 'pfq']
89
90 if options.span == 24:
91 today = datetime.combine(date.today(), datetime.min.time())
92 end_time = time_utils.to_epoch_time(today)
93 else:
94 now = datetime.now()
95 end_time = datetime(year=now.year, month=now.month, day=now.day,
96 hour=now.hour)
97 end_time = time_utils.to_epoch_time(end_time)
98
99 start_time = end_time - timedelta(hours=options.span).total_seconds()
100 print ('Collecting host stats from %s to %s...' %
101 (time_utils.epoch_time_to_date_string(start_time),
102 time_utils.epoch_time_to_date_string(end_time)))
103
104 for board in boards:
105 for pool in pools:
106 report_stats(board, pool, start_time, end_time, options.span)
107
108
109if __name__ == '__main__':
110 main()