# Other library imports import logging import os log = logging.getLogger("util") debug = str(os.getenv("GIA_DEBUG_LOGS", "0")).strip().lower() in { "1", "true", "yes", "on", } # Color definitions BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) COLORS = { "WARNING": YELLOW, "INFO": WHITE, "DEBUG": BLUE, "CRITICAL": YELLOW, "ERROR": RED, } RESET_SEQ = "\033[0m" COLOR_SEQ = "\033[1;%dm" BOLD_SEQ = "\033[1m" def formatter_message(message, use_color=True): if use_color: message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ) else: message = message.replace("$RESET", "").replace("$BOLD", "") return message class ColoredFormatter(logging.Formatter): def __init__(self, msg, use_color=True): logging.Formatter.__init__(self, msg) self.use_color = use_color def format(self, record): levelname = record.levelname if self.use_color and levelname in COLORS: levelname_color = ( COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ ) record.levelname = levelname_color return logging.Formatter.format(self, record) def get_logger(name): # Define the logging format FORMAT = "%(asctime)s %(levelname)18s $BOLD%(name)13s$RESET - %(message)s" COLOR_FORMAT = formatter_message(FORMAT, True) color_formatter = ColoredFormatter(COLOR_FORMAT) # formatter = logging.Formatter( # Define the logger on the base class log = logging.getLogger(name) log.setLevel(logging.INFO) if debug: log.setLevel(logging.DEBUG) # Add exactly one stream handler per logger to avoid duplicate lines. existing_handler = None for handler in log.handlers: if getattr(handler, "_gia_logger_handler", False): existing_handler = handler break if existing_handler is None: ch = logging.StreamHandler() ch._gia_logger_handler = True ch.setFormatter(color_formatter) log.addHandler(ch) existing_handler = ch existing_handler.setLevel(logging.DEBUG if debug else logging.INFO) log.propagate = False return log