diff --git a/modules/core/events.py b/modules/core/events.py index 2f4d7bfbb25963995425ce938fd9e372572d514c..074ae3839f562af1480489aff53030fe586cc958 100644 --- a/modules/core/events.py +++ b/modules/core/events.py @@ -27,7 +27,7 @@ from modules.plugins.monitor import AuraMonitor from modules.core.state import PlayerStateService -from modules.plugins.trackservice import TrackserviceHandler +from modules.plugins.trackservice import TrackServiceHandler class EventBinding(): @@ -57,7 +57,7 @@ class EventBinding(): return self - def get_instances(self): + def get_instance(self): """ Returns the object within that binding. """ @@ -77,7 +77,7 @@ class EngineEventDispatcher(): soundsystem = None player_state = None scheduler = None - api_handler = None + monitor = None def __init__(self, soundsystem, scheduler): @@ -94,7 +94,10 @@ class EngineEventDispatcher(): binding = self.attach(AuraMonitor) binding.subscribe("on_boot") - binding = self.attach(TrackserviceHandler) + binding.subscribe("on_sick") + binding.subscribe("on_resurrect") + + binding = self.attach(TrackServiceHandler) binding.subscribe("on_play") @@ -223,20 +226,20 @@ class EngineEventDispatcher(): self.call_event("on_queue", entries) - def on_sick(self): + def on_sick(self, data): """ Called when the engine is in some unhealthy state. """ self.logger.debug("on_sick(..)") - self.call_event("on_sick", None) + self.call_event("on_sick", data) - def on_resurrect(self): + def on_resurrect(self, data): """ Called when the engine turned healthy again after being sick. """ self.logger.debug("on_resurrect(..)") - self.call_event("on_resurrect", None) + self.call_event("on_resurrect", data) def on_critical(self, subject, message, data=None): diff --git a/modules/plugins/monitor.py b/modules/plugins/monitor.py index fed5267515e1378be93bb8621cc7cc4b35b770f9..776f3bc637393a54bc1c175a15e40bc9b5e4bd81 100644 --- a/modules/plugins/monitor.py +++ b/modules/plugins/monitor.py @@ -18,9 +18,11 @@ import os +import datetime import urllib import logging import json +import requests import threading import platform @@ -115,9 +117,26 @@ class AuraMonitor: self.logger.info("Status Monitor:\n%s" % json.dumps(status, indent=4)) if not is_valid: self.logger.info("Engine Status: " + SU.red(status["engine"]["status"])) + self.post_health(status, False) raise EngineMalfunctionException else: self.logger.info("Engine Status: " + SU.green("[OK]")) + self.post_health(status, True) + + + + def on_sick(self, data): + """ + Called when the engine is in some unhealthy state. + """ + self.post_health(data, False) + + + def on_resurrect(self, data): + """ + Called when the engine turned healthy again after being sick. + """ + self.post_health(data, True) # @@ -172,6 +191,27 @@ class AuraMonitor: # + def post_health(self, data, is_healthy): + """ + Post unhealthy state info to Engine API. + """ + body = dict() + body["log_time"] = datetime.datetime.now() + body["is_healthy"] = is_healthy + body["details"] = json.dumps(data, default=str) + json_data = json.dumps(body, default=str) + + url = self.config.get("api_engine_store_health") + url = url.replace("${ENGINE_NUMBER}", str(self.config.get("api_engine_number"))) + headers = {'content-type': 'application/json'} + r = requests.post(url, data=json_data, headers=headers) + + if r.status_code == 204: + self.logger.info("Successfully posted healthy=%s state to Engine API!" % is_healthy) + else: + self.logger.error("HTTP %s | Error while pushing health state to Engine API: %s" % (r.status_code, str(r.json()))) + + def update_status(self): """ Requests the current status of all components @@ -233,6 +273,8 @@ class AuraMonitor: self.mailer.send_admin_mail( \ "OK - Engine turned back into some HEALTHY STATE!", \ "Things seem fine again at '%s':\n\n%s" % (self.engine_id, status)) + # Route call of event via event dispatcher to provide ability for additional hooks + self.soundsystem.event_dispatcher.on_resurrect(status) else: # Engine turned into invalid state if not self.already_invalid: @@ -242,6 +284,8 @@ class AuraMonitor: self.mailer.send_admin_mail( \ "ERROR - Engine turned into some INVALID STATE!", \ "There's an issue with Aura Engine '%s':\n\n%s" % (self.engine_id, status)) + # Route call of event via event dispatcher to provide ability for additional hooks + self.soundsystem.event_dispatcher.on_sick(status) threading.Timer(self.config.get("heartbeat_frequency"), self.heartbeat).start()