import asyncio import logging import concurrent import os import sys from datetime import datetime def initialize_logger(app_name, user="me", verbosity_stream=None, verbosity_log=None, **kwargs): try: logging.setLoggerClass(MyLogger) logger = logging.getLogger(app_name) logger.setLevel(logging.DEBUG) logger.propagate = False # Set log path location if sys.platform == "linux": log_location = f"." else: log_location = "." # Set up formatting for output and filenames time = datetime.strftime(datetime.now(), '%Y_%m_%d__%H_%M_%S_%f')[:-4] log_path = os.path.join(log_location, f"{app_name}_{time}.log") # create formatter and add it to the handlers formatter = logging.Formatter('%(asctime)s\t%(levelname)-8s\t%(user)s\t%(message)s', '%Y-%m-%d %H:%M:%S%z') # Connect filehandler fh = logging.FileHandler(log_path, mode='w') fh.setLevel(verbosity_log.upper()) fh.setFormatter(formatter) logger.addHandler(fh) # Connect streamhandler ch = logging.StreamHandler() ch.setLevel(verbosity_stream.upper()) ch.setFormatter(formatter) logger.addHandler(ch) logger.debug(logger.handlers) except Exception as e: logger = logging.getLogger(app_name) logger.error("Exception while preparing logger:", exc_info=1) logger.verbose(f"Logger initialized with stream verbosity level " + f"{verbosity_stream} and log verbosity level {verbosity_log}.") return logger class MyLogger(logging.Logger): LEVEL_VERBOSE = 15 # between debug and info def __init__(self, name, user="me", level=logging.NOTSET): self.user = user logging.addLevelName(MyLogger.LEVEL_VERBOSE, "VERBOSE") return super().__init__(name, level=level) def debug(self, *args, **kwargs): return super().debug(*args, **kwargs, extra={"user": self.user}) def verbose(self, message, *args, **kwargs): return self._log(MyLogger.LEVEL_VERBOSE, message, args, **kwargs, extra={"user": self.user}) def info(self, *args, **kwargs): return super().info(*args, **kwargs, extra={"user": self.user}) def warning(self, *args, **kwargs): return super().warning(*args, **kwargs, extra={"user": self.user}) def error(self, *args, **kwargs): return super().error(*args, **kwargs, extra={"user": self.user}) def callback(packet, logger): print("Printed logger: ", logger," ; type(logger):", type(logger)) logger.error( f"ERROR This should print with all my logger formatting: {str(packet)}") logger.warning(f"WARNING This should print with all my logger formatting: {str(packet)}") logger.info( f"INFO This should print with all my logger formatting: {str(packet)}") logger.verbose(f"VERBOSE This should print with all my logger formatting: {str(packet)}") logger.debug( f"DEBUG This should print with all my logger formatting: {str(packet)}") return 0 async def run(logger): loop = asyncio.get_running_loop() with concurrent.futures.ProcessPoolExecutor() as pool: args = tuple([{"test": "please"}, logger]) result = await loop.run_in_executor(pool, callback, *args) if __name__ == "__main__": if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) logger = initialize_logger('logger_name', verbosity_stream="DEBUG", verbosity_log="VERBOSE") s = f"Before async: logger = {logger} ; type(logger) = {type(logger)}" print("PRINTED", s) logger.error( "ERROR: " + s) logger.warning("WARNING: " + s) logger.info( "INFO: " + s) logger.verbose("VERBOSE: " + s) logger.debug( "DEBUG: " + s) result = asyncio.run(run(logger))