import logging import sys def setup_logging(*, level: str = "info") -> None: numeric_level = getattr(logging, level.upper(), logging.INFO) root = logging.getLogger() root.setLevel(numeric_level) for h in root.handlers: if _is_stderr_stream_handler(h): h.setLevel(numeric_level) h.setFormatter(_build_formatter(numeric_level)) return handler = logging.StreamHandler(sys.stderr) handler.setLevel(numeric_level) handler.setFormatter(_build_formatter(numeric_level)) root.addHandler(handler) def _build_formatter(level: int) -> logging.Formatter: if level <= logging.DEBUG: fmt = "%(asctime)s %(levelname)-8s %(name)s:%(funcName)s:%(lineno)d — %(message)s" else: fmt = "%(asctime)s %(levelname)-8s %(name)s — %(message)s" return logging.Formatter(fmt=fmt, datefmt="%H:%M:%S") def _is_stderr_stream_handler(h: logging.Handler) -> bool: """ Return True only for a StreamHandler writing to stderr. Excludes FileHandler and other subclasses that happen to inherit from StreamHandler. """ return type(h) is logging.StreamHandler and getattr(h, "stream", None) is sys.stderr