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