【问题标题】:Python logging override dictConfig levelPython 日志记录覆盖 dictConfig 级别
【发布时间】:2017-06-20 21:27:25
【问题描述】:

我正在为记录器使用以下 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 和控制台处理程序设置为 INFO (20),然后可以选择在运行时将它们更改为 DEBUG (10)。有什么想法吗?

【问题讨论】:

    标签: python json logging config log-level


    【解决方案1】:

    我遇到了类似的问题,刚刚解决了。

    就我而言,我只想更改“控制台”处理程序的级别,但您可以轻松地将其扩展到所有处理程序并尝试一下:

    logger = logging.getLogger(__name__)
    for handler in logger.handlers:
        if handler.get_name() == 'console':
            handler.setLevel(logging.DEBUG)
    

    (请注意,我复制了您的 __name__,但对我来说,我使用的是实际字符串来命名记录器 - 以防万一)

    【讨论】:

    • 不适合我,当我查看 logger.handlers 时,我得到 []。
    • 这里也一样。我以与问题作者类似的方式配置和初始化 Logger 实例,应用了@Starman 提供的 sn-p 并且我得到了类似的输出 - 看起来 logger 的所有属性都丢失了(handlers = []、level = 0 等。 )。也许这是图书馆的问题?另一方面,记录器正确执行初始配置中描述的任务(例如写入声明的文件等),所以我有点困惑......
    • 我遇到了同样的问题,这些最终为我澄清了我没有正确设置根记录器 - stackoverflow.com/questions/47422689/…stackoverflow.com/questions/24719421/… @MarekBocian
    【解决方案2】:

    我正在寻找一个 dict 配置,我找到了你的问题。我遵循了您的确切代码,我也无法更改日志级别,然后我找到了this answer。而不是__name__ 使用@Tjorriemorrie 的第三个解决方案返回正确的logger.handlers。并且我结合了@Starman 的answer...现在我可以随时随地更改日志记录级别。

    logger = logging.getLogger()
    for handler in logger.handlers:
        if handler.get_name() == 'console':
            handler.setLevel(logging.DEBUG)
    

    PS:感谢您的代码 sn-p!这对我帮助很大。

    【讨论】:

    • 干得好。 \n。因此,通过删除 OP 指定的 _name_ ,它只会返回正确的记录器?这对OP有用吗?正如我在回答中提到的那样,我自己并没有在那里使用_name_,但我猜 OP 似乎想要一个以他的文件名命名的记录器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2012-01-12
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多