Python 日志记录对象在每个实例化时都在累积

问题描述 投票:0回答:1

考虑以下代码,我创建了一个自定义记录器类,然后在 for 循环中多次创建记录器对象,但不是一次添加一个日志,而是添加多个日志,如下所示

import sys
import logging
import os

import configs

class Logger:
    def __init__(self, logger_name='logger', log_file_name='logs.log'):
        logger = logging.getLogger(logger_name)
        logger.setLevel(logging.DEBUG)

        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

        file_handler = logging.FileHandler(os.path.join(configs.LOGS_DIR, log_file_name))
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)

        self.logger = logger
    
    def get_logger(self):
        return self.logger

for i in range(5):
    logger = Logger(logger_name=f'test', log_file_name='test').get_logger()
    logger.info(i)

我期待着这个:

2024-12-20 21:17:09,623 - test - INFO - 0
2024-12-20 21:17:09,623 - test - INFO - 1
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,642 - test - INFO - 4

但这就是输出:

2024-12-20 21:17:09,623 - test - INFO - 0
2024-12-20 21:17:09,623 - test - INFO - 1
2024-12-20 21:17:09,623 - test - INFO - 1
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 2
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,623 - test - INFO - 3
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4
2024-12-20 21:17:09,642 - test - INFO - 4

为什么会发生这种情况以及如何解决这个问题?

python class logging
1个回答
0
投票

我通过创建这样的 Logger 类解决了这个问题:

class Logger:
    @staticmethod
    def __create_file_handler__(log_file_path, level, formatter):
        file_handler = logging.FileHandler(log_file_path)
        file_handler.setLevel(level)
        file_handler.setFormatter(formatter)
        return file_handler
    
    @staticmethod
    def __create_stdout_handler__(level, formatter):
        stdout_handler = logging.StreamHandler(sys.stdout)
        stdout_handler.setLevel(level)
        stdout_handler.setFormatter(formatter)
        return stdout_handler
    
    @staticmethod
    def get_logger(logger_name='logger', log_file_name='logs.log'):
        logger = logging.getLogger(logger_name)
        
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        file_handler_file_path = os.path.join(configs.LOGS_DIR, log_file_name)
        file_handler_level = logging.INFO
        stdout_handler_level = logging.INFO
        
        if logger.hasHandlers():
            file_handler = [_ for _ in logger.handlers if isinstance(_, logging.FileHandler)]
            
            if file_handler:
                file_handler = file_handler[0]
                if file_handler.baseFilename != log_file_name:
                    logger.removeHandler(file_handler)
                    logger.addHandler(Logger.__create_file_handler__(
                        file_handler_file_path,
                        file_handler_level,
                        formatter
                    ))
            
            return logger
        
        logger.setLevel(logging.DEBUG)
        logger.addHandler(Logger.__create_file_handler__(
            file_handler_file_path,
            file_handler_level,
            formatter
        ))

        if configs.STDOUT_LOGGING:
            logger.addHandler(Logger.__create_stdout_handler__(
                stdout_handler_level,
                formatter
            ))

        return logger

然后像这样在for循环中使用记录器

for i in range(5):
    logger = Logger.get_logger(logger_name=f'test', log_file_name='test')
    logger.info(i)

这样就解决了问题。

谢谢@john-gordon [约翰·戈登]给了我以另一种方式思考这个问题的见解。

© www.soinside.com 2019 - 2024. All rights reserved.