Skip to content
Snippets Groups Projects
Commit 7419ea03 authored by Carsten Hinz's avatar Carsten Hinz
Browse files

added logging to a rotating text file

-> modified script for testing

fixed a typo in toar_rest_client logging
parent 606f27d6
No related branches found
No related tags found
2 merge requests!11Creation of first beta release version,!8Resolve "add structured logging and output levels for complete module"
...@@ -12,3 +12,5 @@ examples/results ...@@ -12,3 +12,5 @@ examples/results
tests/temp_data_cache/ tests/temp_data_cache/
notTracked/ notTracked/
*.swp *.swp
log/
*/log/
...@@ -14,6 +14,7 @@ from toargridding.defaultLogging import toargridding_defaultLogging ...@@ -14,6 +14,7 @@ from toargridding.defaultLogging import toargridding_defaultLogging
logger = toargridding_defaultLogging() logger = toargridding_defaultLogging()
logger.addShellLogger(logging.DEBUG) logger.addShellLogger(logging.DEBUG)
logger.logExceptions() logger.logExceptions()
logger.addRotatingLogFile_scriptName(__file__)
#logger.addSysLogger(logging.DEBUG) #logger.addSysLogger(logging.DEBUG)
#raise RuntimeError("For testing purposes") #raise RuntimeError("For testing purposes")
......
import sys import sys
import logging import logging
from collections import namedtuple from collections import namedtuple
from logging.handlers import SysLogHandler from pathlib import Path
from logging.handlers import SysLogHandler, TimedRotatingFileHandler
registeredLogger = namedtuple("registeredLogger", ["handler","formatter"]) handlerPair = namedtuple("registeredLogger", ["handler","formatter"])
class toargridding_defaultLogging: class toargridding_defaultLogging:
"""! class to setup default loggers for toargridding """! class to setup default loggers for toargridding
...@@ -33,7 +34,7 @@ class toargridding_defaultLogging: ...@@ -33,7 +34,7 @@ class toargridding_defaultLogging:
def __init__(self, loggername : str = "toargridding" ): def __init__(self, loggername : str = "toargridding" ):
self.logger = logging.getLogger(loggername) self.logger = logging.getLogger(loggername)
self.logger.setLevel(logging.DEBUG) self.logger.setLevel(logging.DEBUG)
self.registeredLoggers = {}# name : registeredLogger self.registeredHandlers = {}# name : registeredLogger
def registerHandler(self, name : str, handler, formatter = None): def registerHandler(self, name : str, handler, formatter = None):
"""register a handler. Adds it to the logger and stores references in this class. """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 given formatter (if not None) is added to the handler.
...@@ -42,23 +43,23 @@ class toargridding_defaultLogging: ...@@ -42,23 +43,23 @@ class toargridding_defaultLogging:
Throws an exception if the name of the handler is already known. Throws an exception if the name of the handler is already known.
""" """
if name in self.registeredLoggers: if name in self.registeredHandlers:
raise ValueError(f"There is already a registered handler with the name {name}.") raise ValueError(f"There is already a registered handler with the name {name}.")
if formatter is not None: if formatter is not None:
handler.setFormatter(formatter) handler.setFormatter(formatter)
self.logger.addHandler(handler) self.logger.addHandler(handler)
self.registeredLoggers[name] = registeredLogger(handler, formatter) self.registeredHandlers[name] = handlerPair(handler, formatter)
def getHandler(self, name : str): def getHandler(self, name : str):
"""get a handler for logging by its name used for the registration """get a handler for logging by its name used for the registration
""" """
if name in self.registeredLoggers: if name in self.registeredHandlers:
return self.registeredLoggers[name].handler return self.registeredHandlers[name].handler
return None return None
def getFormatter(self, name : str): def getFormatter(self, name : str):
"""get a formatter by its name used for the registration """get a formatter by its name used for the registration
""" """
if name in self.registeredLoggers: if name in self.registeredHandlers:
return self.registeredLoggers[name].formatter return self.registeredHandlers[name].formatter
return None return None
def addShellLogger(self, level=logging.INFO): def addShellLogger(self, level=logging.INFO):
"""!adds a formatted logging to the shell to the "toargridding" logger. """!adds a formatted logging to the shell to the "toargridding" logger.
...@@ -86,6 +87,40 @@ class toargridding_defaultLogging: ...@@ -86,6 +87,40 @@ class toargridding_defaultLogging:
syslog_formatter = logging.Formatter(fmt="TOARGRIDDING [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'") syslog_formatter = logging.Formatter(fmt="TOARGRIDDING [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'")
syslog_handler.setLevel(level) syslog_handler.setLevel(level)
self.registerHandler("syslog",syslog_handler, syslog_formatter) self.registerHandler("syslog",syslog_handler, syslog_formatter)
def addRotatingLogFile(self, filename : Path, level=logging.INFO):
"""creation of a rotating file handler, that will change the files at midnight.
The last 7 files logfiles are stored.
Parameters:
----------
filename:
basename of the file. The parent path will be created, if required.
level:
output level for this handler
"""
filename.parent.mkdir(parents=True, exist_ok=True)
handler = TimedRotatingFileHandler(filename, when="midnight", backupCount=7)
handler.setLevel(level)
formatter = logging.Formatter(fmt="%(asctime)s [%(levelname)s] - %(filename)s:%(lineno)d: '%(message)s'", datefmt="%Y-%m-%d %H:%M:%S")
self.registerHandler("rotatingFile", handler, formatter)
def addRotatingLogFile_scriptName(self, scriptName : str | Path, level=logging.INFO):
"""creation of an rotating log file by using the script name.
In the /path/to/script a subdirectory log will be created. The logfile will be name [script basename].log
Parameters:
----------
scriptName:
name to the script, including its path
level:
verbosity level.
"""
sn = Path(scriptName)
if not sn.is_file:
raise ValueError(f"Expecting name to a script. {sn} is not a file.")
path = sn.parent / "log"
path.mkdir(exist_ok=True)
fn = path / f"{sn.stem}.log"
self.addRotatingLogFile(fn, level)
def logExceptions(self): def logExceptions(self):
"""calling this function will redirect all uncaught exceptions to the logger """calling this function will redirect all uncaught exceptions to the logger
This is especially useful to write the exceptions to the system log This is especially useful to write the exceptions to the system log
......
...@@ -586,7 +586,7 @@ class AnalysisServiceDownload(AnalysisService): ...@@ -586,7 +586,7 @@ class AnalysisServiceDownload(AnalysisService):
with open(filename, "w+b") as downloaded_file: with open(filename, "w+b") as downloaded_file:
downloaded_file.write(response.content) downloaded_file.write(response.content)
else: else:
logger.info(f"Loading already downloaded data from {filename}") logger.info(f"Loading already downloaded data to file {filename}")
with open(filename, "r+b") as data_file: with open(filename, "r+b") as data_file:
content = data_file.read() content = data_file.read()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment