python使用配置文件配置logging, 如何方便的将多个logger打印到不同的文件?

发布于 2022-09-07 12:00:38 字数 547 浏览 23 评论 0

我目前只知道可以这样:

handlers:
    file_a:
        formatter: standard
        filename: /var/log/a.log
    file_b:
        formatter: standard
        filename: /var/log/b.log
loggers:
    logger_a:
        level: DEBUG
        handlers: [file_a]
    logger_b:
        level: DEBUG
        handlers: [file_b]

又没有什么方法可以根据logger的名称来决定文件名?
比如这样:

handlers:
    multi_file:
        filename: /var/log/{name}.log

目前考虑可用的就是包装下logging.getLogger方法, 在拿logger的时候去配置它的fileHandler, 又没有更简单易用的方式?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后来的我们 2022-09-14 12:00:38

实现了一下我说的那种方式, 感觉这样太笨重了...

class MyFileHandlerFactory(logging.handlers.RotatingFileHandler):
    def __init__(self, filename, **kwargs):
        FileUtils.ready_file_dir(filename)
        super(MyFileHandlerFactory, self).__init__(filename, **kwargs)


def wrap_logger():
    _raw_getLogger = logging.getLogger

    def getLogger(name=None):
        logger = _raw_getLogger(name)
        if name is None:
            return logger
        for i in range(len(logger.handlers)):
            old_handler = logger.handlers[i]
            if not isinstance(old_handler, logging.handlers.RotatingFileHandler):
                continue
            base_file_name = old_handler.baseFilename
            if '{logger_name}' not in base_file_name:
                continue
            new_handler = MyFileHandlerFactory(base_file_name.format(logger_name=logger.name.replace('.', '_')),
                                               mode=old_handler.mode,
                                               maxBytes=old_handler.maxBytes,
                                               backupCount=old_handler.backupCount,
                                               encoding=old_handler.encoding,
                                               delay=old_handler.delay)
            new_handler.setFormatter(old_handler.formatter)
            new_handler.setLevel(old_handler.level)
            new_handler.set_name(logger.name + '.' + old_handler.name)
            logger.handlers[i] = new_handler
        return logger

    if logging.getLogger.__module__ != 'logging':
        # 已经被包装过了
        return
    logging.getLogger = getLogger


def init():
    import yaml
    with open(config.get_resource_path('logger.yml')) as f_conf:
        dict_conf = yaml.load(f_conf)
    logging.config.dictConfig(dict_conf)
    wrap_logger()
浅忆 2022-09-14 12:00:38

反正我的经验就是能不写wrapper就不写,因为你不知道后面维护这份代码的人能不能看懂你写的嵌套。

我觉得可以简单继承一下logging的Manager类来实现:

import logging


class CustomManger(logging.Manager):
    def getLogger(self, name, format=None):
        logger = super(CustomManger, self).getLogger(name)
        # 简单写一下,Formatter你自己实现吧
        filename = '{}.log'.format(name)
        logger.addHandler(logging.FileHandler(filename))
        return logger


manager = CustomManger(logging.root)
if __name__ == '__main__':
        
    logger_a = manager.getLogger('a')
    logger_b = manager.getLogger('b')
    logger_a.error('111')
    logger_b.error('222')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文