updog/helpers.py
2024-02-06 12:37:19 -06:00

120 lines
3.8 KiB
Python

import threading
import time
# Threaded repeating timer thing
# From https://stackoverflow.com/a/40965385/16432246
# It shouldn't drift, but that's untested
# Keep in mind you can't catch Exceptions for this, it just crashes the thread.
# Some more scheduling stuff: https://www.redwood.com/article/python-job-scheduling/
class RepeatedTimer(object):
'''
Run stuff repeatedly every x seconds
Example usage (from SO and ported to Python 3):
from time import sleep
def hello(name):
print(f'Hello {name}!')
print()"starting...")
rt = RepeatedTimer(1, hello, "World") # it auto-starts, no need of rt.start()
try:
sleep(5) # your long-running job goes here...
except:
rt.stop() # better in a try/catch block to make sure the program ends!
'''
def __init__(self, interval, function, *args, **kwargs):
'''
Run a functions with arguments every
'''
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.next_call = time.time()
self.start()
def _run(self):
self.is_running = False
self.start()
self.function(*self.args, **self.kwargs)
def start(self):
if not self.is_running:
self.next_call += self.interval
self._timer = threading.Timer(
self.next_call - time.time(), self._run)
self._timer.start()
self.is_running = True
def stop(self):
self._timer.cancel()
self.is_running = False
def create_instances(config, checkers, alerts, logging):
'''
Creates instances of all the extensions according to config
Parameters:
config: the dictionary containing the config
Returns:
instances (dict): A dictionary containing instances of the extensions
example: {'site': {'checker': instanceOfCheckerTemplate}}
'''
instances = {}
# global arguments
default_checker = ''
default_alerter = ''
default_logger = ''
for service in config.keys():
if service == 'global-args':
default_checker = config['global-args'].get('default-checker', '')
default_alerter = config['global-args'].get('default-alerts', '')
default_logger = config['global-args'].get('default-logging', '')
continue
instances[service] = {}
# create an instance of checker with the arguments for them, including the optional `default-checker`
checker_args = config[service]['checker-args']
if config[service].get('checker', '') != '':
checker = config[service]['checker']
else:
checker = default_checker
instances[service]['checker'] = checkers[checker](checker_args)
# and for alerts
alerter_args = config[service]['alerts-args']
if config[service].get('alerts', '') != '':
alerter = config[service]['alerts']
else:
alerter = default_alerter
instances[service]['alerts'] = alerts[alerter](alerter_args)
# and for logging
logger_args = config[service]['logging-args']
if config[service].get('logging', '') != '':
logger = config[service]['logging']
else:
logger = default_logger
instances[service]['logging'] = logging[logger](logger_args)
return instances
def run_check(service_name, checker, alerts, logging):
'''
Does the logic and stuff for running the checker, calling alerts/logging, and so on
'''
status = checker.get_status()
return_codes = checker.get_return_codes()
status_message = return_codes[status]
logging.log(service_name, status, status_message)
alerts.alert(service_name, status, status_message)