Python 3.x 如何使用logging.config.dictConfig()设置具有不同设置的多个记录器

Python 3.x 如何使用logging.config.dictConfig()设置具有不同设置的多个记录器,python-3.x,logging,Python 3.x,Logging,我正在尝试使用dictConfig设置三个不同的记录器,出于某种原因,最后一个记录器似乎总是覆盖之前创建的两个记录器的配置。以下是我正在使用的代码: import logging import logging.config def setup_logger(name, level, ContentFormat='%(asctime)s %(levelname)s %(message)s', DateTimeFormat='%Y-%m-%d %H:%M:%S'): logging.con

我正在尝试使用dictConfig设置三个不同的记录器,出于某种原因,最后一个记录器似乎总是覆盖之前创建的两个记录器的配置。以下是我正在使用的代码:

import logging
import logging.config

def setup_logger(name, level, ContentFormat='%(asctime)s %(levelname)s %(message)s', DateTimeFormat='%Y-%m-%d %H:%M:%S'):
    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'default': {'format': ContentFormat, 'datefmt': DateTimeFormat},
        },
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
                'level': level,
                'formatter': 'default',
                'stream': 'ext://sys.stdout'
            }
        },
        'loggers': {
            'a': {
                'level': level,
                'handlers': ['console']
            },
            'b': {
                'level': level,
                'handlers': ['console']
            },
            'c': {
                'level': level,
                'handlers': ['console']
            }
        }
    })
    return logging.getLogger(name)

logger_a = setup_logger(name='a', level=logging.INFO, ContentFormat='A: %(message)s')
logger_b = setup_logger(name='b', level=logging.INFO, ContentFormat='B: %(message)s')
logger_c = setup_logger(name='c', level=logging.INFO, ContentFormat='C: %(message)s')

logger_a.info('logger_a')
logger_b.info('logger_b')
logger_b.info('logger_c')
这是输出:

C: logger_a
C: logger_b
C: logger_c
相反,我想看到的是:

A: logger_a
B: logger_b
C: logger_c
知道我做错了什么吗?我甚至尝试过制作多个处理程序,但仍然遇到同样的问题

我有这个函数的另一个版本,它使用以下代码,我可以多次调用它来创建多个具有不同设置的单独记录器,但我真的很想知道如何使用dictConfig来实现这一点,或者至少了解我的错误所在:

logger = logging.getLogger(name)
logger.setLevel(level)

# create console handler for printing logging output to the screen as well
formatter = logging.Formatter(ContentFormat, DateTimeFormat)
handler = logging.StreamHandler()
handler.setLevel(level)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger

之所以会发生这种情况,是因为您创建并覆盖了全局配置3次。您使用了
default
格式化程序来配置特定的记录器,最后一个
C
用于记录您的记录

您可以使用以下代码轻松地进行检查:

def设置\u记录器(名称、级别、日期时间格式=“%Y-%m-%d%H:%m:%S”):
cfg={
“版本”:1,
“禁用现有日志记录器”:False,
“格式化程序”:{
'default_for_a':{'format':'a:%(message)s','datefmt':DateTimeFormat},
'default_for_b':{'format':'b:%(message)s','datefmt':DateTimeFormat},
'default_for_c':{'format':'c:%(message)s','datefmt':DateTimeFormat}
},
“处理程序”:{
“控制台a的控制台a”:{
'class':'logging.StreamHandler',
“级别”:级别,
“格式化程序”:“a的默认值”,
'流':'ext://sys.stdout'
},
“控制台用于控制台b”:{
'class':'logging.StreamHandler',
“级别”:级别,
'格式化程序':'默认\u for_b',
'流':'ext://sys.stdout'
},
“控制台用于c”:{
'class':'logging.StreamHandler',
“级别”:级别,
“格式化程序”:“c的默认值”,
'流':'ext://sys.stdout'
},
},
“伐木工人”:{
“a”:{
“级别”:级别,
'handlers':['console\u for_a']
},
“b”:{
“级别”:级别,
'handlers':['console\u for\u b']
},
“c”:{
“级别”:级别,
'handlers':['console_for_c']
}
}
}
logging.config.dictConfig(cfg)
返回logging.getLogger(名称)
记录器\u a=设置\u记录器(name='a',level=logging.INFO)
logger\u b=setup\u logger(name='b',level=logging.INFO)
logger\u c=setup\u logger(name='c',level=logging.INFO)
记录器_a.info('logger_a')
logger_b.info('logger_b'))
logger_c.info('logger_c')
或者让代码更通用

导入日志
导入logging.config
def安装程序\u记录器(名称、级别、内容格式='(asctime)s%(级别名称)s%(消息)s',日期时间格式=“%Y-%m-%d%H:%m:%s”):
cfg={
“版本”:1,
“禁用现有日志记录器”:False,
“格式化程序”:{
f'default_for_{name}:{'format':ContentFormat,'datefmt':DateTimeFormat}
},
“处理程序”:{
f'console_for_{name}':{
'class':'logging.StreamHandler',
“级别”:级别,
'formatter':f'default_for{name}',
'流':'ext://sys.stdout'
},
},
“伐木工人”:{
姓名:{
“级别”:级别,
'handlers':[f'console_for_{name}']
}
}
}
logging.config.dictConfig(cfg)
返回logging.getLogger(名称)
logger\u a=setup\u logger(name='a',level=logging.INFO,ContentFormat='a:%(message)s')
logger\u b=setup\u logger(name='b',level=logging.INFO,ContentFormat='b:%(message)s')
logger\u c=setup\u logger(name='c',level=logging.INFO,ContentFormat='c:%(message)s')
记录器_a.info('logger_a')
logger_b.info('logger_b'))
logger_c.info('logger_c')
输出为:

A:logger\u A
B:好的
C:U\C

ohhhh。。。。我没有意识到您只需调用它一次就可以配置所有内容(或者像上一个示例一样,多次使用变量)。这很有帮助!当我尝试您的示例时,它似乎不喜欢f字符串作为格式化程序的ID:文件“logger.py”,第10行f'default_for{name}:{'format':ContentFormat,'datefmt':DateTimeFormat}^语法错误:无效语法-语法错误箭头指向{name}中的第一个括号@Mike您使用的Python版本是什么?此语法自3.6版起可用。如果使用较低版本的python 3,则必须用旧版本的字符串格式替换表达式<代码>“{name}”。格式(name=name)例如。啊。。。3.5-我将其转换为字符串格式,这就解决了它。谢谢