Tons of refactoring and implemented basic task execution. There are lot of bugs and features not working anymore. DO NOT USE!. (0.22.0)

This commit is contained in:
Johannes Findeisen 2023-08-20 22:51:39 +02:00
commit 681475f274
31 changed files with 278 additions and 259 deletions

View file

@ -22,3 +22,4 @@
- Write documentation and inline documentation. - Write documentation and inline documentation.
- Add kwargs to notifications, tasks and maybe plugins. - Add kwargs to notifications, tasks and maybe plugins.
- Add date and cron based scheduling to linspector.py to make the full use of APScheduler. - Add date and cron based scheduling to linspector.py to make the full use of APScheduler.
- Make Linspector Windows compatible (not so important)

View file

@ -18,7 +18,7 @@ from linspector.environment import Environment
from linspector.linspector import Linspector from linspector.linspector import Linspector
from linspector.monitors import Monitors from linspector.monitors import Monitors
__version__ = '0.21.9' __version__ = '0.22.0'
__author__ = 'Johannes Findeisen <you@hanez.org>' __author__ = 'Johannes Findeisen <you@hanez.org>'

View file

@ -25,9 +25,12 @@ logfile_level = DEBUG
logfile_size = 10MB logfile_size = 10MB
notifications = notifications =
plugins = plugins =
tasks =
tasks = mariadb
; timezone can be set to a remote timezone to make monitors run at the remote time. this can be overridden in each ; timezone can be set to a remote timezone to make monitors run at the remote time. this can be overridden in each
; monitor configuration. ; monitor configuration.
timezone = CET timezone = CET

4
etc/tasks/mariadb.conf Normal file
View file

@ -0,0 +1,4 @@
[mariadb]
database = uplink
password = PASSWORD
user = root

View file

@ -12,15 +12,15 @@ import os
# options in the "linspector" section of linspector.conf. maybe log warnings if setting to default? # options in the "linspector" section of linspector.conf. maybe log warnings if setting to default?
class Configuration: class Configuration:
def __init__(self, configuration_path, log): def __init__(self, configuration_path, log):
self.__configuration = configparser.ConfigParser() self._configuration = configparser.ConfigParser()
self.__configuration_path = configuration_path self._configuration_path = configuration_path
self.__log = log self._log = log
log.info('message=reading configuration configfile=' + configuration_path + log.info('message=reading configuration configfile=' + configuration_path +
'/linspector.conf') '/linspector.conf')
if os.path.isfile(configuration_path + '/linspector.conf'): if os.path.isfile(configuration_path + '/linspector.conf'):
try: try:
self.__configuration.read(configuration_path + '/linspector.conf', 'utf-8') self._configuration.read(configuration_path + '/linspector.conf', 'utf-8')
except Exception as err: except Exception as err:
raise Exception('something went wrong reading the configuration file ' raise Exception('something went wrong reading the configuration file '
'linspector.conf in the configuration root path! ({0})'.format(err)) 'linspector.conf in the configuration root path! ({0})'.format(err))
@ -31,8 +31,8 @@ class Configuration:
# add keys and values defined in sub dirs and configuration ini files. # add keys and values defined in sub dirs and configuration ini files.
for target_section in ['notifications', 'plugins', 'services', 'tasks']: for target_section in ['notifications', 'plugins', 'services', 'tasks']:
# check if section exists before adding content. if not exists add the section. # check if section exists before adding content. if not exists add the section.
if not self.__configuration.has_section(target_section): if not self._configuration.has_section(target_section):
self.__configuration.add_section(target_section) self._configuration.add_section(target_section)
section_list = glob.glob(configuration_path + '/' + target_section + '/*.conf') section_list = glob.glob(configuration_path + '/' + target_section + '/*.conf')
for section_file in section_list: for section_file in section_list:
@ -42,38 +42,38 @@ class Configuration:
for source_section in configuration.sections(): for source_section in configuration.sections():
source_section_options = configuration.options(source_section) source_section_options = configuration.options(source_section)
for source_section_option in source_section_options: for source_section_option in source_section_options:
self.__configuration.set(target_section, source_section + '_' + self._configuration.set(target_section, source_section + '_' +
source_section_option, source_section_option,
configuration.get(source_section, configuration.get(source_section,
source_section_option)) source_section_option))
# print('configuration dump: ' + self.dump_to_ini()) # print('configuration dump: ' + self.dump_to_ini())
def dump_to_ini(self): def dump_to_ini(self):
dump = '' dump = ''
i = 0 i = 0
for section in self.__configuration.sections(): for section in self._configuration.sections():
if i < 1: if i < 1:
dump = dump + '[' + section + ']\n' dump = dump + '[' + section + ']\n'
else: else:
dump = dump + '\n[' + section + ']\n' dump = dump + '\n[' + section + ']\n'
options = self.__configuration.options(section) options = self._configuration.options(section)
for option in options: for option in options:
dump = dump + option + " = " + self.__configuration.get(section, option) + '\n' dump = dump + option + " = " + self._configuration.get(section, option) + '\n'
i = 1 i = 1
return dump return dump
def get_configuration_path(self): def get_configuration_path(self):
return self.__configuration_path return self._configuration_path
def get_option(self, section, option): def get_option(self, section, option):
if self.__configuration.has_option(section, option): if self._configuration.has_option(section, option):
return self.__configuration.get(section, option) return self._configuration.get(section, option)
else: else:
return None return None
# this function should be used with care because it edits the main configuration. maybe it can # this function should be used with care because it edits the main configuration. maybe it can
# be used for dynamic runtime configuration later but i need to think about it. # be used for dynamic runtime configuration later but i need to think about it.
def set_option(self, section, option, value): def set_option(self, section, option, value):
if not self.__configuration.has_option(section, option): if not self._configuration.has_option(section, option):
self.__configuration.set(section, option, value) self._configuration.set(section, option, value)

View file

@ -12,14 +12,14 @@ class Environment:
""" """
def __init__(self, log): def __init__(self, log):
self.__env = {} self._env = {}
self.__log = log self._log = log
def get_env_var(self, key): def get_env_var(self, key):
if key in self.__env: if key in self._env:
return self.__env[key] return self._env[key]
else: else:
self.__log.warning('environment var "' + key + '" not found! could be that it is ' self._log.warning('environment var "' + key + '" not found! could be that it is '
'set later at runtime. if you ' 'set later at runtime. if you '
'encounter any errors executing ' 'encounter any errors executing '
'linspector, something is wrong ' 'linspector, something is wrong '
@ -32,8 +32,8 @@ class Environment:
return None return None
def set_env_var(self, key, value): def set_env_var(self, key, value):
if self.__env[key]: if self._env[key]:
self.__log('warning', __name__, 'environment var "' + key + self._log('warning', _name_, 'environment var "' + key +
' existed and was overwritten!') ' existed and was overwritten!')
self.__env[key] = value self._env[key] = value

View file

@ -27,21 +27,21 @@ def job_execution(log, monitor):
class Linspector: class Linspector:
def __init__(self, configuration, environment, log, monitors, plugins, scheduler): def __init__(self, configuration, environment, log, monitors, plugins, scheduler):
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__jobs = [] self._jobs = []
self.__log = log self._log = log
self.__monitors = monitors self._monitors = monitors
self.__plugin_list = [] self._plugin_list = []
self.__plugins = plugins self._plugins = plugins
self.__scheduler = scheduler self._scheduler = scheduler
# load plugins # load plugins
log.info('message=loading plugins') log.info('message=loading plugins')
if configuration.get_option('linspector', 'plugins'): if configuration.get_option('linspector', 'plugins'):
plugin_list = configuration.get_option('linspector', 'plugins') plugin_list = configuration.get_option('linspector', 'plugins')
self.__plugin_list = plugin_list.split(',') self._plugin_list = plugin_list.split(',')
for plugin_option in self.__plugin_list: for plugin_option in self._plugin_list:
if plugin_option not in plugins: if plugin_option not in plugins:
log.info('loading plugin: ' + plugin_option) log.info('loading plugin: ' + plugin_option)
plugin_package = 'linspector.plugins.' + plugin_option.lower() plugin_package = 'linspector.plugins.' + plugin_option.lower()
@ -75,14 +75,14 @@ class Linspector:
# every scheduler job (monitor) must only exist once. # every scheduler job (monitor) must only exist once.
'max_instances': 1 'max_instances': 1
} }
self.__scheduler['linspector'] = BackgroundScheduler(jobstores=jobstores, self._scheduler['linspector'] = BackgroundScheduler(jobstores=jobstores,
executors=executors, executors=executors,
job_defaults=job_defaults, job_defaults=job_defaults,
timezone=utc) timezone=utc)
start_date = datetime.datetime.now() start_date = datetime.datetime.now()
log.debug(monitors.get_monitors()) log.debug(monitors.get_monitors())
monitors = self.__monitors.get_monitors() monitors = self._monitors.get_monitors()
for monitor in monitors: for monitor in monitors:
log.debug(monitor) log.debug(monitor)
if configuration.get_option('linspector', 'delta_range'): if configuration.get_option('linspector', 'delta_range'):
@ -121,7 +121,7 @@ class Linspector:
args=[log, monitors.get(monitor)]) args=[log, monitors.get(monitor)])
monitor_job.set_job(scheduler_job) monitor_job.set_job(scheduler_job)
self.__jobs.append(monitor_job) self._jobs.append(monitor_job)
log.info('identifier=' + monitor + log.info('identifier=' + monitor +
' host=' + monitors.get(monitor).get_host() + ' host=' + monitors.get(monitor).get_host() +
' service=' + monitor_job.get_service() + ' service=' + monitor_job.get_service() +
@ -130,4 +130,4 @@ class Linspector:
' message=scheduling job') ' message=scheduling job')
if configuration.get_option('linspector', 'start_scheduler') == 'true': if configuration.get_option('linspector', 'start_scheduler') == 'true':
self.__scheduler['linspector'].start() self._scheduler['linspector'].start()

View file

@ -13,12 +13,12 @@ import time
# TODO: there is a bug when stopping the daemon. the pid_file is not being deleted. NEEDS A FIX! # TODO: there is a bug when stopping the daemon. the pid_file is not being deleted. NEEDS A FIX!
class Linspectord: class Linspectord:
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
self.__log = log self._log = log
try: try:
self.__pid_file = configuration.get_option('linspector', 'pid_file') self._pid_file = configuration.get_option('linspector', 'pid_file')
except Exception as err: except Exception as err:
log.critical('daemonize error (no pid_file set): {0}'.str(format(err))) log.critical('daemonize error (no pid_file set): {0}'.str(format(err)))
@ -32,7 +32,7 @@ class Linspectord:
# exit first parent. # exit first parent.
sys.exit(0) sys.exit(0)
except OSError as err: except OSError as err:
self.__log.critical('fork #1 failed: {0}'.str(format(err))) self._log.critical('fork #1 failed: {0}'.str(format(err)))
sys.exit(1) sys.exit(1)
# decouple from parent environment. # decouple from parent environment.
@ -47,7 +47,7 @@ class Linspectord:
# Exit from second parent. # Exit from second parent.
sys.exit(0) sys.exit(0)
except OSError as err: except OSError as err:
self.__log.critical('fork #2 failed: {0}'.str(format(err))) self._log.critical('fork #2 failed: {0}'.str(format(err)))
sys.exit(1) sys.exit(1)
# redirect standard file descriptors. # redirect standard file descriptors.
@ -65,24 +65,24 @@ class Linspectord:
atexit.register(self.delete_pid) atexit.register(self.delete_pid)
pid = str(os.getpid()) pid = str(os.getpid())
with open(self.__pid_file, 'w+') as f: with open(self._pid_file, 'w+') as f:
f.write(pid + '\n') f.write(pid + '\n')
def delete_pid(self): def delete_pid(self):
os.remove(self.__pid_file) os.remove(self._pid_file)
def start(self): def start(self):
# start the daemon. check for a pidfile to see if the daemon already runs before. # start the daemon. check for a pidfile to see if the daemon already runs before.
self.__log.info('starting daemon using pid_file: ' + str(self.__pid_file)) self._log.info('starting daemon using pid_file: ' + str(self._pid_file))
try: try:
with open(self.__pid_file, 'r') as pf: with open(self._pid_file, 'r') as pf:
pid = int(pf.read().strip()) pid = int(pf.read().strip())
except IOError: except IOError:
pid = None pid = None
if pid: if pid:
message = 'pid_file {0} already exist. daemon already running?' message = 'pid_file {0} already exist. daemon already running?'
self.__log.critical(str(message.format(self.__pid_file))) self._log.critical(str(message.format(self._pid_file)))
sys.exit(1) sys.exit(1)
# start the daemon. # start the daemon.
@ -91,17 +91,17 @@ class Linspectord:
def stop(self): def stop(self):
# stop the daemon. # stop the daemon.
self.__log.info('stopping daemon using pid_file: ' + str(self.__pid_file)) self._log.info('stopping daemon using pid_file: ' + str(self._pid_file))
# get the pid from the pid file. # get the pid from the pid file.
try: try:
with open(self.__pid_file, 'r') as pf: with open(self._pid_file, 'r') as pf:
pid = int(pf.read().strip()) pid = int(pf.read().strip())
except IOError: except IOError:
pid = None pid = None
if not pid: if not pid:
message = 'pid_file {0} does not exist. daemon not running?' message = 'pid_file {0} does not exist. daemon not running?'
self.__log.error(str(message.format(self.__pid_file))) self._log.error(str(message.format(self._pid_file)))
return # not an error in a restart return # not an error in a restart
# try killing the daemon process. # try killing the daemon process.
@ -112,15 +112,15 @@ class Linspectord:
except OSError as err: except OSError as err:
e = str(err.args) e = str(err.args)
if e.find('no such process') > 0: if e.find('no such process') > 0:
if os.path.exists(self.__pid_file): if os.path.exists(self._pid_file):
os.remove(self.__pid_file) os.remove(self._pid_file)
else: else:
self.__log.critical(str(err.args)) self._log.critical(str(err.args))
sys.exit(1) sys.exit(1)
def restart(self): def restart(self):
# restart the daemon. # restart the daemon.
self.__log.info('restarting daemon using pid_file: ' + str(self.__pid_file)) self._log.info('restarting daemon using pid_file: ' + str(self._pid_file))
self.stop() self.stop()
self.start() self.start()

View file

@ -10,6 +10,6 @@ See LICENSE (MIT license).
class Model: class Model:
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log

View file

@ -10,46 +10,47 @@ import importlib
class Monitor: class Monitor:
def __init__(self, configuration, environment, identifier, log, monitor_configuration, def __init__(self, configuration, environment, identifier, log, monitor_configuration,
notifications, services, tasks, kwargs): notifications, services, tasks, kwargs):
self.__args = kwargs self._args = kwargs
self.__configuration = configuration self._configuration = configuration
self.__enabled = True self._enabled = True
self.__environment = environment self._environment = environment
self.__host = monitor_configuration.get('monitor', 'host') self._host = monitor_configuration.get('monitor', 'host')
try: try:
self.__hostgroups = monitor_configuration.get('monitor', 'hostgroups') self._hostgroups = monitor_configuration.get('monitor', 'hostgroups')
except configparser.NoOptionError as err: except configparser.NoOptionError as err:
self.__hostgroups = "None" self._hostgroups = "None"
self.__identifier = identifier self._identifier = identifier
self.__job_threshold = 0 self._job_threshold = 0
try: try:
self.__interval = int(monitor_configuration.get('monitor', 'interval')) self._interval = int(monitor_configuration.get('monitor', 'interval'))
except Exception as err: except Exception as err:
log.warning('no interval set in identifier ' + identifier + log.warning('no interval set in identifier ' + identifier +
', trying to get a monitor configuration setting. error: ' + str(err)) ', trying to get a monitor configuration setting. error: ' + str(err))
try: try:
self.__interval = int(configuration.get_option('linspector', 'default_interval')) self._interval = int(configuration.get_option('linspector', 'default_interval'))
log.warning('set default_interval as per core configuration with ' log.warning('set default_interval as per core configuration with '
'identifier: ' + identifier + ' to: ' + str(self.__interval)) 'identifier: ' + identifier + ' to: ' + str(self._interval))
except Exception as err: except Exception as err:
log.warning('no default_interval found in core configuration for identifier ' + log.warning('no default_interval found in core configuration for identifier ' +
identifier + identifier +
', set to default interval 300 seconds. error: ' + str(err)) ', set to default interval 300 seconds. error: ' + str(err))
# default interval is 300 seconds (5 minutes) if not set in the monitor # default interval is 300 seconds (5 minutes) if not set in the monitor
# configuration args or a default_interval in the core configuration. # configuration args or a default_interval in the core configuration.
self.__interval = 300 self._interval = 300
self.__log = log self._log = log
self.__monitor_configuration = monitor_configuration self._monitor_configuration = monitor_configuration
self.__notification_list = [] self._notification_list = []
self.__notifications = notifications self._notifications = notifications
self.__scheduler_job = None self._result = None
self._scheduler_job = None
try: try:
self.__service = monitor_configuration.get('monitor', 'service') self._service = monitor_configuration.get('monitor', 'service')
except Exception as err: except Exception as err:
# if no service is set in the monitor configuration, the service is set to misc.dummy # if no service is set in the monitor configuration, the service is set to misc.dummy
# instead. just to make Linspector run but with no real result. # instead. just to make Linspector run but with no real result.
@ -59,20 +60,21 @@ class Monitor:
'Linspector will run. ' 'Linspector will run. '
'error: ' + str(err)) 'error: ' + str(err))
self.__service = 'misc.dummy' self._service = 'misc.dummy'
self.__services = services self._services = services
self.__task_list = [] # put tasks for the dedicated job here. self._task = None
self.__tasks = tasks self._task_list = [] # put tasks for the dedicated job here.
self._tasks = tasks
""" """
NONE job was not executed NONE job was not executed: -1
OK when everything is fine OK when everything is fine: 0
WARNING when a job has errors but the threshold is not overridden WARNING when a job has errors but the threshold is not overridden: 1
RECOVER when a job recovers e.g. the threshold decrements (not implemented) RECOVER when a job recovers e.g. the threshold decrements (not implemented): 2
ERROR when a jobs error threshold is overridden ERROR when a jobs error threshold is overridden: 3
UNKNOWN when a job throws an exception which is not handled by the job itself (not UNKNOWN when a job throws an exception which is not handled by the job itself (not
implemented) implemented) :4
self.status = "NONE" self.status = "NONE"
self.last_execution = None self.last_execution = None
""" """
@ -94,7 +96,7 @@ class Monitor:
else: else:
notification_list = None notification_list = None
self.__notification_list = notification_list.split(',') self._notification_list = notification_list.split(',')
for notification_option in notification_list.split(','): for notification_option in notification_list.split(','):
if notification_option not in notifications: if notification_option not in notifications:
@ -103,86 +105,85 @@ class Monitor:
notification = notification_module.create(configuration, environment, log) notification = notification_module.create(configuration, environment, log)
notifications[notification_option.lower()] = notification notifications[notification_option.lower()] = notification
except configparser.NoOptionError as err: except configparser.NoOptionError as err:
self.__notifications = notifications self._notifications = notifications
if self.__monitor_configuration.get('monitor', 'service'): if self._monitor_configuration.get('monitor', 'service'):
if monitor_configuration.get('monitor', 'service') not in services: if monitor_configuration.get('monitor', 'service') not in services:
service_package = 'linspector.services.' + \ service_package = 'linspector.services.' + \
monitor_configuration.get('monitor', 'service').lower() monitor_configuration.get('monitor', 'service').lower()
service_module = importlib.import_module(service_package) service_module = importlib.import_module(service_package)
self.__service = monitor_configuration.get('monitor', 'service').lower() self._service = monitor_configuration.get('monitor', 'service').lower()
service = service_module.create(configuration, environment, log) service = service_module.create(configuration, environment, log)
self.__services[monitor_configuration.get('monitor', 'service').lower()] = service self._services[monitor_configuration.get('monitor', 'service').lower()] = service
try:
if configuration.get_option('linspector', 'tasks') or \
monitor_configuration.get('args', 'tasks'):
if configuration.get_option('linspector', 'tasks') and \ if self._configuration.get_option('linspector', 'tasks'):
monitor_configuration.get('args', 'tasks'): self._log.info(self._configuration.get_option('linspector', 'tasks'))
task_list = configuration.get_option('linspector', 'tasks') + ',' + \ task_list = self._configuration.get_option('linspector', 'tasks')
monitor_configuration.get('args', 'tasks')
elif configuration.get_option('linspector', 'tasks'):
task_list = configuration.get_option('linspector', 'tasks')
elif monitor_configuration.get('args', 'tasks'):
task_list = monitor_configuration.get('args', 'tasks')
else:
task_list = None
self.__task_list = task_list.split(',') self._task_list = task_list.split(',')
self._log.info(self._task_list)
for task_option in task_list.split(','): for task in self._task_list:
if task_option not in tasks: if self._task is None:
task_package = 'linspector.tasks.' + task_option.lower() task_package = 'linspector.tasks.' + task
task_module = importlib.import_module(task_package) task_module = importlib.import_module(task_package)
task = task_module.create(configuration, environment, log) self._task = task_module.create(self._configuration, self._environment,
tasks[task_option.lower()] = task self._log)
except configparser.NoOptionError:
self.__tasks = tasks
def execute(self): def execute(self):
self.__log.debug('identifier=' + self.__identifier + ' object=' + str(self)) self._log.debug('identifier=' + self._identifier + ' object=' + str(self))
self.__log.debug('identifier=' + self.__identifier + ' message=handle call to service') self._log.debug('identifier=' + self._identifier + ' message=handle call to service')
if self.__enabled: if self._enabled:
try: try:
self.__services[self.__service].execute(self.__identifier, self, self.__service, self._result = self._services[self._service].execute(self._identifier, self,
**self.__args) self._service, **self._args)
if self._task is not None:
self._task.execute()
print("task: " + str(self._task))
print("identifier: " + self._identifier)
print("service: " + self._service)
print("status: " + self._result['status'])
print("message: " + self._result['message'])
print("json: " + str(self._result))
except Exception as err: except Exception as err:
self.__log.error(err) self._log.error(err)
else: else:
self.__log.info('identifier=' + self.__identifier + ' message=is disabled') self._log.info('identifier=' + self._identifier + ' message=is disabled')
def get_host(self): def get_host(self):
return self.__host return self._host
def get_hostgroups(self): def get_hostgroups(self):
return self.__hostgroups return self._hostgroups
def get_identifier(self): def get_identifier(self):
return self.__identifier return self._identifier
def get_interval(self): def get_interval(self):
return self.__interval return self._interval
def get_monitor_configuration(self): def get_monitor_configuration(self):
return self.__monitor_configuration return self._monitor_configuration
def get_monitor_configuration_option(self, section, option): def get_monitor_configuration_option(self, section, option):
if self.__monitor_configuration.has_option(section, option): if self._monitor_configuration.has_option(section, option):
return self.__monitor_configuration.get(section, option) return self._monitor_configuration.get(section, option)
else: else:
return None return None
def get_service(self): def get_service(self):
return self.__service return self._service
def set_enabled(self, enabled=True): def set_enabled(self, enabled=True):
self.__enabled = enabled self._enabled = enabled
def set_job(self, scheduler_job): def set_job(self, scheduler_job):
self.__scheduler_job = scheduler_job self._scheduler_job = scheduler_job
def __str__(self): def _str_(self):
return str(self.__dict__) return str(self._dict_)

View file

@ -18,18 +18,18 @@ from linspector.monitor import Monitor
# to lish which walks thrue all scheduled jobs and when an unknown monitor is found, schedule it. # to lish which walks thrue all scheduled jobs and when an unknown monitor is found, schedule it.
class Monitors: class Monitors:
def __init__(self, configuration, environment, log, notifications, services, tasks): def __init__(self, configuration, environment, log, notifications, services, tasks):
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log
self.__notifications = notifications self._notifications = notifications
self.__monitors = {} self._monitors = {}
self.__services = services self._services = services
self.__tasks = tasks self._tasks = tasks
monitor_groups = os.listdir(self.__configuration.get_configuration_path() + '/monitors/') monitor_groups = os.listdir(self._configuration.get_configuration_path() + '/monitors/')
log.debug('monitor groups: ' + str(monitor_groups)) log.debug('monitor groups: ' + str(monitor_groups))
for monitor_group in monitor_groups: for monitor_group in monitor_groups:
monitors_file_list = glob.glob(self.__configuration.get_configuration_path() + monitors_file_list = glob.glob(self._configuration.get_configuration_path() +
'/monitors/' + monitor_group + '/*.conf') '/monitors/' + monitor_group + '/*.conf')
log.debug('monitor files: ' + str(monitors_file_list)) log.debug('monitor files: ' + str(monitors_file_list))
@ -56,17 +56,17 @@ class Monitors:
# create Monitor() object and copy monitor_configuration for each instance because # create Monitor() object and copy monitor_configuration for each instance because
# they else refer to the same object? copy.deepcopy(monitor_configuration)??? # they else refer to the same object? copy.deepcopy(monitor_configuration)???
self.__monitors[identifier] = Monitor(self.__configuration, self._monitors[identifier] = Monitor(self._configuration,
self.__environment, self._environment,
identifier, identifier,
self.__log, self._log,
monitor_configuration, monitor_configuration,
self.__notifications, self._notifications,
self.__services, self._services,
self.__tasks, self._tasks,
kwargs) kwargs)
del kwargs del kwargs
def get_monitors(self): def get_monitors(self):
return self.__monitors return self._monitors

View file

@ -8,6 +8,6 @@ See LICENSE (MIT license).
class Notification: class Notification:
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__() super().__init__()
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log

View file

@ -7,7 +7,7 @@ See LICENSE (MIT license).
class Plugin: class Plugin:
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
self.__log = log self._log = log

View file

@ -17,10 +17,10 @@ def create(configuration, environment, linspector, log):
class APIPlugin(Plugin): class APIPlugin(Plugin):
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
super().__init__(configuration, environment, linspector, log) super().__init__(configuration, environment, linspector, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
self.__log = log self._log = log
def run(self): def run(self):
return return

View file

@ -19,9 +19,9 @@ class HTTPDPlugin(Plugin):
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
super().__init__(configuration, environment, linspector, log) super().__init__(configuration, environment, linspector, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
@cherrypy.expose @cherrypy.expose
def index(self): def index(self):
@ -30,21 +30,21 @@ class HTTPDPlugin(Plugin):
@cherrypy.expose @cherrypy.expose
def configuration(self): def configuration(self):
return '<!DOCTYPE html><html><head><title>[monipy-' + \ return '<!DOCTYPE html><html><head><title>[monipy-' + \
self.__environment.get_env_var("__version__") + '@' + \ self._environment.get_env_var("_version_") + '@' + \
self.__environment.get_env_var("_hostname") + '] configuration</title><meta ' + \ self._environment.get_env_var("_hostname") + '] configuration</title><meta ' + \
'http-equiv="refresh" content="60"></head><body><pre ' + \ 'http-equiv="refresh" content="60"></head><body><pre ' + \
'style="border:2px solid black;background:#1d2021;color:#f0751a;">' + \ 'style="border:2px solid black;background:#1d2021;color:#f0751a;">' + \
json.dumps(vars(self.__configuration), sort_keys=True, indent=4) + \ json.dumps(vars(self._configuration), sort_keys=True, indent=4) + \
'</pre></body></html>' '</pre></body></html>'
@cherrypy.expose @cherrypy.expose
def environment(self): def environment(self):
return '<!DOCTYPE html><html><head><title>[monipy-' + \ return '<!DOCTYPE html><html><head><title>[monipy-' + \
self.__environment.get_env_var("__version__") + '@' + \ self._environment.get_env_var("_version_") + '@' + \
self.__environment.get_env_var("_hostname") + '] environment</title><meta ' + \ self._environment.get_env_var("_hostname") + '] environment</title><meta ' + \
'http-equiv="refresh" content="60"></head><body><pre ' + \ 'http-equiv="refresh" content="60"></head><body><pre ' + \
'style="border:2px solid black;background:#1d2021;color:#f0751a;">' + \ 'style="border:2px solid black;background:#1d2021;color:#f0751a;">' + \
json.dumps(vars(self.__environment), sort_keys=True, indent=4) + \ json.dumps(vars(self._environment), sort_keys=True, indent=4) + \
'</pre></body></html>' '</pre></body></html>'
@cherrypy.expose @cherrypy.expose
@ -81,8 +81,8 @@ class HTTPDPlugin(Plugin):
# }) # })
cherrypy.config.update({ cherrypy.config.update({
'global': { 'global': {
'server.socket_host': self.__configuration.get_httpserver_host(), 'server.socket_host': self._configuration.get_httpserver_host(),
'server.socket_port': self.__configuration.get_httpserver_port(), 'server.socket_port': self._configuration.get_httpserver_port(),
'environment': 'production' 'environment': 'production'
} }
}) })

View file

@ -17,10 +17,10 @@ def create(configuration, environment, linspector, log):
class LishPlugin(Plugin): class LishPlugin(Plugin):
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
super().__init__(configuration, environment, linspector, log) super().__init__(configuration, environment, linspector, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
self.__log = log self._log = log
def run(self): def run(self):
return return

View file

@ -14,10 +14,10 @@ def create(configuration, environment, linspector, log):
class RPCPlugin(Plugin): class RPCPlugin(Plugin):
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
super().__init__(configuration, environment, linspector, log) super().__init__(configuration, environment, linspector, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
self.__log = log self._log = log
def run(self): def run(self):
return return

View file

@ -16,10 +16,10 @@ def create(configuration, environment, linspector, log):
class SyslogPlugin(Plugin): class SyslogPlugin(Plugin):
def __init__(self, configuration, environment, linspector, log): def __init__(self, configuration, environment, linspector, log):
super().__init__(configuration, environment, linspector, log) super().__init__(configuration, environment, linspector, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__linspector = linspector self._linspector = linspector
self.__log = log self._log = log
def run(self): def run(self):
return return

View file

@ -21,4 +21,5 @@ class DummyService(Service):
' host=' + monitor.get_host() + ' host=' + monitor.get_host() +
' service=' + service + ' service=' + service +
' status=' + 'OK') ' status=' + 'OK')
return True
return {"status": 'OK', "message": "Hello from Dummy Service."}

View file

@ -39,4 +39,7 @@ class RandomService(Service):
' service=' + service + ' service=' + service +
' status=' + ('OK' if status == 0 else 'ERROR') + ' message=' + ' status=' + ('OK' if status == 0 else 'ERROR') + ' message=' +
sha512) sha512)
return True
result = {"status": ('OK' if status == 0 else 'ERROR'), "message": sha512}
return result

View file

@ -18,26 +18,26 @@ def create(configuration, environment, log):
class SpeedtestService(Service): class SpeedtestService(Service):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log
self.__speedtest_maximum_speed = None self._speedtest_maximum_speed = None
self.__speedtest_average_speed = None self._speedtest_average_speed = None
self.__speedtest_time_elapsed = None self._speedtest_time_elapsed = None
def execute(self, **kwargs): def execute(self, **kwargs):
while True: while True:
tmp_time = time.localtime(calendar.timegm(time.gmtime())) tmp_time = time.localtime(calendar.timegm(time.gmtime()))
self.__environment.set_env_var('_speedtest_last_run_date', self._environment.set_env_var('_speedtest_last_run_date',
time.strftime('%Y-%m-%d %H:%M:%S', time.strftime('%Y-%m-%d %H:%M:%S',
tmp_time)) tmp_time))
self.__environment.set_env_var('_speedtest_last_run_timestamp', self._environment.set_env_var('_speedtest_last_run_timestamp',
calendar.timegm(time.gmtime())) calendar.timegm(time.gmtime()))
start = time.perf_counter() start = time.perf_counter()
request = requests.get(self.__configuration.get_speedtest_url(), stream=True) request = requests.get(self._configuration.get_speedtest_url(), stream=True)
size = int(request.headers.get('Content-Length')) size = int(request.headers.get('Content-Length'))
downloaded = 0.0 downloaded = 0.0
total_mbps = 0.0 total_mbps = 0.0
@ -54,21 +54,21 @@ class SpeedtestService(Service):
total_chunks += 1 total_chunks += 1
total_mbps += mbps total_mbps += mbps
self.__speedtest_average_speed = total_mbps / total_chunks self._speedtest_average_speed = total_mbps / total_chunks
self.__environment.set_env_var('_speedtest_average_speed_megabyte_per_second', self._environment.set_env_var('_speedtest_average_speed_megabyte_per_second',
str(round(self.__speedtest_average_speed))) str(round(self._speedtest_average_speed)))
self.__speedtest_maximum_speed = maximum_speed self._speedtest_maximum_speed = maximum_speed
self.__environment.set_env_var('_speedtest_maximum_speed_megabyte_per_second', self._environment.set_env_var('_speedtest_maximum_speed_megabyte_per_second',
str(round(self.__speedtest_maximum_speed))) str(round(self._speedtest_maximum_speed)))
self.__speedtest_time_elapsed = time.perf_counter() - start self._speedtest_time_elapsed = time.perf_counter() - start
self.__environment.set_env_var('_speedtest_time_elapsed', self._environment.set_env_var('_speedtest_time_elapsed',
str(self.__speedtest_time_elapsed)) str(self._speedtest_time_elapsed))
self.__log.info('speedtest average: ' + str(self.__speedtest_average_speed) + self._log.info('speedtest average: ' + str(self._speedtest_average_speed) +
', max: ' + str(self.__speedtest_maximum_speed) + ', max: ' + str(self._speedtest_maximum_speed) +
', time: ' + str(self.__speedtest_time_elapsed)) ', time: ' + str(self._speedtest_time_elapsed))
else: else:
self.__log.warning('could not calculate download speed!') self._log.warning('could not calculate download speed!')
time.sleep(self.__configuration.get_speedtest_interval()) time.sleep(self._configuration.get_speedtest_interval())

View file

@ -15,6 +15,7 @@ def create(configuration, environment, log):
class IsConnectedService(Service): class IsConnectedService(Service):
def execute(self, identifier, monitor, service, **kwargs): def execute(self, identifier, monitor, service, **kwargs):
self._log.debug('identifier=' + identifier + self._log.debug('identifier=' + identifier +
' service=' + service + ' service=' + service +
' object=' + str(self) + ' object=' + str(self) +
@ -34,7 +35,6 @@ class IsConnectedService(Service):
' service=' + service + ' service=' + service +
' status=' + ('OK' if fc.is_connected else 'ERROR')) ' status=' + ('OK' if fc.is_connected else 'ERROR'))
if fc.is_connected: result = {"status": ('OK' if fc.is_connected else 'ERROR'), "message": "CUSTOM"}
return True
else: return result
return False

View file

@ -19,7 +19,7 @@ class Singleton:
no restrictions that apply to the decorated class. no restrictions that apply to the decorated class.
To get the singleton instance, use the `Instance` method. Trying To get the singleton instance, use the `Instance` method. Trying
to use `__call__` will result in a `TypeError` being raised. to use `_call_` will result in a `TypeError` being raised.
Limitations: The decorated class cannot be inherited from. Limitations: The decorated class cannot be inherited from.
@ -42,8 +42,8 @@ class Singleton:
self._instance = self._decorated() self._instance = self._decorated()
return self._instance return self._instance
def __call__(self): def _call_(self):
raise TypeError('Singletons must be accessed through `Instance()`.') raise TypeError('Singletons must be accessed through `Instance()`.')
def __instancecheck__(self, inst): def _instancecheck_(self, inst):
return isinstance(inst, self._decorated) return isinstance(inst, self._decorated)

View file

@ -15,10 +15,10 @@ KEY_CLASS = "class"
class Task: class Task:
def __init__(self, configuration, environment, log, **kwargs): def __init__(self, configuration, environment, log, **kwargs):
self.__args = {} self._args = {}
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log
if KEY_ARGS in kwargs: if KEY_ARGS in kwargs:
self.add_arguments(kwargs[KEY_ARGS]) self.add_arguments(kwargs[KEY_ARGS])
@ -42,10 +42,10 @@ class Task:
def add_arguments(self, args): def add_arguments(self, args):
for key, val in args.items(): for key, val in args.items():
self.__args[key] = val self._args[key] = val
def get_arguments(self): def get_arguments(self):
return self.__args return self._args
# def set_member(self, member): # def set_member(self, member):
# self.member = member # self.member = member
@ -69,9 +69,9 @@ class Task:
@Singleton @Singleton
class TaskRunner: class TaskRunner:
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log
self.queue = Queue() self.queue = Queue()
self.task_infos = [] self.task_infos = []
task_thread = Thread(target=self._run_worker_thread) task_thread = Thread(target=self._run_worker_thread)
@ -86,12 +86,12 @@ class TaskRunner:
try: try:
msg, task = self.queue.get() msg, task = self.queue.get()
if task: if task:
self.__log.debug('starting task execution...') self._log.debug('starting task execution...')
# task.execute(msg) # task.execute(msg)
self.queue.task_done() self.queue.task_done()
except Exception as err: except Exception as err:
self.__log.error('error ' + str(err)) self._log.error('error ' + str(err))
def is_instant_end(self): def is_instant_end(self):
return self._instant_end return self._instant_end

View file

@ -14,6 +14,9 @@ def create(configuration, environment, log):
class CSVTask(Task): class CSVTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log
def execute(self):
print("Hello from CSV Task...")

View file

@ -14,6 +14,6 @@ def create(configuration, environment, log):
class FileTask(Task): class FileTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log

View file

@ -14,6 +14,9 @@ def create(configuration, environment, log):
class MariaDBTask(Task): class MariaDBTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log
def execute(self):
print("Hello from MariaDB Task...")

View file

@ -14,6 +14,6 @@ def create(configuration, environment, log):
class RedisTask(Task): class RedisTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log

View file

@ -14,6 +14,6 @@ def create(configuration, environment, log):
class SplunkTask(Task): class SplunkTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log

View file

@ -14,6 +14,6 @@ def create(configuration, environment, log):
class SQLiteTask(Task): class SQLiteTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log

View file

@ -14,6 +14,6 @@ def create(configuration, environment, log):
class SyslogTask(Task): class SyslogTask(Task):
def __init__(self, configuration, environment, log): def __init__(self, configuration, environment, log):
super().__init__(configuration, environment, log) super().__init__(configuration, environment, log)
self.__configuration = configuration self._configuration = configuration
self.__environment = environment self._environment = environment
self.__log = log self._log = log