Basic scheduling works now but execution of services is not available. Lot of stuff done...
This commit is contained in:
parent
1420738299
commit
8808b657c4
54 changed files with 538 additions and 199 deletions
|
|
@ -32,7 +32,7 @@ from linspector.core.environment import Environment
|
|||
from linspector.core.linspector import Linspector
|
||||
from linspector.core.monitors import Monitors
|
||||
|
||||
__version__ = '0.19.10'
|
||||
__version__ = '0.19.11.dev1'
|
||||
__author__ = 'Johannes Findeisen <you@hanez.org>'
|
||||
|
||||
logger = logging.getLogger('linspector')
|
||||
|
|
@ -125,6 +125,7 @@ def main():
|
|||
|
||||
try:
|
||||
linspector = Linspector(configuration, environment, monitors, plugins, scheduler)
|
||||
#linspector.print_debug()
|
||||
except Exception as err:
|
||||
logger.critical('[linspector] core initialization error: {0}'.format(err))
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ members = superadmin@example.com,developers@example.com
|
|||
; scheduler configuration
|
||||
start_scheduler = true
|
||||
max_threads = 3500
|
||||
max_processes = 100
|
||||
max_processes = 10
|
||||
timezone = CET
|
||||
|
||||
; hostgroup parents; if the hostgroup "group1" is down, don't alert for the hosts in group2. see TODO.txt for more
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ tasks = redis
|
|||
; internally to single hosts to become a monitor for each host internally. some more ideas are in ;)
|
||||
; hosts with added hostgroup defined in main configuration file
|
||||
hosts = 192.168.0.1,192.168.23.24,@group1,@testgroup1
|
||||
hostgroup = group1
|
||||
user = USERNAME
|
||||
password = PASSWORD
|
||||
info = Cable Provider
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
service = misc.dummy
|
||||
interval = 1
|
||||
3
etc/monitors/test/test10.conf
Normal file
3
etc/monitors/test/test10.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 60
|
||||
3
etc/monitors/test/test2.conf
Normal file
3
etc/monitors/test/test2.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 60
|
||||
3
etc/monitors/test/test3.conf
Normal file
3
etc/monitors/test/test3.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 120
|
||||
3
etc/monitors/test/test4.conf
Normal file
3
etc/monitors/test/test4.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 50
|
||||
3
etc/monitors/test/test5.conf
Normal file
3
etc/monitors/test/test5.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 62
|
||||
3
etc/monitors/test/test6.conf
Normal file
3
etc/monitors/test/test6.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 30
|
||||
3
etc/monitors/test/test7.conf
Normal file
3
etc/monitors/test/test7.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 60
|
||||
3
etc/monitors/test/test8.conf
Normal file
3
etc/monitors/test/test8.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 60
|
||||
3
etc/monitors/test/test9.conf
Normal file
3
etc/monitors/test/test9.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[monitor]
|
||||
service = misc.dummy
|
||||
interval = 240
|
||||
|
|
@ -7,9 +7,7 @@ import configparser
|
|||
import glob
|
||||
import os
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
# TODO: check for all required configuration options and set defaults if needed. do this only for
|
||||
|
|
@ -21,7 +19,8 @@ class Configuration:
|
|||
self.__configuration_path = configuration_path
|
||||
self.__environment = environment
|
||||
|
||||
logger.info('reading configuration file: ' + configuration_path + '/linspector.conf')
|
||||
log('info', __name__, 'reading configuration file: ' + configuration_path +
|
||||
'/linspector.conf')
|
||||
if os.path.isfile(configuration_path + '/linspector.conf'):
|
||||
try:
|
||||
self.__configuration.read(configuration_path + '/linspector.conf', 'utf-8')
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
class Environment:
|
||||
|
|
@ -13,6 +11,7 @@ class Environment:
|
|||
Object for storing environment variables at runtime. These variables must not affect the
|
||||
stability or runtime of Linspector.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.__env = {}
|
||||
|
||||
|
|
@ -20,17 +19,20 @@ class Environment:
|
|||
if key in self.__env:
|
||||
return self.__env[key]
|
||||
else:
|
||||
logger.info('environment var "' + key + '" not found! could be that it is set later at '
|
||||
'runtime. if you encounter any errors '
|
||||
'executing monipyd, something is wrong in the '
|
||||
'logic of the code. please consider reporting '
|
||||
'this as a bug! btw. INFO is not an ERROR! '
|
||||
'monipyd should work even with missing '
|
||||
'environment variables.')
|
||||
log('warning', __name__, 'environment var "' + key + '" not found! could be that it is '
|
||||
'set later at runtime. if you '
|
||||
'encounter any errors executing '
|
||||
'linspector, something is wrong '
|
||||
'in the logic of the code. please '
|
||||
'consider reporting this as a '
|
||||
'bug! btw. WARNING is not an '
|
||||
'ERROR! Linspector should work '
|
||||
'even with missing environment '
|
||||
'variables.')
|
||||
return None
|
||||
|
||||
def set_env_var(self, key, value):
|
||||
if self.__env[key]:
|
||||
logger.warning('environment var "' + key + ' existed and was overwritten!')
|
||||
log('warning', __name__, 'environment var "' + key + ' existed and was overwritten!')
|
||||
|
||||
self.__env[key] = value
|
||||
|
|
|
|||
21
linspector/core/helpers.py
Normal file
21
linspector/core/helpers.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
This file is part of Linspector (https://linspector.org/)
|
||||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def log(level, name, msg):
|
||||
if level == 'critical':
|
||||
logger.critical('[' + name + '] ' + str(msg))
|
||||
if level == 'error':
|
||||
logger.error('[' + name + '] ' + str(msg))
|
||||
elif level == 'warning':
|
||||
logger.warning('[' + name + '] ' + str(msg))
|
||||
elif level == 'info':
|
||||
logger.info('[' + name + '] ' + str(msg))
|
||||
elif level == 'debug':
|
||||
logger.debug('[' + name + '] ' + str(msg))
|
||||
|
|
@ -3,19 +3,19 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
import datetime
|
||||
import importlib
|
||||
|
||||
from logging import getLogger
|
||||
import random
|
||||
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.jobstores.memory import MemoryJobStore
|
||||
from apscheduler.executors.pool import ThreadPoolExecutor # , ProcessPoolExecutor
|
||||
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
def job_function(job):
|
||||
job.handle_call()
|
||||
def job_function(monitor):
|
||||
monitor.handle_call()
|
||||
|
||||
|
||||
class Linspector:
|
||||
|
|
@ -23,19 +23,20 @@ class Linspector:
|
|||
def __init__(self, configuration, environment, monitors, plugins, scheduler):
|
||||
self.__configuration = configuration
|
||||
self.__environment = environment
|
||||
self.__jobs = []
|
||||
self.__monitors = monitors
|
||||
self.__plugin_list = None
|
||||
self.__plugins = plugins
|
||||
self.__scheduler = scheduler
|
||||
|
||||
# load plugins
|
||||
logger.info('loading plugins...')
|
||||
log('info', __name__, 'loading plugins...')
|
||||
if configuration.get_option('linspector', 'plugins'):
|
||||
plugin_list = configuration.get_option('linspector', 'plugins')
|
||||
self.__plugin_list = plugin_list.split(',')
|
||||
for plugin_option in plugin_list.split(','):
|
||||
if plugin_option not in plugins:
|
||||
logger.info('loading plugin: ' + plugin_option)
|
||||
log('info', __name__, 'loading plugin: ' + plugin_option)
|
||||
plugin_package = 'linspector.plugins.' + plugin_option.lower()
|
||||
plugin_module = importlib.import_module(plugin_package)
|
||||
plugin = plugin_module.get(configuration, environment, self)
|
||||
|
|
@ -45,10 +46,10 @@ class Linspector:
|
|||
'memory': MemoryJobStore()
|
||||
}
|
||||
executors = {
|
||||
'default': ThreadPoolExecutor(int(configuration.get_option('linspector',
|
||||
'max_threads'))),
|
||||
#'default': ProcessPoolExecutor(int(configuration.get_option('linspector',
|
||||
# 'max_processes')))
|
||||
#'default': ThreadPoolExecutor(int(configuration.get_option('linspector',
|
||||
# 'max_threads'))),
|
||||
'default': ProcessPoolExecutor(int(configuration.get_option('linspector',
|
||||
'max_processes')))
|
||||
}
|
||||
job_defaults = {
|
||||
'max_instances': 10000
|
||||
|
|
@ -57,6 +58,24 @@ class Linspector:
|
|||
executors=executors,
|
||||
job_defaults=job_defaults)
|
||||
|
||||
start_date = datetime.datetime.now()
|
||||
log('debug', __name__, monitors.get_monitors())
|
||||
monitors = self.__monitors.get_monitors()
|
||||
for monitor in monitors:
|
||||
time_delta = round(random.uniform(1.00, 10.00), 2)
|
||||
new_start_date = start_date + datetime.timedelta(seconds=time_delta)
|
||||
monitor_job = monitors.get(monitor)
|
||||
interval = monitor_job.get_interval()
|
||||
scheduler_job = scheduler['linspector'].add_job(job_function, 'interval',
|
||||
start_date=new_start_date,
|
||||
seconds=interval, timezone="CET",
|
||||
args=[monitors.get(monitor)])
|
||||
|
||||
monitor_job.set_job(scheduler_job)
|
||||
self.__jobs.append(monitor_job)
|
||||
log('info', __name__, 'scheduling job ' + monitor + ' with delta ' + str(time_delta) +
|
||||
' @' + str(new_start_date) + ' running service ')
|
||||
|
||||
if configuration.get_option('linspector', 'start_scheduler') == 'true':
|
||||
self.__scheduler['linspector'].start()
|
||||
|
||||
|
|
@ -64,7 +83,7 @@ class Linspector:
|
|||
def print_debug(self):
|
||||
# example on how to access the monitor objects in monitors
|
||||
monitors = self.__monitors.get_monitors()
|
||||
print(__file__ + ' (59): ' + str(monitors))
|
||||
print(__file__ + ' (78): ' + str(monitors))
|
||||
for monitor in monitors:
|
||||
print(__file__ + ' (61): ' + monitors.get(monitor).get_identifier())
|
||||
print(__file__ + ' (62): ' + monitors.get(monitor).get_service())
|
||||
print(__file__ + ' (80): ' + monitors.get(monitor).get_identifier())
|
||||
print(__file__ + ' (81): ' + monitors.get(monitor).get_service())
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ import signal
|
|||
import sys
|
||||
import time
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
# TODO: there is a bug when stopping the daemon. the pid_file is not being deleted. NEEDS A FIX!
|
||||
|
|
@ -24,7 +22,7 @@ class Linspectord:
|
|||
try:
|
||||
self.__pid_file = configuration.get_option('linspector', 'pid_file')
|
||||
except Exception as err:
|
||||
logger.critical(str('daemonize error (no pid_file set): {0}'.format(err)))
|
||||
log('critical', __name__, str('daemonize error (no pid_file set): {0}'.format(err)))
|
||||
|
||||
def daemonize(self):
|
||||
# daemonize the class using the UNIX double fork mechanism.
|
||||
|
|
@ -36,7 +34,7 @@ class Linspectord:
|
|||
# exit first parent.
|
||||
sys.exit(0)
|
||||
except OSError as err:
|
||||
logger.critical(str('fork #1 failed: {0}'.format(err)))
|
||||
log('critical', __name__, str('fork #1 failed: {0}'.format(err)))
|
||||
sys.exit(1)
|
||||
|
||||
# decouple from parent environment.
|
||||
|
|
@ -51,7 +49,7 @@ class Linspectord:
|
|||
# Exit from second parent.
|
||||
sys.exit(0)
|
||||
except OSError as err:
|
||||
logger.critical(str('fork #2 failed: {0}'.format(err)))
|
||||
log('critical', __name__, str('fork #2 failed: {0}'.format(err)))
|
||||
sys.exit(1)
|
||||
|
||||
# redirect standard file descriptors.
|
||||
|
|
@ -77,7 +75,7 @@ class Linspectord:
|
|||
|
||||
def start(self):
|
||||
# start the daemon. check for a pidfile to see if the daemon already runs before.
|
||||
logger.info('starting daemon using pid_file: ' + self.__pid_file)
|
||||
log('info', __name__, 'starting daemon using pid_file: ' + self.__pid_file)
|
||||
try:
|
||||
with open(self.__pid_file, 'r') as pf:
|
||||
pid = int(pf.read().strip())
|
||||
|
|
@ -86,7 +84,7 @@ class Linspectord:
|
|||
|
||||
if pid:
|
||||
message = 'pid_file {0} already exist. daemon already running?'
|
||||
logger.critical(str(message.format(self.__pid_file)))
|
||||
log('critical', __name__, str(message.format(self.__pid_file)))
|
||||
sys.exit(1)
|
||||
|
||||
# start the daemon.
|
||||
|
|
@ -95,7 +93,7 @@ class Linspectord:
|
|||
|
||||
def stop(self):
|
||||
# stop the daemon.
|
||||
logger.info('stopping daemon using pid_file: ' + self.__pid_file)
|
||||
log('info', __name__, 'stopping daemon using pid_file: ' + self.__pid_file)
|
||||
# get the pid from the pid file.
|
||||
try:
|
||||
with open(self.__pid_file, 'r') as pf:
|
||||
|
|
@ -105,7 +103,7 @@ class Linspectord:
|
|||
|
||||
if not pid:
|
||||
message = 'pid_file {0} does not exist. daemon not running?'
|
||||
logger.error(str(message.format(self.__pid_file)))
|
||||
log('error', __name__, str(message.format(self.__pid_file)))
|
||||
return # not an error in a restart
|
||||
|
||||
# try killing the daemon process.
|
||||
|
|
@ -119,12 +117,12 @@ class Linspectord:
|
|||
if os.path.exists(self.__pid_file):
|
||||
os.remove(self.__pid_file)
|
||||
else:
|
||||
logger.critical(str(err.args))
|
||||
log('critical', __name__, str(err.args))
|
||||
sys.exit(1)
|
||||
|
||||
def restart(self):
|
||||
# restart the daemon.
|
||||
logger.info('restarting daemon using pid_file: ' + self.__pid_file)
|
||||
log('info', __name__, 'restarting daemon using pid_file: ' + self.__pid_file)
|
||||
self.stop()
|
||||
self.start()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
# The logger can be used by any monitor to write arbitrary data to any arbitrary place.
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
# This class can maybe be used for a general data model for Linspector data processing. currently
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ See LICENSE (MIT license)
|
|||
"""
|
||||
import importlib
|
||||
|
||||
from logging import getLogger
|
||||
from datetime import datetime
|
||||
from binascii import crc32
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.task import Task, TaskExecutor
|
||||
|
||||
|
||||
class Monitor:
|
||||
|
|
@ -17,14 +19,38 @@ class Monitor:
|
|||
self.__configuration = configuration
|
||||
self.__environment = environment
|
||||
self.__identifier = identifier
|
||||
self.__interval = int(monitor_configuration.get('monitor', 'interval'))
|
||||
self.__monitor_configuration = monitor_configuration
|
||||
self.__notification_list = []
|
||||
self.__service = None
|
||||
self.__service = monitor_configuration.get('monitor', 'service')
|
||||
self.__notifications = notifications
|
||||
self.__services = services
|
||||
self.__task_list = [] # put tasks for the dedicated job here.
|
||||
self.__tasks = tasks
|
||||
|
||||
self.service = self.__service
|
||||
self.host = monitor_configuration.get('monitor', 'host')
|
||||
#self.members = members
|
||||
#self.core = core
|
||||
self.hostgroup = monitor_configuration.get('monitor', 'hostgroup')
|
||||
self.job_threshold = 0
|
||||
self.enabled = True
|
||||
self.scheduler_job = None
|
||||
self.job_id = self.hex_string()
|
||||
|
||||
"""
|
||||
NONE job was not executed
|
||||
OK when everything is fine
|
||||
WARNING when a job has errors but not the threshold overridden
|
||||
RECOVER when a job recovers e.g. the threshold decrements (not implemented)
|
||||
ERROR when a jobs threshold is overridden
|
||||
UNKNOWN when a job throws an exception which is not handled by the job itself (not implemented)
|
||||
"""
|
||||
self.status = "NONE"
|
||||
self.last_execution = None
|
||||
self.monitor_information = MonitorInformation(self.job_id, self.hostgroup, self.host,
|
||||
self.service)
|
||||
|
||||
if configuration.get_option('linspector', 'notifications') or \
|
||||
monitor_configuration.get('monitor', 'notifications'):
|
||||
|
||||
|
|
@ -47,7 +73,7 @@ class Monitor:
|
|||
if notification_option not in notifications:
|
||||
notification_package = 'linspector.notifications.' + notification_option.lower()
|
||||
notification_module = importlib.import_module(notification_package)
|
||||
notification = notification_module.get(configuration, environment)
|
||||
notification = notification_module.create(configuration, environment)
|
||||
notifications[notification_option.lower()] = notification
|
||||
|
||||
if self.__monitor_configuration.get('monitor', 'service'):
|
||||
|
|
@ -57,7 +83,7 @@ class Monitor:
|
|||
|
||||
service_module = importlib.import_module(service_package)
|
||||
self.__service = monitor_configuration.get('monitor', 'service').lower()
|
||||
service = service_module.get(configuration, environment)
|
||||
service = service_module.create(configuration, environment)
|
||||
services[monitor_configuration.get('monitor', 'service').lower()] = service
|
||||
|
||||
#service.execute(self)
|
||||
|
|
@ -83,14 +109,201 @@ class Monitor:
|
|||
if task_option not in tasks:
|
||||
task_package = 'linspector.tasks.' + task_option.lower()
|
||||
task_module = importlib.import_module(task_package)
|
||||
task = task_module.get(configuration, environment)
|
||||
task = task_module.create(configuration, environment)
|
||||
tasks[task_option.lower()] = task
|
||||
|
||||
def get_identifier(self):
|
||||
return self.__identifier
|
||||
|
||||
def get_interval(self):
|
||||
return self.__interval
|
||||
|
||||
def get_service(self):
|
||||
return self.__service
|
||||
|
||||
# currently only used for testing but maybe i will add get functions for all known variables.
|
||||
# but not all variables can be known because all monitors are different. only the service
|
||||
# implementation can know all variables which are being used inside the service.
|
||||
def get_service(self):
|
||||
return self.__monitor_configuration.get('monitor', 'service')
|
||||
return self.__service
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__dict__)
|
||||
|
||||
def __hex__(self):
|
||||
return hex(crc32(bytes(self.hostgroup + self.host + self.service, 'utf-8')))
|
||||
|
||||
def hex_string(self):
|
||||
ret = self.__hex__()
|
||||
if ret[0] == "-":
|
||||
ret = ret[3:]
|
||||
else:
|
||||
ret = ret[2:]
|
||||
while len(ret) < 8:
|
||||
ret = "0" + ret
|
||||
return ret
|
||||
|
||||
def get_job_id(self):
|
||||
return self.job_id
|
||||
|
||||
def set_job(self, scheduler_job):
|
||||
self.scheduler_job = scheduler_job
|
||||
|
||||
def set_enabled(self, enabled=True):
|
||||
self.enabled = enabled
|
||||
|
||||
def handle_threshold(self, service_threshold, execution_successful):
|
||||
if execution_successful:
|
||||
if self.job_threshold > 0:
|
||||
if "threshold_reset" in self.core and self.core["threshold_reset"]:
|
||||
#logger.info("Job " + self.get_job_id() + ", Threshold Reset")
|
||||
self.job_threshold = 0
|
||||
else:
|
||||
#logger.info("Job " + self.get_job_id() + ", Threshold Decrement")
|
||||
self.job_threshold -= 1
|
||||
|
||||
self.status = "OK"
|
||||
self.monitor_information.set_status(self.status)
|
||||
self.monitor_information.inc_job_overall_wins()
|
||||
else:
|
||||
self.status = "WARNING"
|
||||
self.monitor_information.set_status(self.status)
|
||||
self.monitor_information.inc_job_overall_fails()
|
||||
self.job_threshold += 1
|
||||
|
||||
if self.job_threshold >= service_threshold:
|
||||
#logger.info("Job " + self.get_job_id() + ", Threshold reached!")
|
||||
self.status = "ERROR"
|
||||
self.monitor_information.set_status(self.status)
|
||||
|
||||
def handle_tasks(self, monitor_information):
|
||||
for task in self.__tasks:
|
||||
if self.status.lower() in task.get_task_type().lower():
|
||||
log('debug', __name__, 'executing task of type: ' + self.status)
|
||||
# tasks can but should not be executed here. putting them in a queue is the better
|
||||
# solution to execute them in a serial process.
|
||||
#TaskExecutor.instance().schedule_task(monitor_information, task)
|
||||
|
||||
def handle_call(self):
|
||||
log('info', __name__, "handle call to identifier: " + self.__identifier)
|
||||
#logger.debug("handle call")
|
||||
#logger.debug(self.service)
|
||||
if self.enabled:
|
||||
self.last_execution = None
|
||||
try:
|
||||
self.last_execution = MonitorExecution(self.get_host())
|
||||
self.service.execute(self.last_execution)
|
||||
except Exception as err:
|
||||
log.debug('debug', __name__, err)
|
||||
|
||||
self.last_execution.set_execution_end()
|
||||
|
||||
self.handle_threshold(self.service.get_threshold(),
|
||||
self.last_execution.was_successful())
|
||||
|
||||
#logger.info("Job " + self.get_job_id() +
|
||||
# ", Code: " + str(self.last_execution.get_error_code()) +
|
||||
# ", Message: " + str(self.last_execution.get_message()))
|
||||
|
||||
self.monitor_information.set_response_message(
|
||||
self.last_execution.get_response_message(self))
|
||||
|
||||
self.handle_tasks(self.monitor_information)
|
||||
else:
|
||||
log('info', __name__, "job " + self.get_job_id() + " disabled")
|
||||
|
||||
def get_host(self):
|
||||
return self.host
|
||||
|
||||
def get_hostgroup(self):
|
||||
return self.hostgroup
|
||||
|
||||
|
||||
class MonitorExecution:
|
||||
def __init__(self, host):
|
||||
self.execution_start = datetime.now()
|
||||
self.execution_end = -1
|
||||
self.host = host
|
||||
self.error_code = -1
|
||||
self.message = None
|
||||
self.kwargs = None
|
||||
|
||||
def get_host_name(self):
|
||||
return self.host
|
||||
|
||||
def get_message(self):
|
||||
return self.message
|
||||
|
||||
def get_kwargs(self):
|
||||
return self.kwargs
|
||||
|
||||
def set_execution_end(self):
|
||||
self.execution_end = datetime.now()
|
||||
|
||||
def get_error_code(self):
|
||||
return self.error_code
|
||||
|
||||
def was_successful(self):
|
||||
return self.get_error_code() == 0
|
||||
|
||||
def set_result(self, error_code=0, message="", kwargs=None):
|
||||
self.error_code = error_code
|
||||
self.message = message
|
||||
self.kwargs = kwargs
|
||||
|
||||
def get_response_message(self, job):
|
||||
msg = str(job.status) + " [" + job.service.get_config_name() + ": " + str(job.get_job_id()) + "] " + \
|
||||
str(job.get_hostgroup()) + " " + str(job.get_host())
|
||||
if self.get_message() is not None:
|
||||
msg += " " + str(self.get_message())
|
||||
if self.get_kwargs() is not None:
|
||||
msg += " " + str(self.get_kwargs())
|
||||
return msg
|
||||
|
||||
|
||||
class MonitorInformation:
|
||||
def __init__(self, job_id, hostgroup, host, service):
|
||||
self.job_id = job_id
|
||||
self.hostgroup = hostgroup
|
||||
self.host = host
|
||||
self.service = service
|
||||
|
||||
self.response_massage = None
|
||||
self.period = None
|
||||
self.next_run = None
|
||||
self.runs = 0
|
||||
self.enabled = None
|
||||
self.threshold = 0
|
||||
self.fails = 0
|
||||
self.job_overall_fails = 0
|
||||
self.job_overall_wins = 0
|
||||
self.last_execution = None
|
||||
self.last_run = None
|
||||
self.last_fail = None
|
||||
self.last_success = None
|
||||
self.last_disabled = None
|
||||
self.last_enabled = None
|
||||
self.last_threshold_override = None
|
||||
self.last_escalation = None
|
||||
self.status = "NONE"
|
||||
|
||||
def inc_job_overall_fails(self):
|
||||
self.job_overall_fails += 1
|
||||
|
||||
def inc_job_overall_wins(self):
|
||||
self.job_overall_wins += 1
|
||||
|
||||
def get_job_id(self):
|
||||
return self.job_id
|
||||
|
||||
def get_response_message(self):
|
||||
return self.response_massage
|
||||
|
||||
def set_response_message(self, msg):
|
||||
self.response_massage = msg
|
||||
|
||||
def get_status(self):
|
||||
return self.status
|
||||
|
||||
def set_status(self, status):
|
||||
self.status = status
|
||||
|
|
|
|||
|
|
@ -8,12 +8,8 @@ import copy
|
|||
import glob
|
||||
import os
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.monitor import Monitor
|
||||
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
# monitors may could / should be added (and maybe changed) at runtime to add new monitors without
|
||||
|
|
@ -27,12 +23,12 @@ class Monitors:
|
|||
self.__monitors = {}
|
||||
|
||||
monitor_groups = os.listdir(self.__configuration.get_configuration_path() + '/monitors/')
|
||||
logger.debug('[' + __name__ + '] monitor groups: ' + str(monitor_groups))
|
||||
log('debug', __name__, 'monitor groups: ' + str(monitor_groups))
|
||||
monitor_configuration = configparser.ConfigParser()
|
||||
for monitor_group in monitor_groups:
|
||||
monitors_file_list = glob.glob(self.__configuration.get_configuration_path() +
|
||||
'/monitors/' + monitor_group + '/*.conf')
|
||||
logger.debug('[' + __name__ + '] monitor files: ' + str(monitors_file_list))
|
||||
log('debug', __name__, 'monitor files: ' + str(monitors_file_list))
|
||||
for monitor_file in monitors_file_list:
|
||||
monitor_configuration.read(monitor_file, 'utf-8')
|
||||
|
||||
|
|
@ -41,9 +37,9 @@ class Monitors:
|
|||
|
||||
# create Monitor() object and copy monitor_configuration for each instance because
|
||||
# they else refer to the same object.
|
||||
self.__monitors[identifier] = Monitor(configuration, environment, identifier,
|
||||
self.__monitors[identifier] = copy.deepcopy(Monitor(configuration, environment, identifier,
|
||||
copy.deepcopy(monitor_configuration),
|
||||
notifications, services, tasks)
|
||||
notifications, services, tasks))
|
||||
|
||||
def get_monitors(self):
|
||||
return self.__monitors
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
class Notification:
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
from apscheduler.util import convert_to_datetime
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
class Period(object):
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
|
||||
|
||||
class Service:
|
||||
|
|
|
|||
|
|
@ -3,13 +3,100 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
from queue import Queue
|
||||
from threading import Event, Thread
|
||||
|
||||
logger = getLogger('linspector')
|
||||
from linspector.core.helpers import log
|
||||
from linspector.utils.singleton import Singleton
|
||||
|
||||
KEY_TYPE = "type"
|
||||
KEY_ARGS = "args"
|
||||
KEY_CLASS = "class"
|
||||
|
||||
|
||||
class Task:
|
||||
|
||||
def __init__(self, configuration, environment):
|
||||
def __init__(self, configuration, environment, **kwargs):
|
||||
self.__configuration = configuration
|
||||
self._environment = environment
|
||||
|
||||
self._args = {}
|
||||
if KEY_ARGS in kwargs:
|
||||
self.add_arguments(kwargs[KEY_ARGS])
|
||||
elif self.needs_arguments():
|
||||
raise Exception("Error: needs arguments but none provided!")
|
||||
|
||||
if KEY_CLASS in kwargs:
|
||||
self.name = kwargs[KEY_CLASS]
|
||||
else:
|
||||
self.name = self.__class__
|
||||
|
||||
self._type = None
|
||||
if KEY_TYPE in kwargs:
|
||||
self._type = kwargs[KEY_TYPE]
|
||||
|
||||
def get_task_type(self):
|
||||
return str(self._type)
|
||||
|
||||
def get_config_name(self):
|
||||
return str(self.name)
|
||||
|
||||
def add_arguments(self, args):
|
||||
for key, val in args.items():
|
||||
self._args[key] = val
|
||||
|
||||
def get_arguments(self):
|
||||
return self._args
|
||||
|
||||
#def set_member(self, member):
|
||||
# self.member = member
|
||||
|
||||
def needs_arguments(self):
|
||||
return False
|
||||
|
||||
def execute(self, job):
|
||||
try:
|
||||
self.execute(job)
|
||||
except Exception as e:
|
||||
#logger.debug("Task execute failed!!!")
|
||||
raise e
|
||||
|
||||
|
||||
@Singleton
|
||||
class TaskExecutor:
|
||||
def __init__(self):
|
||||
self.queue = Queue()
|
||||
self.taskInfos = []
|
||||
task_thread = Thread(target=self._run_worker_thread)
|
||||
self._instantEnd = False
|
||||
self._running = True
|
||||
task_thread.daemon = True
|
||||
task_thread.start()
|
||||
|
||||
def _run_worker_thread(self):
|
||||
while self.is_running() or not self.is_instant_end():
|
||||
|
||||
try:
|
||||
msg, task = self.queue.get()
|
||||
if task:
|
||||
log('debug', __name__, "starting task execution...")
|
||||
#task.execute(msg)
|
||||
self.queue.task_done()
|
||||
|
||||
except Exception as err:
|
||||
log('error', __name__, "error " + str(err))
|
||||
|
||||
def is_instant_end(self):
|
||||
return self._instantEnd
|
||||
|
||||
def is_running(self):
|
||||
return self._running
|
||||
|
||||
def stop(self):
|
||||
self._running = False
|
||||
|
||||
def stop_immediately(self):
|
||||
self._running = False
|
||||
self._instantEnd = True
|
||||
|
||||
def schedule_task(self, msg, task):
|
||||
self.queue.put((msg, task))
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.notification import Notification
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return CallNotification(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.notification import Notification
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return EmailNotification(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
import gammu
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.notification import Notification
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return SMSNotification(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.notification import Notification
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return TwitterNotification(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,13 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
import xmpp
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.notification import Notification
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return XMPPNotification(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,9 @@ See LICENSE (MIT license)
|
|||
import cherrypy
|
||||
import json
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.plugin import Plugin
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment, linspector):
|
||||
return HTTPServerPlugin(configuration, environment, linspector)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,9 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.plugin import Plugin
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment, linspector):
|
||||
return LishPlugin(configuration, environment, linspector)
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return HTTPKeywordService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return DummyService(configuration, environment)
|
||||
|
||||
|
||||
|
|
@ -22,4 +19,5 @@ class DummyService(Service):
|
|||
self.__environment = environment
|
||||
|
||||
def execute(self):
|
||||
log('debug', __name__, 'dummy object @' + str(self))
|
||||
return
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return RandomService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,12 @@ Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
|||
See LICENSE (MIT)
|
||||
"""
|
||||
from fritzconnection.lib.fritzstatus import FritzStatus
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return FritzboxUplinkService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return PingService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,14 +5,11 @@ See LICENSE (MIT license)
|
|||
"""
|
||||
import socket
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return PortService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,14 +7,11 @@ import calendar
|
|||
import requests
|
||||
import time
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return SpeedtestService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,15 +7,11 @@ import os
|
|||
import paramiko
|
||||
import pprint
|
||||
|
||||
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return SSHService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return TCPConnectService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,13 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
from pysnmp.entity.rfc3413.oneliner import cmdgen
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return GetService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return ShellService(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,9 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.service import Service
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
return UptimeService(configuration, environment)
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.task import Task
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return CSVTask(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.task import Task
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return FileLoggerTask(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.task import Task
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return MariaDBTask(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.task import Task
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return RedisTask(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ This file is part of Linspector (https://linspector.org/)
|
|||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
from logging import getLogger
|
||||
|
||||
from linspector.core.helpers import log
|
||||
from linspector.core.task import Task
|
||||
|
||||
logger = getLogger('linspector')
|
||||
|
||||
|
||||
def get(configuration, environment):
|
||||
def create(configuration, environment):
|
||||
return SQLiteTask(configuration, environment)
|
||||
|
||||
|
||||
|
|
|
|||
0
linspector/utils/__init__.py
Normal file
0
linspector/utils/__init__.py
Normal file
48
linspector/utils/singleton.py
Normal file
48
linspector/utils/singleton.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
"""
|
||||
This file is part of Linspector (https://linspector.org/)
|
||||
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
||||
See LICENSE (MIT license)
|
||||
"""
|
||||
|
||||
#see http://stackoverflow.com/questions/42558/python-and-the-singleton-pattern
|
||||
|
||||
|
||||
class Singleton:
|
||||
"""
|
||||
A non-thread-safe helper class to ease implementing singletons.
|
||||
This should be used as a decorator -- not a metaclass -- to the
|
||||
class that should be a singleton.
|
||||
|
||||
The decorated class can define one `__init__` function that
|
||||
takes only the `self` argument. Other than that, there are
|
||||
no restrictions that apply to the decorated class.
|
||||
|
||||
To get the singleton instance, use the `Instance` method. Trying
|
||||
to use `__call__` will result in a `TypeError` being raised.
|
||||
|
||||
Limitations: The decorated class cannot be inherited from.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, decorated):
|
||||
self._decorated = decorated
|
||||
self._instance = None
|
||||
|
||||
def instance(self):
|
||||
"""
|
||||
Returns the singleton instance. Upon its first call, it creates a
|
||||
new instance of the decorated class and calls its `__init__` method.
|
||||
On all subsequent calls, the already created instance is returned.
|
||||
|
||||
"""
|
||||
try:
|
||||
return self._instance
|
||||
except AttributeError:
|
||||
self._instance = self._decorated()
|
||||
return self._instance
|
||||
|
||||
def __call__(self):
|
||||
raise TypeError('Singletons must be accessed through `Instance()`.')
|
||||
|
||||
def __instancecheck__(self, inst):
|
||||
return isinstance(inst, self._decorated)
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
APScheduler==3.9.1 # (required)
|
||||
CherryPy==18.8.0 # (optional)
|
||||
fritzconnection==1.10.3 # (optional)
|
||||
paramiko==2.11.0 # (optional)
|
||||
pysnmp==4.4.12 # (optional)
|
||||
fritzconnection==1.10.3 # (optional, used by fritzuplink service)
|
||||
python-gammu==3.2.4 # (optional, used by the sms notification)
|
||||
paramiko==2.11.0 # (optional, used by ssh service)
|
||||
pysnmp==4.4.12 # (optional, used by snmp services)
|
||||
requests==2.28.1 # (optional, used by speedtest service)
|
||||
xmpp2==0.4 # (optional, used by the xmpp notification)
|
||||
Loading…
Add table
Add a link
Reference in a new issue