stack-monitor: monitor.py now takes args for modularity
[slapos.git] / stack / monitor / monitor.py.in
1 #!/usr/bin/python
2
3 import json
4 import os
5 import subprocess
6 import sys
7 import time
8 from optparse import OptionParser, make_option
9
10 instance_path = "{{ directory['home'] }}"
11 monitor_dir = "{{ directory['monitor'] }}"
12 pid_dir = "{{ directory['run'] }}"
13 promise_dir = "{{ directory['promise'] }}"
14
15 monitoring_file_bool = "{{ monitoring_file_bool }}"
16 monitoring_file_json = "{{ monitoring_file_json }}"
17
18 option_list = [
19 make_option("-a", "--all", action="store_true", dest="all",
20 help="test everything : promises, services, customs"),
21 make_option("-n", "--no-write", action="store_true", dest="only_stdout",
22 help="just show the json output on stdout"),
23 make_option("-m", "--monitors", action="store_true", dest="monitor",
24 help="add the custom monitoring file to the files to monitor"),
25 make_option("-p", "--promises", action="store_true", dest="promise",
26 help="add the promises\'file to the files to monitor"),
27 make_option("-s", "--services", action="store_true", dest="service",
28 help="add the file containing services\'pid to the files to monitor")
29 ]
30
31
32 def getListOfScripts(directory):
33 scripts = []
34 if os.path.exists(directory) and os.path.isdir(directory):
35 for file in os.listdir(directory):
36 scripts.append(os.path.join(directory, file))
37 else:
38 exit("There is a problem in your directories" \
39 "of monitoring. Please check them")
40 return scripts
41
42 def runServices(directory):
43 services = getListOfScripts(directory)
44 result = {}
45 for service in services:
46 service_path = os.path.join(pid_dir, service)
47 service_name = os.path.basename(service_path)
48 pid = int(open(service_path).read())
49 try:
50 os.kill(pid, 0)
51 result[service_name] = ''
52 except OSError:
53 result[service_name] = "This service is not running anymore"
54 return result
55
56
57 def runScripts(directory):
58 scripts = getListOfScripts(directory)
59 script_timeout = 3
60 result = {}
61 for script in scripts:
62 command = [os.path.join(promise_dir, script)]
63 script = os.path.basename(command[0])
64 result[script] = ''
65
66 process_handler = subprocess.Popen(command,
67 cwd=instance_path,
68 env=None if sys.platform == 'cygwin' else {},
69 stdout=subprocess.PIPE,
70 stderr=subprocess.PIPE,
71 stdin=subprocess.PIPE)
72 process_handler.stdin.flush()
73 process_handler.stdin.close()
74 process_handler.stdin = None
75
76 time.sleep(script_timeout)
77
78 if process_handler.poll() is None:
79 process_handler.terminate()
80 result[script] = "Time Out"
81 elif process_handler.poll() != 0:
82 stderr = process_handler.communicate()[1]
83 if stderr is not None:
84 result[script] = stderr.strip()
85 return result
86
87
88 def writeFiles(monitors):
89 open(monitoring_file_json, "w+").write(json.dumps(monitors))
90 if len(monitors) == 0:
91 open(monitoring_file_bool, "w+").write("SUCCESS : everything is ok")
92 else:
93 open(monitoring_file_bool, "w+").write("FAILURE : something went wrong")
94
95
96 if __name__ == "__main__":
97 parser = OptionParser(option_list=option_list)
98 monitors = {}
99 (options, args) = parser.parse_args()
100
101 if not (options.monitor or options.promise
102 or options.service or options.all):
103 exit("Please provide at list one arg in : -a, -m, -p, -s")
104
105 if options.monitor or options.all:
106 monitors.update(runScripts(monitor_dir))
107 if options.promise or options.all:
108 monitors.update(runScripts(promise_dir))
109 if options.service or options.all:
110 monitors.update(runServices(pid_dir))
111
112 if options.only_stdout:
113 print json.dumps(monitors)
114 else:
115 writeFiles(monitors)
116 if len(monitors) == 0:
117 exit(0)
118 else:
119 exit(1)
120