From 5843f4358f140559ed0fd9572df91d27332cfd6e Mon Sep 17 00:00:00 2001 From: Johannes Findeisen Date: Thu, 23 Feb 2023 19:06:53 +0100 Subject: [PATCH] Migrated to Loguru for logging and set up basic configuration, but it still needs adjustments. (0.21) --- Makefile | 3 +++ README.md | 51 ++++++++++++++++++------------------- bin/linspector | 44 ++++++++++++++++++++------------ linspector/configuration.py | 3 ++- 4 files changed, 58 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 6bc4d74..e047933 100644 --- a/Makefile +++ b/Makefile @@ -36,5 +36,8 @@ help: run: PYTHONPATH=$(shell pwd):$(shell pwd)/venv/lib/python$(PYTHON_VERSION)/site-packages/ bin/linspector -s ./etc +rundev: + PYTHONPATH=$(shell pwd):$(shell pwd)/venv/lib/python$(PYTHON_VERSION)/site-packages/ bin/linspector -s ./etc.local + daemon: PYTHONPATH=$(shell pwd):$(shell pwd)/venv/lib/python$(PYTHON_VRESION)/site-packages/ bin/linspector -d ./etc diff --git a/README.md b/README.md index 73fd8db..27da90b 100644 --- a/README.md +++ b/README.md @@ -42,29 +42,29 @@ development environment. ### To do - **Everything!** But the progress is fast and after some few days I am not far - away to get a first working codebase. If the core is running I believe adding features - will happen from day to day... ;) +away to get a first working codebase. If the core is running I believe adding features +will happen from day to day... ;) See TODO for internal tasks. ### Ideas - **Thousands!** For now the goal is to implement most features from the old version - of Linspector. :) +of Linspector. :) ### Manifest - All of this project **must be MIT licensed**. When using 3rd party libraries make - sure the license is compatible. +sure the license is compatible. - The core of Linspector should not use 3rd party libraries if possible. Only notifications, - plugins, services and tasks may use other libraries. But copying code into the - source tree is ok when respecting the license. Not using 3rd party libraries - should always be preferred though. +source tree is ok when respecting the license. Not using 3rd party libraries +should always be preferred though. - Inline comments should be all lowercase. Descriptions and documentation comments - must be natural language. +must be natural language. - Arguments to functions must always be in alphabetical order. - Class member variables must always be in alphabetical order in __init__() or any - function / method. +function / method. - Functions must always be in alphabetical order in classe. - Every commit must run without errors even if not being a working version of Linspector. @@ -72,13 +72,13 @@ See TODO for internal tasks. Currently, the Linspector core requires the following 3rd party libraries: -- [APScheduler](https://github.com/agronholm/apscheduler)- Apscheduler is the scheduler used in - Linspector for the execution of monitors. I started - to use this library in very early versions of Linspector in 2011. Since the main task - in Linspector is the execution of jobs in regularly intervals I believe it is the right - decision to make use of APScheduler directly in the core of the Linspector project. -- [Loguru](https://github.com/Delgan/loguru) - Linspector uses Loguru for file based logging. Loguru is a library - which aims to bring enjoyable logging in Python. +- [APScheduler](https://pypi.org/project/APScheduler/)- Apscheduler is the scheduler used in +Linspector for the execution of monitors. I started +to use this library in very early versions of Linspector in 2011. Since the main task +in Linspector is the execution of jobs in regularly intervals I believe it is the right +decision to make use of APScheduler directly in the core of the Linspector project. +- [Loguru](https://pypi.org/project/loguru/) - Linspector uses Loguru for file based logging. Loguru is a library +which aims to bring enjoyable logging in Python. ### Other used libraries @@ -87,20 +87,20 @@ monitors, notifications, services or plugins sometimes need to make the use of them may only affect parts of Linspector. Currently used libraries are: - [CherryPy](https://cherrypy.dev/) - CherryPy is a pythonic, object-oriented HTTP framework. - Used by the HTTPServer plugin. +Used by the HTTPServer plugin. - [fritzconnection](https://github.com/kbr/fritzconnection) - A Python-Tool to communicate with - the AVM Fritz!Box. Uses the TR-064 protocol over UPnP. Used by the FritzboxPhoneStatus and - FritzBoxUplink service. +the AVM Fritz!Box. Uses the TR-064 protocol over UPnP. Used by the FritzboxPhoneStatus and +FritzBoxUplink service. - [Paramiko](https://www.paramiko.org/) - Paramiko is a pure-Python (2.7, 3.4+) implementation - of the SSHv2 protocol, providing both client and server functionality. Used by the SSH service. +of the SSHv2 protocol, providing both client and server functionality. Used by the SSH service. - [python-gammu](https://wammu.eu/python-gammu/) - Python bindings for the Gammu library. Used by the - SMS notification. +SMS notification. - [PySNMP](https://pysnmp.readthedocs.io/en/latest/) - PySNMP is a cross-platform, pure-Python - SNMP engine implementation. It features fully-functional SNMP engine capable to act in - Agent/Manager/Proxy roles, talking SNMP v1/v2c/v3 protocol versions over IPv4/IPv6 and other - network transports. Used by the SNMP services (get). +SNMP engine implementation. It features fully-functional SNMP engine capable to act in +Agent/Manager/Proxy roles, talking SNMP v1/v2c/v3 protocol versions over IPv4/IPv6 and other +network transports. Used by the SNMP services (get). - [requests](https://requests.readthedocs.io/en/latest/) - Requests is an elegant and simple - HTTP library for Python, built for human beings. Used by the Speedtest service. +HTTP library for Python, built for human beings. Used by the Speedtest service. - [xmpp2](https://pypi.org/project/xmpp2/) - A XMPP client for Python. Used by the XMPP notification. These libraries are not being delivered with the Linspector source code and maybe have @@ -131,8 +131,7 @@ scheme (See: [https://semver.org/](https://semver.org/)): - 15.10 - Date based release - 23 - Serial release -(More -information: [https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#choosing-a-versioning-scheme](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#choosing-a-versioning-scheme) & +(More information: [https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#choosing-a-versioning-scheme](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#choosing-a-versioning-scheme) & [https://peps.python.org/pep-0440/#public-version-identifiers](https://peps.python.org/pep-0440/#public-version-identifiers)) ### Configuration file rules diff --git a/bin/linspector b/bin/linspector index b7e10f4..02d5fa3 100755 --- a/bin/linspector +++ b/bin/linspector @@ -14,10 +14,10 @@ import sys from linspector.configuration import Configuration from linspector.environment import Environment from linspector.linspector import Linspector -from linspector.logger import Log from linspector.monitors import Monitors +from loguru import logger -__version__ = '0.20.5' +__version__ = '0.21' __author__ = 'Johannes Findeisen ' @@ -62,49 +62,61 @@ def main(): tasks = {} try: - configuration = Configuration(args.configuration_path) + configuration = Configuration(args.configuration_path, logger) except Exception as err: - print('[linspector] configuration error: {0}'.format(err)) + logger.error('configuration error: {0}'.format(err)) sys.exit(1) - log = Log(configuration, args.stdout, args.verbose) - environment = Environment(log) + logger.remove() + log_level = "ERROR" + if configuration.get_option('linspector', 'log_level'): + log_level = configuration.get_option('linspector', 'log_level') + + logger.add(sys.stderr, backtrace=True, colorize=True, diagnose=True, level=log_level) + # log.add(sys.stderr, backtrace=True, colorize=True, diagnose=True, format="{time} [{level}]: {message}", level="INFO") + # log.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO") + if configuration.get_option('linspector', 'logfile'): + logger.add(configuration.get_option('linspector', 'logfile'), backtrace=True, diagnose=True, enqueue=True, + level=configuration.get_option('linspector', 'logfile_level')) + + environment = Environment(logger) try: - monitors = Monitors(configuration, environment, log, notifications, services, tasks) + monitors = Monitors(configuration, environment, logger, notifications, services, tasks) except Exception as err: - log.warning('[linspector] monitor initialization error: {0}'.format(err)) + logger.warning('monitor initialization error: {0}'.format(err)) try: - linspector = Linspector(configuration, environment, log, monitors, plugins, scheduler) + linspector = Linspector(configuration, environment, logger, monitors, plugins, scheduler) # linspector.print_debug() except Exception as err: - log.critical('[linspector] core initialization error: {0}'.format(err)) + logger.critical('core initialization error: {0}'.format(err)) + logger.critical('program terminating...') sys.exit(1) # daemon initialization if args.daemon: try: from linspector.linspectord import Linspectord - linspectord = Linspectord(configuration, environment, linspector, log) + linspectord = Linspectord(configuration, environment, linspector, logger) # do handling of restart, start and stop commands but for now "start" is enough... ;) if args.kill: - log.info('[linspector] stopping daemon.') + logger.info('stopping daemon.') linspectord.stop() elif args.restart: - log.info('[linspector] restarting daemon.') + logger.info('restarting daemon.') linspectord.restart() else: - log.info('[linspector] starting daemon.') + logger.info('starting daemon.') linspectord.start() except Exception as err: - log.critical('[linspector] daemon error: {0}'.format(err)) + logger.critical('daemon error: {0}'.format(err)) sys.exit(1) else: try: signal.pause() except KeyboardInterrupt: - log.info('[linspector] program terminated by user!') + logger.info('program terminated by user!') if __name__ == '__main__': diff --git a/linspector/configuration.py b/linspector/configuration.py index 631fe9c..5c41f0b 100644 --- a/linspector/configuration.py +++ b/linspector/configuration.py @@ -11,9 +11,10 @@ import os # TODO: check for all required configuration options and set defaults if needed. do this only for # options in the "linspector" section of linspector.ini. class Configuration: - def __init__(self, configuration_path): + def __init__(self, configuration_path, log): self.__configuration = configparser.ConfigParser() self.__configuration_path = configuration_path + self.__log = log # print('[linspector] reading configuration file: ' + configuration_path + # '/linspector.conf')