python日志记录设置多个记录器并在它们之间切换

时间:2019-05-29 23:34:49

标签: python python-3.x logging

我有一个带循环的程序,我想设置一个主记录器来记录整个程序中的信息。我想为每个循环实例在循环内设置一个不同的记录器(我将其称为“ logger_instance”)。主记录器还需要能够在循环中记录一些信息。

当前代码的问题如下:一旦我在循环内初始化logger_instance,我打算记录到主记录器的信息就会记录到logger_instance而不是主记录器中。

下面是示例代码:

img = Image.fromarray(IMIR)

log_main.txt包含

 "DBClusters": [
    {
        ...
        "AssociatedRoles": [
            {
                "Status": "ACTIVE",
                "RoleArn": "<role-arn>"
            }
        ],
        ...
    }
   ]

log_0.txt包含

class DispatchingFormatter:
"""
This allows to create several formatter objects with desired formats so that logging outputs can take different
formats
"""
    def __init__(self, formatters, default_formatter):
        self._formatters = formatters
        self._default_formatter = default_formatter

    def format(self, record):
        formatter_obj = self._formatters.get(record.name, self._default_formatter)
        return formatter_obj.format(record)

def initiate_logger(log_file_name):

    # Set logging to display INFO level or above
    logging.basicConfig(level=logging.INFO)

    # First empty out list of handlers to remove the default handler created by the running basicConfig above
    # logging.getLogger().handlers.clear()
    logger = logging.getLogger()
    logger.handlers.clear()
    # logger = logging.getLogger().handlers.clear()

    # Set up formatter objects
    formatter_obj = DispatchingFormatter(
    # Custom formats - add new desired formats here
    {
        # This format allows to print the user and the time - use this log format at the start of the execution
        'start_log': logging.Formatter('\n%(levelname)s - %(message)s executed the pipeline at %(asctime)s',
                                       datefmt='%Y-%m-%d %H:%M:%S'),
        # This format allows to print the time - use this log format at the end of the execution
        'end_log': logging.Formatter('\n%(levelname)s - pipeline execution completed at %(asctime)s',
                                     datefmt='%Y-%m-%d %H:%M:%S'),
        # This format allows to print the duration - use this log format at the end of the execution
        'duration_log': logging.Formatter('\n%(levelname)s - total time elapsed: %(message)s minutes'),
        # This is the format of warning messages
        'warning_log': logging.Formatter('\n\t\t%(levelname)s - %(message)s'),
        # This is the format of error messages (
        'error_log': logging.Formatter('\n%(levelname)s! [%(filename)s:line %(lineno)s - %(funcName)20s()] - '
                                       'Pipeline terminating!\n\t%(message)s')
    },
        # Default format - this default is used to print all ESN outputs
        logging.Formatter('%(message)s'),
    )

    # Log to console (stdout)
    c_handler = logging.StreamHandler()
    c_handler.setFormatter(formatter_obj)
    # logging.getLogger().addHandler(c_handler)
    logger.addHandler(c_handler)

    # Log to file in runs folder
    f_handler = logging.FileHandler(log_file_name, 'w+')
    f_handler.setFormatter(formatter_obj)
    # logging.getLogger().addHandler(f_handler)

    logger.addHandler(f_handler)

    # Log user and start time information upon creating the logger
    logging.getLogger('start_log').info(f'{getpass.getuser()}')

    return logger

if __name__ == '__main__':
    # Test logging

    # Initial main logger for outside the loop
    logger_main = initiate_logger('log_main.txt')
    logger_main.info(f'Started the main logging')

    for i in range(5):
        # Create logger in a loop
        this_logger = initiate_logger(f'log_{str(i)}.txt')
        this_logger.info(f'Logging in a loop - loop #{str(i)}')

        # Log some information to main logger
        logger_main.info(f'Something happened in loop #{str(i)}')

    # Log more information to main logger after the loop
    logger_main.info(f'Loop completed!')

log_main.txt的所需输出应为

INFO - this_user executed the pipeline at 2019-05-29 19:15:47
Started the main logging

log_0.txt的所需输出应为

INFO - lqk4061 executed the pipeline at 2019-05-29 19:15:47
Logging in a loop - loop #0
Something happened in loop #0

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

之所以会这样,是因为您的initiate_logger函数始终返回根记录器,因为它调用了没有名称的getlogger。请参见documentation。如果您希望它们成为不同的记录器实例,则需要为它们分别命名。例如logger = logging.getLogger(log_file_name)可以在您的代码中使用。我建议改用filters