diff --git a/tests/conversionOfTimestamps.py b/tests/conversionOfTimestamps.py index 34314662226bc2a7ab8d53e44ccd9ef9c9400fa5..bb6a18e9448a08866f37fea9a6350e42a75fa9f9 100644 --- a/tests/conversionOfTimestamps.py +++ b/tests/conversionOfTimestamps.py @@ -1,5 +1,4 @@ import logging -from logging.handlers import SysLogHandler from datetime import datetime as dt from collections import namedtuple @@ -10,14 +9,15 @@ from toargridding.grids import RegularGrid from toargridding.gridding import get_gridded_toar_data from toargridding.metadata import TimeSample -##setting up logger +##setting up logging from toargridding.defaultLogging import toargridding_defaultLogging logger = toargridding_defaultLogging() logger.addShellLogger(logging.DEBUG) +logger.logExceptions() +#logger.addSysLogger(logging.DEBUG) +#raise RuntimeError("For testing purposes") - -## add logger to syslog #creation of request. Config = namedtuple("Config", ["grid", "time", "variables", "stats","moreOptions"]) diff --git a/toargridding/defaultLogging.py b/toargridding/defaultLogging.py index f1b4f8b7d4c788f45993eb876c108cb273e24d5d..70698bc9724b64e32fc8edcca3cb8cbf1814a3e2 100644 --- a/toargridding/defaultLogging.py +++ b/toargridding/defaultLogging.py @@ -1,45 +1,104 @@ +import sys import logging +from collections import namedtuple from logging.handlers import SysLogHandler + +registeredLogger = namedtuple("registeredLogger", ["handler","formatter"]) + class toargridding_defaultLogging: """! class to setup default loggers for toargridding + + The added handler and their formatters are stored by this class for further configuration. + Parameters: + ---------- + loggername: + name of the logger to be used. default: toargridding Methods: ------- + registerHandler: + register a handler. Adds it to the logger and stores references in this class addShellLogger: adds a formatting logging to the shell. Default level is DEBUG addSysLogger: adds a formatted logging to the system log (on a linux system). Default level is WARNING + logExceptions: + enable passing of any uncaught exception to the logger + getHandler: + get a registered handler + getFormatter: + get a registered formatter """ - def __init__(self): - self.logger = logging.getLogger("toargridding") + def __init__(self, loggername : str = "toargridding" ): + self.logger = logging.getLogger(loggername) self.logger.setLevel(logging.DEBUG) + self.registeredLoggers = {}# name : registeredLogger + def registerHandler(self, name : str, handler, formatter = None): + """register a handler. Adds it to the logger and stores references in this class. + The given formatter (if not None) is added to the handler. + The handler is added to the logger. + Handler and logger are stored for a possible later access. + + Throws an exception if the name of the handler is already known. + """ + if name in self.registeredLoggers: + raise ValueError(f"There is already a registered handler with the name {name}.") + if formatter is not None: + handler.setFormatter(formatter) + self.logger.addHandler(handler) + self.registeredLoggers[name] = registeredLogger(handler, formatter) + def getHandler(self, name : str): + """get a handler for logging by its name used for the registration + """ + if name in self.registeredLoggers: + return self.registeredLoggers[name].handler + return None + def getFormatter(self, name : str): + """get a formatter by its name used for the registration + """ + if name in self.registeredLoggers: + return self.registeredLoggers[name].formatter + return None def addShellLogger(self, level=logging.INFO): """!adds a formatted logging to the shell to the "toargridding" logger. - The output handler can afterwards be accessed as shell_handler and its formatter as shell_formatter + The handler is registered as "shell". Parameters: ---------- level: set the verbosity level of the logger (default: info) """ - self.shell_handler = logging.StreamHandler() - self.shell_handler.setLevel(level) - self.shell_formatter = logging.Formatter(fmt="%(asctime)s [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'", datefmt="%Y-%m-%d %H:%M:%S") - self.shell_handler.setFormatter(self.shell_formatter) - self.logger.addHandler(self.shell_handler) + shell_handler = logging.StreamHandler() + shell_handler.setLevel(level) + shell_formatter = logging.Formatter(fmt="%(asctime)s [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'", datefmt="%Y-%m-%d %H:%M:%S") + self.registerHandler("shell", shell_handler, shell_formatter) def addSysLogger(self, level=logging.WARNING): """!adds a formatted logging to the system log of a linux system to the "toargridding" logger. - The output handler can afterwards be accessed as syslog_handler and its formatter as syslog_formatter + This logging is registered as "syslog". Parameters: ---------- level: set the verbosity level of the logger (default: warning) """ - self.syslog_handler = SysLogHandler(facility=SysLogHandler.LOG_DAEMON, address='/dev/log') - self.syslog_formatter = logging.Formatter(fmt="TOARGRIDDING [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'") - self.syslog_handler.setFormatter(self.syslog_formatter) - self.syslog_handler.setLevel(level) - self.logger.addHandler(self.syslog_handler) + syslog_handler = SysLogHandler(facility=SysLogHandler.LOG_DAEMON, address='/dev/log') + syslog_formatter = logging.Formatter(fmt="TOARGRIDDING [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'") + syslog_handler.setLevel(level) + self.registerHandler("syslog",syslog_handler, syslog_formatter) + def logExceptions(self): + """calling this function will redirect all uncaught exceptions to the logger + This is especially useful to write the exceptions to the system log + """ + sys.excepthook = self.handle_exception + def handle_exception(self, exc_type, exc_value, exc_traceback): + """function for passing uncaught exceptions to the logger + + """ + if issubclass(exc_type, KeyboardInterrupt): + sys.__excepthook__(exc_type, exc_value, exc_traceback) + return + + self.logger.error("Program terminated by the following exception:", exc_info=(exc_type, exc_value, exc_traceback)) +