Source code for nv_ingest_api.util.logging.configuration

# SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES.
# All rights reserved.
# SPDX-License-Identifier: Apache-2.0


import logging
import logging.config
from enum import Enum


[docs] class LogLevel(str, Enum): DEFAULT = "DEFAULT" DEBUG = "DEBUG" INFO = "INFO" WARNING = "WARNING" ERROR = "ERROR" CRITICAL = "CRITICAL"
[docs] def configure_logging(level_name: str) -> None: """ Configures global logging. Parameters ---------- level_name : str The name of the logging level (e.g., "DEBUG", "INFO"). """ numeric_level = getattr(logging, level_name.upper(), None) if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level: {level_name}") # Scorched-earth reset: remove ALL existing handlers from root and named loggers # to ensure there is exactly one handler after configuration. root_logger = logging.getLogger() for h in list(root_logger.handlers): root_logger.removeHandler(h) try: h.close() except Exception: pass # Clear handlers from all known loggers and make them propagate to root for name, logger_obj in list(logging.Logger.manager.loggerDict.items()): if isinstance(logger_obj, logging.Logger): for h in list(logger_obj.handlers): logger_obj.removeHandler(h) try: h.close() except Exception: pass # Ensure messages bubble to root; levels will be controlled centrally logger_obj.propagate = True logger_obj.setLevel(logging.NOTSET) # Use dictConfig to establish a single console handler on the root logger. config_dict = { "version": 1, # We already cleared handlers above; keep loggers enabled so they propagate to root "disable_existing_loggers": False, "formatters": { "standard": { "format": "%(asctime)s - %(levelname)s - %(name)s - %(message)s", } }, "handlers": { "console": { "class": "logging.StreamHandler", "level": numeric_level, "formatter": "standard", "stream": "ext://sys.stdout", } }, "root": { "level": numeric_level, "handlers": ["console"], }, } logging.config.dictConfig(config_dict) # Enforce exactly one handler remains attached to root (keep first StreamHandler) root_logger = logging.getLogger() if len(root_logger.handlers) > 1: keep = None for h in list(root_logger.handlers): if keep is None and isinstance(h, logging.StreamHandler): keep = h continue root_logger.removeHandler(h) try: h.close() except Exception: pass # Route warnings module through logging try: import logging as _logging _logging.captureWarnings(True) except Exception: pass