linspector/bin/linspector

178 lines
7.5 KiB
Python
Executable file

#!/usr/bin/python3 -d
"""
This file is part of Linspector (https://linspector.org/)
Copyright (c) 2022-2023 Johannes Findeisen <you@hanez.org>. All Rights Reserved.
See LICENSE (MIT 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
__version__ = '0.24.0'
__author__ = 'Johannes Findeisen <you@hanez.org>'
def parse_args():
parser = argparse.ArgumentParser(
description='linspector is a infrastructure and system monitoring daemon and toolchain.',
epilog='author: ' + __author__,
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():
args = parse_args()
databases = {}
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 = {}
log.remove()
default_log_format = 'timestamp={time:YYYY-MM-DD HH:mm:ss.SSSSSS ZZ} uptime={elapsed} level={level} ' \
'name=linspector exec={name}:{function} line={line} {message}'
log_level = "INFO"
log.add(sys.stderr, backtrace=True, colorize=True, diagnose=True, format=default_log_format, level=log_level)
try:
configuration = Configuration(args.configuration_path, log)
except Exception as err:
log.error('configuration error: {0}'.format(err))
sys.exit(1)
if configuration.get_option('linspector', 'log_format') or configuration.get_option('linspector', 'log_level'):
log.remove()
log_format = default_log_format
if configuration.get_option('linspector', 'log_format'):
log_format = configuration.get_option('linspector', 'log_format')
if configuration.get_option('linspector', 'log_level'):
log_level = configuration.get_option('linspector', 'log_level')
log.add(sys.stderr, backtrace=True, colorize=True, diagnose=True, format=log_format, level=log_level)
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 = log_level
if configuration.get_option('linspector', 'logfile_level'):
logfile_level = configuration.get_option('linspector', 'logfile_level')
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)
environment = Environment(log)
try:
if configuration.get_option('linspector', 'databases'):
log.info('Loading databases: ' + configuration.get_option('linspector', 'databases'))
database_list = configuration.get_option('linspector', 'databases')
database_list = database_list.split(',')
for database_name in database_list:
database_package = 'linspector.databases.' + database_name
if importlib.util.find_spec(database_package) is not None:
database_module = importlib.import_module(database_package)
database_object = database_module.create(configuration, environment, log)
databases[database_name] = database_object
else:
log.warning('initialization of database: {0} failed! seems it does not exist.'.
format(database_name))
except Exception as err:
log.warning('database initialization error: {0}'.format(err))
try:
if configuration.get_option('linspector', 'tasks'):
log.info('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, databases, 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!')
if __name__ == '__main__':
linspector()