1 #!{{ python_executable }}
10 from optparse
import OptionParser
, make_option
16 db_path
= "{{ monitor_parameter['db-path'] }}"
17 instance_path
= "{{ directory['home'] }}"
18 monitor_dir
= "{{ directory['monitor-custom-scripts'] }}"
19 pid_dir
= "{{ directory['run'] }}"
20 promise_dir
= "{{ directory['promise'] }}"
22 monitoring_file_json
= "{{ monitoring_file_json }}"
25 make_option("-a", "--all", action
="store_true", dest
="all",
26 help="test everything : promises, services, customs"),
27 make_option("-n", "--no-write", action
="store_true", dest
="only_stdout",
28 help="just show the json output on stdout"),
29 make_option("-m", "--monitors", action
="store_true", dest
="monitor",
30 help="add the custom monitoring file to the files to monitor"),
31 make_option("-p", "--promises", action
="store_true", dest
="promise",
32 help="add the promises\'file to the files to monitor"),
33 make_option("-s", "--services", action
="store_true", dest
="service",
34 help="add the file containing services\'pid to the files to monitor")
37 class Popen(subprocess
.Popen
):
39 def set_timeout(self
, timeout
):
40 self
.set_timeout
= None # assert we're not called twice
41 event
= threading
.Event()
42 event
.__killed
= False # we just need a mutable
44 # do not call wait() or poll() because they're not thread-safe
45 if not event
.wait(timeout
) and self
.returncode
is None:
46 # race condition if waitpid completes just before the signal sent ?
51 if self
.returncode
is None:
52 self
.kill() # same race as for terminate ?
53 t
= threading
.Thread(target
=t
)
64 CREATE TABLE IF NOT EXISTS status (
65 timestamp INTEGER UNIQUE,
67 CREATE TABLE IF NOT EXISTS individual_status (
74 def getListOfScripts(directory
):
76 Get the list of script inside of a directory (not recursive)
79 if os
.path
.exists(directory
) and os
.path
.isdir(directory
):
80 for file_name
in os
.listdir(directory
):
81 file = os
.path
.join(directory
, file_name
)
82 if os
.access(file, os
.X_OK
) and not os
.path
.isdir(file):
85 exit("There is a problem in your directories" \
86 "of monitoring. Please check them")
90 def runServices(directory
):
91 services
= getListOfScripts(directory
)
93 for service
in services
:
94 service_path
= os
.path
.join(pid_dir
, service
)
95 service_name
= os
.path
.basename(service_path
)
97 pid
= int(open(service_path
).read())
98 ### because apache (or others) can write sockets
99 ### We also ignore not readable pid files
100 except (IOError, ValueError):
104 result
[service_name
] = ''
106 result
[service_name
] = "This service is not running anymore"
110 def runScripts(directory
):
111 # XXX script_timeout could be passed as parameters
112 script_timeout
= 60 # in seconds
114 with
open(os
.devnull
, 'r+') as f
:
115 for script
in getListOfScripts(directory
):
116 command
= os
.path
.join(promise_dir
, script
),
117 script
= os
.path
.basename(script
)
120 p
= Popen(command
, cwd
=instance_path
,
121 env
=None if sys
.platform
== 'cygwin' else {},
122 stdin
=f
, stdout
=f
, stderr
=subprocess
.PIPE
)
123 killed
= p
.set_timeout(script_timeout
)
124 stderr
= p
.communicate()[1]
126 result
[script
] = "Time Out"
128 result
[script
] = stderr
.strip()
132 def writeFiles(monitors
):
133 timestamp
= int(time
.time())
134 db
= sqlite3
.connect(db_path
)
137 for key
, value
in monitors
.iteritems():
139 element_status
= status
= FAILURE
141 element_status
= SUCCESS
142 db
.execute("insert into individual_status(timestamp, element, output, status) values (?, ?, ?, ?)", (timestamp
, key
, value
, element_status
))
143 db
.execute("insert into status(timestamp, status) values (?, ?)", (timestamp
, status
))
146 monitors
['datetime'] = time
.ctime(timestamp
)
147 json
.dump(monitors
, open(monitoring_file_json
, "w+"))
150 parser
= OptionParser(option_list
=option_list
)
152 (options
, args
) = parser
.parse_args()
154 if not (options
.monitor
or options
.promise
155 or options
.service
or options
.all
):
156 exit("Please provide at list one arg in : -a, -m, -p, -s")
158 if options
.monitor
or options
.all
:
159 monitors
.update(runScripts(monitor_dir
))
160 if options
.promise
or options
.all
:
161 monitors
.update(runScripts(promise_dir
))
162 if options
.service
or options
.all
:
163 monitors
.update(runServices(pid_dir
))
165 if options
.only_stdout
:
166 print json
.dumps(monitors
)
171 if __name__
== "__main__":