Python日志记录覆盖dictConfig级别

4
我正在使用以下dictConfig作为日志记录器。然而,我无法在运行时修改日志记录级别。
# log_config.json的内容
{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(name)-12s - %(levelname)-8s - %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        },
        "detailed": {
            "format": "%(asctime)s %(name)-12s %(module)-17s line:%(lineno)-4d %(levelname)-8s %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        }
    },

    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple",
            "stream": "ext://sys.stdout"
        },

        "info_file_handler": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "INFO",
            "formatter": "detailed",
            "filename": "info.log",
            "when": "midnight",
            "backupCount": 7,
            "encoding": "utf8"
        },

        "error_file_handler": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "ERROR",
            "formatter": "detailed",
            "filename": "errors.log",
            "when": "midnight",
            "backupCount": 7,
            "encoding": "utf8"
        }
    },

    "loggers": {
        "": {
            "level": "ERROR",
            "handlers": ["console"],
            "propagate": "no"
        }
    },

    "root": {
        "level": "NOTSET",
        "handlers": ["console", "info_file_handler", "error_file_handler"]
    }
}

然后我获取日志记录器并使用以下代码设置级别:

with open('/path/to/log_config.json', 'r') as fd:
    cfg = json.load(fd)

logging.config.dictConfig(cfg)
logger = logging.getLogger(__name__)
logger.setLevel(10)

但是,由于日志记录器是使用dictConfig创建的,我无法覆盖级别。我想建立一个UI工具,在运行时有一个选项菜单可以调整日志记录级别,而不必打开代码或json文件进行调整。我能够将级别调高,但是由于某种原因它不允许级别降低... 我想做的是将info_file和console处理程序设置为config中的INFO(20),然后在运行时有选择地将它们更改为DEBUG(10)。有什么想法吗?
2个回答

1
我遇到了类似的问题,最终找到了解决方法。
在我的情况下,我只想改变“console”处理程序的级别,但你可以轻松地将其扩展到所有处理程序并尝试一下:
logger = logging.getLogger(__name__)
for handler in logger.handlers:
    if handler.get_name() == 'console':
        handler.setLevel(logging.DEBUG)

(注意,我复制了你的__name__,但是我使用实际字符串来命名记录器 - 以防万一有影响)

2
对我不起作用,而且当我查看 logger.handlers 时,会得到 []。 - Jason Templeman
我这里也是一样。我按照提问者的方式配置和初始化了Logger实例,应用了@Starman提供的代码片段,结果输出类似 - 看起来所有logger属性都丢失了(handlers = [],level = 0等)。也许这是一个库的问题?另一方面,logger在初始配置中执行其任务正确(例如写入已声明的文件等),所以我有点困惑... - Marek Bocian
我曾经遇到相同的问题,最终这些解答让我明白我没有正确设置根记录器- https://dev59.com/VVYN5IYBdhLWcg3wdX2B 和 https://dev59.com/e4Hba4cB1Zd3GeqPRnm2?noredirect=1&lq=1 @MarekBocian - JJ101

1
我在寻找字典配置时发现了你的问题。我按照你的代码尝试,但我也无法更改日志级别,然后我发现了这个答案。使用@Tjorriemorrie的第三种解决方案而不是__name__可以返回正确的logger.handlers。并且我结合了@Starman的答案...现在我可以在任何时间和任何地点更改日志记录级别。
logger = logging.getLogger()
for handler in logger.handlers:
    if handler.get_name() == 'console':
        handler.setLevel(logging.DEBUG)

PS:谢谢您的代码片段!它对我很有帮助。


干得好。那么通过删除OP指定的“_name_”,它只会返回正确的记录器吗?这对OP有效吗?正如我在答案中提到的,我自己不在那里使用“_name_”,但是OP似乎想要一个以他的文件名命名的记录器,我猜测。 - Starman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接