Created
May 6, 2015 08:09
-
-
Save chrigl/5a30d5fca48bb533653e to your computer and use it in GitHub Desktop.
upstartwatch... not sure if this is a good idea.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys | |
import dbus | |
import time | |
import json | |
import argparse | |
import threading | |
import functools | |
import http.server | |
from gi.repository import GObject | |
from dbus.mainloop.glib import DBusGMainLoop | |
EMPTY_INSTANCE = 'instance=' | |
RESPAWN_TIME = 10 # if respawn happens in RESPAWN_TIME seconds, log it | |
LISTEN_IP = '127.0.0.1' | |
LISTEN_PORT = 18000 | |
STORAGE = {} | |
lock = threading.Lock() | |
class ReqHandler(http.server.SimpleHTTPRequestHandler): | |
def do_GET(self): | |
if self.path != '/': | |
self.send_response(404) | |
self.end_headers() | |
self.wfile.write(b'Not found') | |
return | |
self.send_response(200) | |
self.send_header('Content-Type', 'application/json') | |
self.end_headers() | |
self.wfile.write(json.dumps(STORAGE).encode('utf-8', errors='ignore')) | |
return | |
def run_httpd(server_addr): | |
httpd = http.server.HTTPServer(server_addr, ReqHandler) | |
httpd.serve_forever() | |
def detect_respawn_loops(respawn_time, event_name, event): | |
if event_name == 'started': | |
job = event[0].lower().split('=')[1] | |
instance = event[1].lower() | |
if instance == EMPTY_INSTANCE: | |
# not interrested in e.g. | |
# string "JOB=startpar-bridge" | |
# string "INSTANCE=chris-test--started" | |
with lock: | |
if job not in STORAGE: | |
STORAGE[job] = {'respawn_count': 0, | |
'last_respawn': 0} | |
if STORAGE[job]['last_respawn'] + respawn_time > time.time(): | |
if STORAGE[job]['respawn_count'] < sys.maxsize: | |
STORAGE[job]['respawn_count'] += 1 | |
else: | |
STORAGE[job]['respawn_count'] = 0 | |
STORAGE[job]['last_respawn'] = time.time() | |
def params(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-p', '--port', type=int, default=LISTEN_PORT, | |
help='Listen port of httpd (default: 18000)') | |
parser.add_argument('-l', '--listen', type=str, default=LISTEN_IP, | |
help='Listen address (default: 127.0.0.1)') | |
parser.add_argument('-r', '--respawn', type=int, default=RESPAWN_TIME, | |
help='Allowed respawn seconds. If service respawns ' | |
'within this period, internal counter will be ' | |
'increased. (default: 10)') | |
return parser | |
def main(): | |
args = params().parse_args() | |
thread_fn = functools.partial(run_httpd, (args.listen, args.port)) | |
httpd_thread = threading.Thread(target=thread_fn, daemon=True) | |
httpd_thread.start() | |
# no need to join. | |
# prepare detect_respawn_loops with argument | |
_detect_respawn_loops = functools.partial(detect_respawn_loops, | |
args.respawn) | |
DBusGMainLoop(set_as_default=True) | |
bus = dbus.SystemBus(mainloop=DBusGMainLoop()) | |
bus.add_signal_receiver(_detect_respawn_loops, | |
dbus_interface="com.ubuntu.Upstart0_6", | |
path="/com/ubuntu/Upstart") | |
loop = GObject.MainLoop() | |
try: | |
loop.run() | |
except KeyboardInterrupt: | |
print("Bye") | |
exit(0) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment