在 Python 记录器中使用变量控制的日志记录级别

Posted

技术标签:

【中文标题】在 Python 记录器中使用变量控制的日志记录级别【英文标题】:Using variable-controlled logging level in Python logger 【发布时间】:2022-01-17 18:32:49 【问题描述】:

我想编写一个函数来获取用户请求的日志记录级别,例如:

import logging

logger = logging.getLogger()

def func(log_level: <Type?>):
    logger.log_level("everything is bad")

这个可以吗?

【问题讨论】:

【参考方案1】:

你可以用这个。它首先看起来有点冗长,但您可以轻松添加额外的处理程序(也许一些记录到文件中......)

import logging

logger = logging.getLogger()
handler = logging.StreamHandler() #you can also use FileHandler here, but then you need to specify a path
handler.setLevel(logging.NOTSET)

LOG_FORMAT = "%(levelname)s: %(message)s"
formatter = logging.Formatter(LOG_FORMAT)

handler.setFormatter(formatter)
logger.addHandler(handler)

logger.log(logging.CRITICAL, "your logging message 1") #==> CRITICAL: your logging message 1
logger.log(logging.WARN,     "your logging message 2") #==> WARN: your logging message 2

注1:LOG_FORMAT是根据logging-documentation定义的

注意 2:日志记录级别(logging.DEBUGlogging.INFO...)在 here 中进行了解释。您也可以相应地使用整数值:

logging.XX Value
NOTSET 0
DEBUG 10
INFO 20
WARN 30
ERROR 40
CRITICAL 50

【讨论】:

【参考方案2】:

只需使用记录器的log() method,它需要一个级别以及一个格式字符串和参数。

import logging

logger = logging.getLogger()

def func(log_level: int, message: str):
    logger.log(log_level, message)
    
logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(message)s')

func(logging.DEBUG, 'message at DEBUG level')
func(logging.INFO, 'message at INFO level')
func(logging.CRITICAL, 'message at CRITICAL level')

打印出来的

DEBUG    message at DEBUG level
INFO     message at INFO level
CRITICAL message at CRITICAL level

运行时。

【讨论】:

【参考方案3】:

您可以使用上下文管理器,我在文档中引用“有时临时更改日志配置并在执行某些操作后将其恢复回来很有用。为此,上下文管理器是最明显的方式保存和恢复日志上下文。下面是这样一个上下文管理器的简单示例,它允许您选择性地更改日志记录级别并在上下文管理器的范围内添加一个日志处理程序:"

import logging
import sys

class LoggingContext:
    def __init__(self, logger, level=None, handler=None, close=True):
        self.logger = logger
        self.level = level
        self.handler = handler
        self.close = close

    def __enter__(self):
        if self.level is not None:
            self.old_level = self.logger.level
            self.logger.setLevel(self.level)
        if self.handler:
            self.logger.addHandler(self.handler)

    def __exit__(self, et, ev, tb):
        if self.level is not None:
            self.logger.setLevel(self.old_level)
        if self.handler:
            self.logger.removeHandler(self.handler)
        if self.handler and self.close:
            self.handler.close()
        # implicit return of None => don't swallow exceptions

确切地在文档中,它在这里:https://docs.python.org/3/howto/logging-cookbook.html#using-a-context-manager-for-selective-logging。 您还可以重写任何示例代码 sn-ps 来自:https://docs.python.org/3/howto/logging-cookbook.html#using-logging-in-multiple-modules。

【讨论】:

以上是关于在 Python 记录器中使用变量控制的日志记录级别的主要内容,如果未能解决你的问题,请参考以下文章

在Python日志记录模块中禁止换行

拦截 Python 中的所有日志记录

python中更优雅的记录日志

Blender Python 语句控制台日志记录

python日志的记录与保存

如何使用 Python 在日志文件中复制/捕获标准输出