Python 3.x 如何使用logging.config.dictConfig()设置具有不同设置的多个记录器
我正在尝试使用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
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-我将其转换为字符串格式,这就解决了它。谢谢