Source code for CorrHOD.logging

#%% Logging utils
import sys
import logging
import types
from pathlib import Path

[docs]def log_newline(self, how_many_lines=1): """ Add a blank to the logger. Accessed as a method of the logger object with `types.MethodType(log_newline, logger)` """ # From https://stackoverflow.com/a/45032701 # Switch formatter, output a blank line self.handler.setFormatter(self.blank_formatter) for i in range(how_many_lines): self.info('') # Switch back self.handler.setFormatter(self.formatter)
[docs]def create_logger(name:str, level=logging.INFO, stream=sys.stdout, filename:str=None, filemode:str='w', propagate=False): """ Will get or create the loger with the given name, and add a method to the logger object to output a blank line. A handler is created, with the given level and stream (or file output). Parameters ---------- name : str Name of the logger level : optional Level of the logger and handler. Can be a string ('info', 'debug', 'warning') or a logging level (`logging.INFO`, `logging.DEBUG`, `logging.WARNING`). Defaults to `logging.INFO` stream : optional Stream to which the logger will output. Defaults to sys.stdout filename : str, optional Path to the file to which the logger will output. Defaults to None filemode : str, optional Mode to open the file. Defaults to 'w' propagate : bool, optional Whether to propagate the logs to the root logger. Defaults to False Warning : If sets to False, the logs will not be propagated to the root logger, and will not be output by the root logger. If the root logger outputs to a file, the logs will not be saved in the file, unless the logger has the same output file. However, if propagate is True, the logs will be output twice if the root has a different handler (once by the logger, once by the root logger) Returns ------- logger : logging.Logger Logger object """ # From https://stackoverflow.com/a/45032701 if isinstance(level, str): level = {'info': logging.INFO, 'debug': logging.DEBUG, 'warning': logging.WARNING}[level.lower()] # Create a handler if filename is not None: path = Path(filename).parent[0] # Get the path to the directory containing the file path.mkdir(parents=True, exist_ok=True) # Create the directory if it does not exist handler = logging.FileHandler(filename, mode=filemode) else: handler = logging.StreamHandler(stream=stream) handler.setLevel(level) # Create formatter and add it to the handler formatter = logging.Formatter(fmt="%(message)s") blank_formatter = logging.Formatter(fmt="") handler.setFormatter(formatter) # Create a logger, with the previously-defined handler logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) # Remove all handlers already associated with the logger object for hd in logger.handlers: logger.removeHandler(hd) logger.propagate = propagate # Prevent the logs from being propagated to the root logger that will have different handlers logger.addHandler(handler) # Add the handler to the logger # Save some data and add a method to logger object logger.handler = handler logger.formatter = formatter logger.blank_formatter = blank_formatter logger.newline = types.MethodType(log_newline, logger) return logger