Coverage for mlair/helpers/logger.py: 100%
24 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-12-02 15:24 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-12-02 15:24 +0000
1"""Logger class."""
2import logging
3import os
4import time
5from ..configuration import ROOT_PATH
8class Logger:
9 """
10 Basic logger class to unify all logging outputs.
12 Logs are saved in local file and returned to std output. In default settings, logging level of file logger is DEBUG,
13 logging level of stream logger is INFO. Class must be imported and initialised in starting script, all subscripts
14 should log with logging.info(), debug, ...
15 """
17 def __init__(self, log_path=None, level_file=logging.DEBUG, level_stream=logging.INFO):
18 """Construct logger."""
19 # define shared logger format
20 self.formatter = '%(asctime)s - %(levelname)s: %(message)s [%(filename)s:%(funcName)s:%(lineno)s]'
22 # assure defaults
23 level_stream = level_stream or logging.INFO
24 level_file = level_file or logging.DEBUG
26 # set log path
27 self.log_file = self.setup_logging_path(log_path)
28 # set root logger as file handler
29 logging.basicConfig(level=level_file,
30 format=self.formatter,
31 filename=self.log_file,
32 filemode='a')
33 # add stream handler to the root logger
34 logging.getLogger('').addHandler(self.logger_console(level_stream))
35 # print logger path
36 logging.info(f"File logger: {self.log_file}")
38 @staticmethod
39 def setup_logging_path(path: str = None):
40 """
41 Check if given path exists and creates if not.
43 If path is None, use path from main. The logging file is named like `logging_<runtime>.log` where
44 runtime=`%Y-%m-%d_%H-%M-%S` of current run.
46 :param path: path to logfile
48 :return: path of logfile
49 """
50 if not path: # set default path
51 path = os.path.join(ROOT_PATH, "logging")
52 if not os.path.exists(path):
53 os.makedirs(path)
54 runtime = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
55 log_file = os.path.join(path, f'logging_{runtime}.log')
56 return log_file
58 def logger_console(self, level: int):
59 """
60 Define a stream handler which writes messages of given level or higher to std out.
62 :param level: logging level as integer, e.g. logging.DEBUG or 10
64 :return: defines stream handler
65 """
66 # define Handler
67 console = logging.StreamHandler()
68 # set level of Handler
69 console.setLevel(level)
70 # set a format which is simpler for console use
71 formatter = logging.Formatter(self.formatter)
72 # tell the handler to use this format
73 console.setFormatter(formatter)
74 return console