Coverage for C:\src\imod-python\imod\logging\pythonlogger.py: 92%
37 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-08 13:27 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-08 13:27 +0200
1import logging
2import sys
4from imod.logging.ilogger import ILogger
5from imod.logging.loglevel import LogLevel
8def _formatter():
9 return logging.Formatter(
10 "%(name)s: %(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(process)d >>> %(message)s"
11 )
14def _stack_level(additional_depth: int) -> int:
15 """
16 The stack level is used to print the file and line number of the line being logged.
17 Because there are a few layers between the place where the imod logger is used and
18 the place where the pyton logger is used we need to set a custom stack level.
20 An additional_depth can be provided to add to this default stack level.
21 This is useful when a decorator is added which introduces an additional level between
22 the imod logger and the python logger.
23 """
25 default_stack_level = 3
26 return default_stack_level + additional_depth
29class PythonLogger(ILogger):
30 """
31 The :class:`PythonLogger` is used to log messages using the default python logging framework.
32 """
34 def __init__(
35 self,
36 log_level: LogLevel,
37 add_default_stream_handler: bool,
38 add_default_file_handler: bool,
39 ) -> None:
40 self.logger = logging.getLogger("imod")
41 self._set_level(log_level)
43 if add_default_stream_handler:
44 self._add_stream_handler()
45 if add_default_file_handler:
46 self._add_file_handler()
48 def debug(self, message: str, additional_depth: int = 0) -> None:
49 self.logger.debug(message, stacklevel=_stack_level(additional_depth))
51 def info(self, message: str, additional_depth: int = 0) -> None:
52 self.logger.info(message, stacklevel=_stack_level(additional_depth))
54 def warning(self, message: str, additional_depth: int = 0) -> None:
55 self.logger.warning(message, stacklevel=_stack_level(additional_depth))
57 def error(self, message: str, additional_depth: int = 0) -> None:
58 self.logger.error(message, stacklevel=_stack_level(additional_depth))
60 def critical(self, message: str, additional_depth: int = 0) -> None:
61 self.logger.critical(message, stacklevel=_stack_level(additional_depth))
63 def _set_level(self, log_level: LogLevel) -> None:
64 self.logger.setLevel(log_level.value)
66 def _add_stream_handler(self) -> None:
67 stdout = logging.StreamHandler(stream=sys.stdout)
68 stdout.setFormatter(_formatter())
70 self.logger.addHandler(stdout)
72 def _add_file_handler(self) -> None:
73 file = logging.FileHandler("imod-python.log")
74 file.setFormatter(_formatter())
76 self.logger.addHandler(file)