Added dynamic loading of tasks and services, refactoring and fixes.

This commit is contained in:
Johannes Findeisen 2022-09-27 07:00:17 +02:00
commit 8d9ec5c73b
18 changed files with 51 additions and 236 deletions

View file

@ -65,6 +65,7 @@ def main():
monitors = None
notifications = {}
services = {}
tasks = {}
try:
configuration = Configuration(args.configuration_path, environment)
@ -74,7 +75,7 @@ def main():
sys.exit(1)
try:
monitors = Monitors(configuration, environment, notifications, services)
monitors = Monitors(configuration, environment, notifications, services, tasks)
except Exception as err:
logger.warning('[linspector] monitor initialization error: {0}'.format(err))

View file

@ -7,8 +7,12 @@ log_level= verbose
log_count = 5
log_size = 10485760
pid_file = /var/run/user/1000/linspector.pid
; default delimiters '=' and ':' should be changed to ',' to be more native
; plugins separated by ','. no whitespaces allowed
plugins = HTTPServer
; globally configured tasks will always run on all monitors when no task is configured there. if tasks are configured in
; a monitor then maybe only run tasks from the dedicated monitor. maybe it is a good idea to run global tasks in every
; monitor and the monitor can add tasks to the global settings... need to think about it.
; tasks separated by ','. no whitespaces allowed
tasks = MariaDB,Logger
; maybe the run_mode is obsolete because this will be a daemon but maybe it is useful for one time execution?
; in uplink the available run_modes were cron, daemon and foreground
@ -18,7 +22,7 @@ run_mode = cron
; is needed. see email example.
[notifications]
; values can be overridden in each defined monitor
sms_receivers = +number1:+number2
sms_receivers = +number1,+number2
sms_configuration_file = ~/linspector/etc/gammurc
; retry to send interval and number of retries if something failed
sms_resend = 10

View file

@ -1,11 +1,18 @@
[monitor]
; currently i get errors when the service option is not spelled correct. error handling need to fix this. same for
; notifications and tasks.
service = FritzboxUplink
interval = 60
; notifications separated by ','. no whitespaces allowed
notifications = SMS,Email
; values from main configuration can be overridden for each defined monitor
email_receivers = admin@example.com:fallback@example.com
sms_receivers = +329084320984:+39804932409
tasks = None
; email_receivers separated by ','. no whitespaces allowed
email_receivers = admin@example.com,fallback@example.com
; sms_receivers separated by ','. no whitespaces allowed
sms_receivers = +329084320984,+39804932409
; setting to None fails. just do not set this option. currently i get an error when tasks is not set here. need to be
; fixed. setting it like below works but is no good design for optional options. same for notifications.
tasks = Redis
host = 192.168.0.1
user = USERNAME
password = PASSWORD

View file

@ -2,11 +2,10 @@
identifier = dsl
service = FritzboxUplink
interval = 60
# default delimiters '=' and ':' should be changed to ',' to be more native
notifications = SMS,Email
email_receivers = admin@example.com:fallback@example.com
sms_receivers = +329084320984:+39804932409
tasks = MariaDB:Logger:Redis
email_receivers = admin@example.com,fallback@example.com
sms_receivers = +329084320984,+39804932409
tasks = MariaDB
host = 192.168.1.1
user = USERNAME
password = PASSWORD

View file

@ -31,15 +31,16 @@ logger = getLogger('linspector')
class Monitor:
def __init__(self, configuration, environment, identifier, monitor_configuration, notifications,
services):
services, tasks):
self.__configuration = configuration
self.__environment = environment
self.__identifier = identifier
self.__monitor_configuration = monitor_configuration
self.__notifications = notifications
self.__services = services
self.__tasks = tasks
#print(__file__ + ' (42): ' + str(monitor_configuration))
#print(__file__ + ' (43): ' + str(monitor_configuration))
if self.__monitor_configuration.get('monitor', 'service'):
# TODO: the exception handling later!!!
@ -48,13 +49,13 @@ class Monitor:
self.__monitor_configuration.get('monitor', 'service').lower()
service_module = importlib.import_module(service_package)
service = getattr(service_module, self.__monitor_configuration.get('monitor', 'service') +
'Service')
service = getattr(service_module,
self.__monitor_configuration.get('monitor', 'service') + 'Service')
service.__init__(self, configuration, environment)
if self.__monitor_configuration.get('monitor', 'service') not in services:
services[self.__monitor_configuration.get('monitor', 'service')] = service
#print(__file__ + ' (57): ' + str(services))
#print(__file__ + ' (58): ' + str(services))
#else:
# do some logging
@ -69,7 +70,7 @@ class Monitor:
for notification_option in self.__monitor_configuration.get('monitor',
'notifications').split(','):
#print(__file__ + ' (72): ' + str(notification_option))
#print(__file__ + ' (73): ' + str(notification_option))
notification_package = 'linspector.notifications.' + notification_option.lower()
notification_module = importlib.import_module(notification_package)
@ -78,7 +79,21 @@ class Monitor:
if notification_option not in notifications:
notifications[notification_option] = notification
#print(__file__ + ' (81): ' + str(notifications))
#print(__file__ + ' (82): ' + str(notifications))
if self.__monitor_configuration.get('monitor', 'tasks'):
for task_option in self.__monitor_configuration.get('monitor',
'tasks').split(','):
#print(__file__ + ' (87): ' + str(task_option))
task_package = 'linspector.tasks.' + task_option.lower()
task_module = importlib.import_module(task_package)
task = getattr(task_module, task_option + 'Task')
task.__init__(self, configuration, environment)
if task_option not in tasks:
tasks[task_option] = task
#print(__file__ + ' (96): ' + str(tasks))
def get_identifier(self):
return self.__identifier

View file

@ -38,7 +38,7 @@ logger = getLogger('linspector')
# when changed dynamically.
class Monitors:
def __init__(self, configuration, environment, notifications, services):
def __init__(self, configuration, environment, notifications, services, tasks):
self.__configuration = configuration
self.__environment = environment
self.__monitors = {}
@ -60,7 +60,7 @@ class Monitors:
# they else refer to the same object.
self.__monitors[identifier] = Monitor(configuration, environment, identifier,
copy.deepcopy(monitor_configuration),
notifications, services)
notifications, services, tasks)
def get_monitors(self):
return self.__monitors

View file

@ -1,33 +0,0 @@
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
logger = getLogger('linspector')
class Notification:
def __init__(self, configuration, environment):
self.__configuration = configuration
self.__environment = environment

View file

@ -1,33 +0,0 @@
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
logger = getLogger('linspector')
class Notifications:
def __init__(self, configuration, environment):
self.__configuration = configuration
self.__environment = environment

View file

@ -1,33 +0,0 @@
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
logger = getLogger('linspector')
class Plugin:
def __init__(self, configuration, environment):
self.__configuration = configuration
self.__environment = environment

View file

@ -1,34 +0,0 @@
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
logger = getLogger('linspector')
class Plugins:
def __init__(self, configuration, environment):
super().__init__()
self.__configuration = configuration
self.__environment = environment

View file

@ -1,33 +0,0 @@
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
logger = getLogger('linspector')
class Task:
def __init__(self, configuration, environment):
self.__configuration = configuration
self.__environment = environment

View file

@ -1,33 +0,0 @@
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
logger = getLogger('linspector')
class Tasks:
def __init__(self, configuration, environment):
self.__configuration = configuration
self.__environment = environment

View file

@ -25,16 +25,14 @@ import cherrypy
import json
from logging import getLogger
from linspector.core.plugin import Plugin
logger = getLogger('linspector')
# TODO: check for all required configuration options and set defaults if needed.
class HTTPServerPlugin(Plugin):
class HTTPServerPlugin:
def __init__(self, configuration, environment):
super().__init__(configuration, environment)
self.__configuration = configuration
self.__environment = environment

View file

@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
from linspector.core.plugin import Plugin
logger = getLogger('linspector')
# TODO: check for all required configuration options and set defaults if needed.
class LishPlugin(Plugin):
class LishPlugin:
def __init__(self, configuration, environment):
super().__init__(configuration, environment)
self.__configuration = configuration
self.__environment = environment

View file

@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
from linspector.core.task import Task
logger = getLogger('linspector')
# TODO: check for all required configuration options and set defaults if needed.
class FileLoggerTask(Task):
class FileLoggerTask:
def __init__(self, configuration, environment):
super().__init__(configuration, environment)
self.__configuration = configuration
self.__environment = environment

View file

@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
from linspector.core.task import Task
logger = getLogger('linspector')
# TODO: check for all required configuration options and set defaults if needed.
class MariaDBTask(Task):
class MariaDBTask:
def __init__(self, configuration, environment):
super().__init__(configuration, environment)
self.__configuration = configuration
self.__environment = environment

View file

@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
from linspector.core.task import Task
logger = getLogger('linspector')
# TODO: check for all required configuration options and set defaults if needed.
class RedisTask(Task):
class RedisTask:
def __init__(self, configuration, environment):
super().__init__(configuration, environment)
self.__configuration = configuration
self.__environment = environment

View file

@ -22,15 +22,13 @@ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from logging import getLogger
from linspector.core.task import Task
logger = getLogger('linspector')
# TODO: check for all required configuration options and set defaults if needed.
class SQLiteTask(Task):
class SQLiteTask:
def __init__(self, configuration, environment):
super().__init__(configuration, environment)
self.__configuration = configuration
self.__environment = environment