3193d3304818f81c0009df07f8cc0216eee41714
[yardstick.git] / yardstick / benchmark / scenarios / availability / monitor.py
1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd. and others
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import logging
10 import multiprocessing
11 import subprocess
12 import traceback
13 import time
14
15 LOG = logging.getLogger(__name__)
16
17
18 def _execute_shell_command(command):
19     '''execute shell script with error handling'''
20     exitcode = 0
21     output = []
22     try:
23         output = subprocess.check_output(command, shell=True)
24     except Exception:
25         exitcode = -1
26         output = traceback.format_exc()
27         LOG.error("exec command '%s' error:\n " % command)
28         LOG.error(traceback.format_exc())
29
30     return exitcode, output
31
32
33 def _monitor_process(config, queue, event):
34
35     total_time = 0
36     outage_time = 0
37     total_count = 0
38     outage_count = 0
39     first_outage = 0
40     last_outage = 0
41
42     wait_time = config.get("duration", 0)
43     cmd = config.get("monitor_cmd", None)
44     if cmd is None:
45         LOG.error("There are no monitor cmd!")
46         return
47
48     queue.put("started")
49
50     begin_time = time.time()
51     while True:
52
53         total_count = total_count + 1
54
55         one_check_begin_time = time.time()
56         exit_status, stdout = _execute_shell_command(cmd)
57         one_check_end_time = time.time()
58
59         LOG.info("the exit_status:%s stdout:%s" % (exit_status, stdout))
60         if exit_status:
61             outage_count = outage_count + 1
62
63             outage_time = outage_time + (
64                 one_check_end_time - one_check_begin_time)
65
66             if not first_outage:
67                 first_outage = one_check_begin_time
68
69             last_outage = one_check_end_time
70
71         if event.is_set():
72             LOG.debug("the monitor process stop")
73             break
74
75         if wait_time > 0:
76             time.sleep(wait_time)
77
78     end_time = time.time()
79     total_time = end_time - begin_time
80
81     queue.put({"total_time": total_time,
82                "outage_time": last_outage-first_outage,
83                "total_count": total_count,
84                "outage_count": outage_count})
85
86
87 class Monitor:
88
89     def __init__(self):
90         self._result = []
91         self._monitor_process = []
92
93     def setup(self, config):
94         self._config = config
95
96     def start(self):
97         self._queue = multiprocessing.Queue()
98         self._event = multiprocessing.Event()
99         self._monitor_process = multiprocessing.Process(
100             target=_monitor_process, name="Monitor",
101             args=(self._config, self._queue, self._event))
102
103         self._monitor_process.start()
104         ret = self._queue.get()
105         if ret == "started":
106             LOG.debug("monitor process started!")
107
108     def stop(self):
109         self._event.set()
110         self._result = self._queue.get()
111         LOG.debug("stop the monitor process. the result:%s" % self._result)
112
113     def get_result(self):
114         return self._result