import logging
from platform import system
from tqdm import tqdm
from multiprocessing import Lock

loggers = {}


# https://stackoverflow.com/questions/38543506/
class TqdmLoggingHandler(logging.Handler):
    def __init__(self, level=logging.NOTSET):
        super(TqdmLoggingHandler, self).__init__(level)

    def emit(self, record):
        try:
            msg = self.format(record)
            tqdm.set_lock(Lock())
            tqdm.write(msg)
            self.flush()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)

def setup_custom_logger(name):
    """
    Create a logger with a certain name and level
    """
    global loggers

    if loggers.get(name):
        return loggers.get(name)

    formatter = logging.Formatter(
        fmt='%(levelname)s: %(message)s'
    )

    handler = TqdmLoggingHandler()
    handler.setFormatter(formatter)

    if system() not in ['Windows', 'cli']:
        logging.addLevelName(logging.ERROR, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.ERROR))
        logging.addLevelName(logging.WARNING, "\033[1;33m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
        logging.addLevelName(logging.INFO, "\033[1;34m%s\033[1;0m" % logging.getLevelName(logging.INFO))
        logging.addLevelName(logging.DEBUG, "\033[1;35m%s\033[1;0m" % logging.getLevelName(logging.DEBUG))

    logger = logging.getLogger(name)
    logger.setLevel(logging.WARNING)

    # if (logger.hasHandlers()):
    #     logger.handlers.clear()
    if logger.handlers:
        logger.handlers = []
    logger.addHandler(handler)
    loggers.update(dict(name=logger))

    return logger

[(34, 'logging.Formatter', 'logging.Formatter', False, 'import logging\n'), (47, 'logging.getLogger', 'logging.getLogger', False, 'import logging\n'), (41, 'platform.system', 'system', False, 'from platform import system\n'), (18, 'tqdm.tqdm.write', 'tqdm.write', False, 'from tqdm import tqdm\n'), (17, 'multiprocessing.Lock', 'Lock', False, 'from multiprocessing import Lock\n'), (42, 'logging.getLevelName', 'logging.getLevelName', False, 'import logging\n'), (43, 'logging.getLevelName', 'logging.getLevelName', False, 'import logging\n'), (44, 'logging.getLevelName', 'logging.getLevelName', False, 'import logging\n'), (45, 'logging.getLevelName', 'logging.getLevelName', False, 'import logging\n')]