bench_executor.logger
This module contains the Logger class which is responsible for logging. This class is a small wrapper around the Python logging module to automatically configure the loggers and handle unittest logging.
1#!/usr/bin/env python3 2 3""" 4This module contains the Logger class which is responsible for logging. 5This class is a small wrapper around the Python logging module to automatically 6configure the loggers and handle unittest logging. 7""" 8 9import os 10import sys 11import logging 12 13LOG_FILE_NAME = 'log.txt' 14LOGGER_FORMAT_FILE = '[%(asctime)s] %(levelname)-8s %(message)-s' 15LOGGER_FORMAT_CONSOLE = '%(levelname)s: %(message)s' 16 17 18class Logger: 19 """Log messages to a log file and console.""" 20 21 def __init__(self, name: str, directory: str, verbose: bool): 22 """Creates an instance of the Logger class. 23 24 During unittests, the `UNITTEST` environment variable is set which 25 disables the console logger. 26 27 Parameters 28 ---------- 29 name : str 30 Name of the logger 31 directory : str 32 The path to the directory where the logs must be stored. 33 verbose : bool 34 Enable verbose logs 35 """ 36 self._logger = logging.getLogger(name) 37 38 # Configure logging level 39 self._verbose = verbose 40 level = logging.INFO 41 if self._verbose: 42 level = logging.DEBUG 43 self._logger.setLevel(level) 44 45 # Disable default handlers 46 handlers = self._logger.handlers 47 for h in handlers: 48 self._logger.removeHandler(h) 49 50 # Configure handlers 51 directory = os.path.abspath(directory) 52 os.makedirs(directory, exist_ok=True) 53 log_file = logging.FileHandler(os.path.join(directory, LOG_FILE_NAME)) 54 log_file.setLevel(logging.DEBUG) 55 format_file = logging.Formatter(LOGGER_FORMAT_FILE) 56 log_file.setFormatter(format_file) 57 self._logger.addHandler(log_file) 58 59 # Silence console logging during unittests, logs are available in the 60 # log file anyway 61 if os.environ.get('UNITTEST') is None: 62 log_console = logging.StreamHandler(sys.stderr) 63 log_console.setLevel(logging.WARNING) 64 format_console = logging.Formatter(LOGGER_FORMAT_CONSOLE) 65 log_console.setFormatter(format_console) 66 self._logger.addHandler(log_console) 67 68 level_name = logging.getLevelName(self._logger.level) 69 self._logger.info(f'Logger ({level_name}) initialized for {name}') 70 71 def __del__(self): 72 """Close any handlers if needed""" 73 handlers = self._logger.handlers 74 for h in handlers: 75 try: 76 h.close() 77 except AttributeError: 78 pass 79 self._logger.removeHandler(h) 80 81 @property 82 def verbose(self) -> bool: 83 """Verbose logging enabled. 84 85 Returns 86 ------- 87 verbose : bool 88 Verbose logging enabled or not. 89 """ 90 return self._verbose 91 92 def debug(self, msg): 93 """Log a message with level DEBUG.""" 94 self._logger.debug(msg) 95 96 def info(self, msg): 97 """Log a message with level INFO.""" 98 self._logger.info(msg) 99 100 def warning(self, msg): 101 """Log a message with level WARNING.""" 102 self._logger.warning(msg) 103 104 def error(self, msg): 105 """Log a message with level ERROR.""" 106 self._logger.error(msg)
class
Logger:
19class Logger: 20 """Log messages to a log file and console.""" 21 22 def __init__(self, name: str, directory: str, verbose: bool): 23 """Creates an instance of the Logger class. 24 25 During unittests, the `UNITTEST` environment variable is set which 26 disables the console logger. 27 28 Parameters 29 ---------- 30 name : str 31 Name of the logger 32 directory : str 33 The path to the directory where the logs must be stored. 34 verbose : bool 35 Enable verbose logs 36 """ 37 self._logger = logging.getLogger(name) 38 39 # Configure logging level 40 self._verbose = verbose 41 level = logging.INFO 42 if self._verbose: 43 level = logging.DEBUG 44 self._logger.setLevel(level) 45 46 # Disable default handlers 47 handlers = self._logger.handlers 48 for h in handlers: 49 self._logger.removeHandler(h) 50 51 # Configure handlers 52 directory = os.path.abspath(directory) 53 os.makedirs(directory, exist_ok=True) 54 log_file = logging.FileHandler(os.path.join(directory, LOG_FILE_NAME)) 55 log_file.setLevel(logging.DEBUG) 56 format_file = logging.Formatter(LOGGER_FORMAT_FILE) 57 log_file.setFormatter(format_file) 58 self._logger.addHandler(log_file) 59 60 # Silence console logging during unittests, logs are available in the 61 # log file anyway 62 if os.environ.get('UNITTEST') is None: 63 log_console = logging.StreamHandler(sys.stderr) 64 log_console.setLevel(logging.WARNING) 65 format_console = logging.Formatter(LOGGER_FORMAT_CONSOLE) 66 log_console.setFormatter(format_console) 67 self._logger.addHandler(log_console) 68 69 level_name = logging.getLevelName(self._logger.level) 70 self._logger.info(f'Logger ({level_name}) initialized for {name}') 71 72 def __del__(self): 73 """Close any handlers if needed""" 74 handlers = self._logger.handlers 75 for h in handlers: 76 try: 77 h.close() 78 except AttributeError: 79 pass 80 self._logger.removeHandler(h) 81 82 @property 83 def verbose(self) -> bool: 84 """Verbose logging enabled. 85 86 Returns 87 ------- 88 verbose : bool 89 Verbose logging enabled or not. 90 """ 91 return self._verbose 92 93 def debug(self, msg): 94 """Log a message with level DEBUG.""" 95 self._logger.debug(msg) 96 97 def info(self, msg): 98 """Log a message with level INFO.""" 99 self._logger.info(msg) 100 101 def warning(self, msg): 102 """Log a message with level WARNING.""" 103 self._logger.warning(msg) 104 105 def error(self, msg): 106 """Log a message with level ERROR.""" 107 self._logger.error(msg)
Log messages to a log file and console.
Logger(name: str, directory: str, verbose: bool)
22 def __init__(self, name: str, directory: str, verbose: bool): 23 """Creates an instance of the Logger class. 24 25 During unittests, the `UNITTEST` environment variable is set which 26 disables the console logger. 27 28 Parameters 29 ---------- 30 name : str 31 Name of the logger 32 directory : str 33 The path to the directory where the logs must be stored. 34 verbose : bool 35 Enable verbose logs 36 """ 37 self._logger = logging.getLogger(name) 38 39 # Configure logging level 40 self._verbose = verbose 41 level = logging.INFO 42 if self._verbose: 43 level = logging.DEBUG 44 self._logger.setLevel(level) 45 46 # Disable default handlers 47 handlers = self._logger.handlers 48 for h in handlers: 49 self._logger.removeHandler(h) 50 51 # Configure handlers 52 directory = os.path.abspath(directory) 53 os.makedirs(directory, exist_ok=True) 54 log_file = logging.FileHandler(os.path.join(directory, LOG_FILE_NAME)) 55 log_file.setLevel(logging.DEBUG) 56 format_file = logging.Formatter(LOGGER_FORMAT_FILE) 57 log_file.setFormatter(format_file) 58 self._logger.addHandler(log_file) 59 60 # Silence console logging during unittests, logs are available in the 61 # log file anyway 62 if os.environ.get('UNITTEST') is None: 63 log_console = logging.StreamHandler(sys.stderr) 64 log_console.setLevel(logging.WARNING) 65 format_console = logging.Formatter(LOGGER_FORMAT_CONSOLE) 66 log_console.setFormatter(format_console) 67 self._logger.addHandler(log_console) 68 69 level_name = logging.getLevelName(self._logger.level) 70 self._logger.info(f'Logger ({level_name}) initialized for {name}')
Creates an instance of the Logger class.
During unittests, the UNITTEST
environment variable is set which
disables the console logger.
Parameters
- name (str): Name of the logger
- directory (str): The path to the directory where the logs must be stored.
- verbose (bool): Enable verbose logs