我为这个问题找到的大多数答案都使用了根记录器的 basicConfig。
这对于打算使用多个未使用 basicConfig 初始化的独立记录器的人没有帮助。 basicConfig 的使用意味着所有记录器的日志级别将被更改。它还具有生成重复日志的不幸副作用。
所以我尝试了几天来尝试不同的方法来操作日志级别,并想出了一种最终奏效的方法。
诀窍是不仅要更改所有处理程序的日志级别,还要更改记录器父级的所有处理程序。
def setLevel(self, infoLevel):
# To dynamically reset the loglevel, you need to also change the parent levels as well as all handlers!
self.logger.parent.setLevel(infoLevel)
for handler in self.logger.parent.handlers:
handler.setLevel(infoLevel)
self.logger.setLevel(infoLevel)
for handler in self.logger.handlers:
handler.setLevel(infoLevel)
灵感来自于 basicConfig 更改了根记录器设置的事实,所以我尝试在不使用 basicConfig 的情况下做同样的事情。
对于那些感兴趣的人,我在 Github 上做了一个小 Python 项目,说明了设置记录器的 loglevel 的不同问题(它部分工作),证明 SLogger(Sample Logger)实现工作,还说明了重复的日志使用多个未使用它初始化的记录器时,basicConfig 出现问题。
https://github.com/FrancisChung/python-logging-playground
TLDR:如果您只对记录器的工作示例代码感兴趣,下面列出了实现
import logging
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
class SLogger():
"""
SLogger : Sample Logger class using the standard Python logging Library
Parameters:
name : Name of the Logger
infoLevel : logging level of the Logger (e.g. logging.DEBUG/INFO/WARNING/ERROR)
"""
def __init__(self, name: str, infoLevel=logging.INFO):
try:
if name is None:
raise ValueError("Name argument not specified")
logformat = '%(asctime)s %(levelname)s [%(name)s %(funcName)s] %(message)s'
self.logformat = logformat
self.name = name.upper()
self.logger = logging.getLogger(self.name)
self.logger.setLevel(infoLevel)
self.add_consolehandler(infoLevel, logformat)
except Exception as e:
if self.logger:
self.logger.error(str(e))
def error(self, message):
self.logger.error(message)
def info(self, message):
self.logger.info(message)
def warning(self, message):
self.logger.warning(message)
def debug(self, message):
self.logger.debug(message)
def critical(self, message):
self.logger.critical(message)
def setLevel(self, infoLevel):
# To dynamically reset the loglevel, you need to also change the parent levels as well as all handlers!
self.logger.parent.setLevel(infoLevel)
for handler in self.logger.parent.handlers:
handler.setLevel(infoLevel)
self.logger.setLevel(infoLevel)
for handler in self.logger.handlers:
handler.setLevel(infoLevel)
return self.logger.level
def add_consolehandler(self, infoLevel=logging.INFO,
logformat='%(asctime)s %(levelname)s [%(name)s %(funcName)s] %(message)s'):
sh = logging.StreamHandler()
sh.setLevel(infoLevel)
formatter = logging.Formatter(logformat)
sh.setFormatter(formatter)
self.logger.addHandler(sh)