代码之家  ›  专栏  ›  技术社区  ›  shadowtalker

重复的日志输出,但没有重复的处理程序

  •  0
  • shadowtalker  · 技术社区  · 7 年前

    我如何调试这个?

    import io
    import logging
    import os
    import sys
    from typing import Optional
    
    
    DEFAULT_LOG_LEVEL = logging.INFO
    
    
    def get_sub_loggers():
        return [
            logging.getLogger('a'),
            logging.getLogger('b'),
            logging.getLogger('c')
        ]
    
    
    def safe_add_handler(logger: logging.Logger, h: logging.Handler) -> None:
        if h not in logger.handlers:
            logger.addHandler(h)
    
    
    def safe_add_filter(logger: logging.Logger, f: logging.Filter) -> None:
        if f not in logger.filters:
            logger.addFilter(f)
    
    
    def configure_logging(main_logger: logging.Logger,
                          log_level = DEFAULT_LOG_LEVEL,
                          log_file = None,
                          fmt: Optional[str] = None,
                          force_add_handler: bool = False) -> None:
        main_logger.setLevel(log_level)
        logging.captureWarnings(True)  # send all warnings to be logged
    
        if force_add_handler or not main_logger.hasHandlers():
            if log_file is None or log_file == '-':
                log_file = sys.stderr
    
            if isinstance(log_file, (str, os.PathLike)):
                handler = logging.FileHandler(log_file)
            else:
                handler = logging.StreamHandler(log_file)
    
            handler.setFormatter(logging.Formatter(fmt if fmt is not None else logging.BASIC_FORMAT))
    
            main_logger.addHandler(handler)
            log_output_location = handler.stream.name if isinstance(handler, logging.StreamHandler) else handler.baseFilename
            main_logger.info('Writing logs to {}'.format(log_output_location))
        else:
            main_logger.info('Using existing log handlers')
    
        main_logger.info('Using log level {}'.format(log_level))
    
        for logger in get_sub_loggers():
            logger.setLevel(log_level)
            for h in main_logger.handlers:
                safe_add_handler(logger, h)
            for f in main_logger.filters:
                safe_add_filter(logger, f)
            main_logger.debug('Configured logger {}'.format(logger.name))
    
        main_logger.info('Configured submodule loggers.')
    
    
    configure_logging(logging.getLogger())
    
    a_logger = logging.getLogger('a')
    assert len(a_logger.handlers) == 1
    
    # Should only output "hi" once, but it does it twice
    a_logger.info('hi')
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   user2357112    7 年前

    伐木工人 propagate 默认情况下,将事件记录到其祖先的处理程序中。 a_logger 可能只有一个处理程序,但其父级根记录器也有一个处理程序(实际上是同一个处理程序)。 a_logger.info('hi')

    您不需要将相同的处理程序附加到每个记录器。将其连接到根记录器就足够了。