205 lines
8.8 KiB
Python
Executable file
205 lines
8.8 KiB
Python
Executable file
#!/usr/bin/python3 -d
|
|
"""
|
|
This file is part of Linspector (https://linspector.org/)
|
|
Copyright (c) 2013-2023 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
|
|
See LICENSE.
|
|
"""
|
|
|
|
# TODO: VERY IMPORTANT! IMPLEMENT ERROR HANDLING ALL THE WAY...!!!
|
|
# Only exit execution on critical core errors. Do not exit when monitors are failing on
|
|
# configuration and execution, but log these errors.
|
|
import argparse
|
|
import importlib
|
|
import signal
|
|
import sys
|
|
|
|
from loguru import logger as log
|
|
|
|
from linspector.configuration import Configuration
|
|
from linspector.environment import Environment
|
|
from linspector.linspector import Linspector
|
|
from linspector.monitors import Monitors
|
|
|
|
__author__ = 'Johannes Findeisen'
|
|
__author_email__ = 'you@hanez.org'
|
|
__description__ = 'linspector is a infrastructure and system monitoring daemon and toolchain.'
|
|
__version__ = '0.30.2'
|
|
|
|
sys.stderr = open('/dev/null', 'w')
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(
|
|
description=__description__,
|
|
epilog='author: ' + __author__ + ' <' + __author_email__ + '>',
|
|
prog='linspector')
|
|
|
|
parser.add_argument('configuration_path', metavar='CONFIGURATION_PATH',
|
|
help='the configuration path to use')
|
|
|
|
parser.add_argument('-d', '--daemon', default=False, dest='daemon', action='store_true',
|
|
help='run linspector as native daemon (default: false)')
|
|
|
|
parser.add_argument('-k', '--kill', default=False, dest='kill', action='store_true',
|
|
help='kill the daemon if it is running (default: false)')
|
|
|
|
parser.add_argument('-r', '--restart', default=False, dest='restart', action='store_true',
|
|
help='restart the daemon if it is running (default: false)')
|
|
|
|
parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + str(__version__))
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def linspector():
|
|
print('Starting Linspector ' + __version__ + '...')
|
|
print('This software is free software licensed under the terms of the MIT license. Copyright (c) 2013-2023 by ' +
|
|
__author__ + ' <' + __author_email__ + '>')
|
|
|
|
args = parse_args()
|
|
monitors = {}
|
|
notifications = {}
|
|
plugins = {}
|
|
# the scheduler is a dict to make it possible in the future to run more than one scheduler in
|
|
# one linspector instance. need to think about it a little more...
|
|
scheduler = {}
|
|
services = {}
|
|
tasks = {}
|
|
|
|
try:
|
|
configuration = Configuration(args.configuration_path)
|
|
except Exception as err:
|
|
print('Configuration error: {0}'.format(err))
|
|
sys.exit(1)
|
|
|
|
log.remove()
|
|
default_log_format = 'timestamp={time:YYYY-MM-DD HH:mm:ss.SSSSSS ZZ} uptime={elapsed} level={level} ' \
|
|
'name=linspector {message}'
|
|
|
|
if configuration.get_option('linspector', 'logfile'):
|
|
logfile_count = '10'
|
|
if configuration.get_option('linspector', 'logfile_count'):
|
|
logfile_count = configuration.get_option('linspector', 'logfile_count')
|
|
|
|
logfile_format = default_log_format
|
|
if configuration.get_option('linspector', 'logfile_format'):
|
|
logfile_format = configuration.get_option('linspector', 'logfile_format')
|
|
|
|
logfile_level = 'INFO'
|
|
if configuration.get_option('linspector', 'logfile_level'):
|
|
logfile_level = configuration.get_option('linspector', 'logfile_level')
|
|
if logfile_level == 'DEBUG':
|
|
logfile_format = 'timestamp={time:YYYY-MM-DD HH:mm:ss.SSSSSS ZZ} uptime={elapsed} level={level} ' \
|
|
'name=linspector exec={name}:{function} line={line} {message}'
|
|
|
|
logfile_size = '1MB'
|
|
if configuration.get_option('linspector', 'logfile_size'):
|
|
logfile_size = configuration.get_option('linspector', 'logfile_size')
|
|
|
|
log.add(configuration.get_option('linspector', 'logfile'), backtrace=True, diagnose=True, enqueue=True,
|
|
format=logfile_format, level=logfile_level, retention=int(logfile_count), rotation=logfile_size)
|
|
|
|
default_debug_log_format = 'timestamp={time:YYYY-MM-DD HH:mm:ss.SSSSSS ZZ} uptime={elapsed} level={level} ' \
|
|
'name=linspector exec={name}:{function} line={line} {message}'
|
|
|
|
if configuration.get_option('linspector', 'debug_logfile'):
|
|
debug_logfile_count = '10'
|
|
if configuration.get_option('linspector', 'debug_logfile_count'):
|
|
debug_logfile_count = configuration.get_option('linspector', 'debug_logfile_count')
|
|
|
|
debug_logfile_format = default_debug_log_format
|
|
if configuration.get_option('linspector', 'error_logfile_format'):
|
|
debug_logfile_format = configuration.get_option('linspector', 'debug_logfile_format')
|
|
|
|
debug_logfile_level = 'DEBUG'
|
|
|
|
debug_logfile_size = '1MB'
|
|
if configuration.get_option('linspector', 'debug_logfile_size'):
|
|
debug_logfile_size = configuration.get_option('linspector', 'debug_logfile_size')
|
|
|
|
log.add(configuration.get_option('linspector', 'debug_logfile'), backtrace=True, diagnose=True,
|
|
enqueue=True, format=debug_logfile_format, level=debug_logfile_level,
|
|
retention=int(debug_logfile_count), rotation=debug_logfile_size)
|
|
|
|
default_error_log_format = 'timestamp={time:YYYY-MM-DD HH:mm:ss.SSSSSS ZZ} uptime={elapsed} level={level} ' \
|
|
'name=linspector exec={name}:{function} line={line} {message}'
|
|
|
|
if configuration.get_option('linspector', 'error_logfile'):
|
|
error_logfile_count = '10'
|
|
if configuration.get_option('linspector', 'error_logfile_count'):
|
|
error_logfile_count = configuration.get_option('linspector', 'error_logfile_count')
|
|
|
|
error_logfile_format = default_error_log_format
|
|
if configuration.get_option('linspector', 'error_logfile_format'):
|
|
error_logfile_format = configuration.get_option('linspector', 'error_logfile_format')
|
|
|
|
error_logfile_level = 'ERROR'
|
|
|
|
error_logfile_size = '1MB'
|
|
if configuration.get_option('linspector', 'error_logfile_size'):
|
|
error_logfile_size = configuration.get_option('linspector', 'error_logfile_size')
|
|
|
|
log.add(configuration.get_option('linspector', 'error_logfile'), backtrace=True, diagnose=True,
|
|
enqueue=True, format=error_logfile_format, level=error_logfile_level,
|
|
retention=int(error_logfile_count), rotation=error_logfile_size)
|
|
|
|
environment = Environment(log)
|
|
|
|
try:
|
|
if configuration.get_option('linspector', 'tasks'):
|
|
log.info('loading tasks: ' + configuration.get_option('linspector', 'tasks'))
|
|
print('Loading tasks: ' + configuration.get_option('linspector', 'tasks'))
|
|
task_list = configuration.get_option('linspector', 'tasks')
|
|
task_list = task_list.split(',')
|
|
for task_name in task_list:
|
|
task_package = 'linspector.tasks.' + task_name
|
|
if importlib.util.find_spec(task_package) is not None:
|
|
task_module = importlib.import_module(task_package)
|
|
task_object = task_module.create(configuration, environment, log)
|
|
tasks[task_name] = task_object
|
|
else:
|
|
log.warning('initialization of task: {0} failed! seems it does not exist.'.format(task_name))
|
|
except Exception as err:
|
|
log.warning('task initialization error: {0}'.format(err))
|
|
|
|
try:
|
|
monitors = Monitors(configuration, environment, log, notifications, services, tasks)
|
|
except Exception as err:
|
|
log.warning('monitor initialization error: {0}'.format(err))
|
|
|
|
try:
|
|
linspector = Linspector(configuration, environment, log, monitors, plugins, scheduler)
|
|
# linspector.print_debug()
|
|
except Exception as err:
|
|
log.critical('core initialization error: {0}'.format(err))
|
|
log.critical('program terminating...')
|
|
sys.exit(1)
|
|
|
|
# daemon initialization
|
|
if args.daemon:
|
|
try:
|
|
from linspector.linspectord import Linspectord
|
|
linspectord = Linspectord(configuration, environment, linspector, log)
|
|
# do handling of restart, start and stop commands but for now "start" is enough... ;)
|
|
if args.kill:
|
|
log.info('stopping daemon.')
|
|
linspectord.stop()
|
|
elif args.restart:
|
|
log.info('restarting daemon.')
|
|
linspectord.restart()
|
|
else:
|
|
log.info('starting daemon.')
|
|
linspectord.start()
|
|
except Exception as err:
|
|
log.critical('daemon error: {0}'.format(err))
|
|
sys.exit(1)
|
|
else:
|
|
try:
|
|
signal.pause()
|
|
except KeyboardInterrupt:
|
|
log.info('program terminated by user!')
|
|
print('Program terminated by user!')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
linspector()
|