正在忽略记录setLevel

meh*_*meh 29 python logging

以下代码是从文档中复制的.我应该能够看到所有的信息日志.但我没有.即使我已将setLevel设置为INFO,我也只能看到警告及以上.

为什么会这样?foo.py:

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
Run Code Online (Sandbox Code Playgroud)

输出:

workingDirectory$ python foo.py
warn message
error message
critical message
Run Code Online (Sandbox Code Playgroud)

信息和调试消息在哪里?

小智 24

试试logging.basicConfig()在那里跑步.值得注意的是,我看到你提到INFO,但是使用DEBUG.如上所述,它应该显示所有五条消息.用INFO交换DEBUG,你应该看到四条消息.

import logging

logging.basicConfig()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
Run Code Online (Sandbox Code Playgroud)

编辑:您是否已在代码中的其他位置设置了日志记录?无法使用提供的特定代码重现您注意到的确切行为.


Vin*_*jip 22

更换线

logger.setLevel(logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

logging.basicConfig(level=logging.DEBUG, format='%(message)s')
Run Code Online (Sandbox Code Playgroud)

它应该按预期工作.如果您没有使用任何处理程序配置日志记录(如在帖子中 - 您只为记录器配置一个级别,但在任何地方都没有处理程序),您将获得一个"最后手段"的内部处理程序,它被设置为仅输出WARNING级别上的消息(没有其他格式).

  • 保持 - 这设置了全局/根日志记录设置,但是如果我只想为`logger`设置级别呢?为什么`logger.setLevel(logging.DEBUG)`不起作用?这应该. (9认同)
  • 它仍然应该工作.用户明确设置级别. (8认同)
  • 所以在getLogger()之后调用`logger.setlevel(logging.DEBUG)`是不够的。我还必须惹一个处理程序吗?那一点都不直观。 (4认同)
  • 来自其他编程语言,这是愚蠢的。 (4认同)
  • @Greg因为没有配置处理程序,所以日志记录使用内部"最后处理程序",其级别为"警告":https://docs.python.org/3.2/library/logging.html#logging.lastResort (3认同)
  • 我认为很明显,默认应该输出到标准输出(如果可能)。假设我在运行其他人的初始化脚本后从其他人那里拉入记录器,我应该仔细检查它们并确保他们不会调用 basicConfig ?我只是想确保记录器在调试级别进行记录。 (2认同)
  • 如果没有指定处理程序,我真的更喜欢异常。 (2认同)

Mil*_*vis 22

正如一些用户所指出的,使用:

logging.basicConfig(level=logging.DEBUG, format='%(message)s')
Run Code Online (Sandbox Code Playgroud)

像在接受的 answare 中编写的那样不是一个goot选项,因为它全局设置了日志级别,因此它将记录来自每个记录器的调试消息。

在我的情况下,为我的记录器设置日志级别的最佳解决方案是:

import logging

logger = logging.getLogger('MyLogger')
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

不是真正直观的解决方案,但如果您只想为“MyLogger”而不是全局设置日志级别,则这是必要的。


Ray*_*Luo 9

这在技术上也是一个“答案”,因为它可以“解决”问题。但我绝对不喜欢它。这并不直观,我为此浪费了 2 个多小时。

前:

import logging
logger = logging.getLogger('foo')
logger.setLevel(logging.INFO)
logger.info('You can not see me')
# Or you can just use the following one-liner in command line.
# $ python -c "import logging; logger = logging.getLogger('foo'); logger.setLevel(logging.INFO); logger.info('You can not see me')"
Run Code Online (Sandbox Code Playgroud)

后:

import logging

logging.debug('invisible magic')  # <-- magic

logger = logging.getLogger('foo')
logger.setLevel(logging.INFO)
logger.info('But now you can see me')
# Or you can just use the following one-liner in command line.
$ python -c "import logging; logging.debug('invisible magic'); logger = logging.getLogger('foo'); logger.setLevel(logging.INFO); logger.info('But now you see me')"
Run Code Online (Sandbox Code Playgroud)

PS:将其与当前选择的答案以及@Vinay-Sajip 的解释进行比较,我可以理解为什么。但我仍然希望事情不是这样进行的。

  • 这确实令人困惑,这让我问/sf/ask/3998077681/ 我发现那里接受的答案非常有帮助:-) (4认同)

Dev*_*yzr 5

如果您希望在没有 basicConfig 的情况下也能正常工作,则必须首先设置登录记录器的最低可能级别。由于记录器设置了最小阈值,因此具有较低阈值但属于同一记录器的处理程序将不会收到这些较低阈值消息,因为它们首先被记录器忽略。直观,但不明显。

我们首先这样做:

lgr = logging.getLogger(name)
lgr.setLevel(logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

然后,使用您需要的不同级别设置处理程序,在我的例子中,我希望在标准输出上进行调试日志记录,并将信息日志记录到旋转文件中,因此我执行以下操作:

rot_hndlr = RotatingFileHandler('filename.log',
                                maxBytes=log_size,
                                backupCount=3)
    
rot_hndlr.setFormatter(formatter)
rot_hndlr.setLevel(logging.INFO)
lgr.addHandler(rot_hndlr)

stream_hndlr = logging.StreamHandler()
stream_hndlr.setFormatter(stream_formatter)
lgr.addHandler(stream_hndlr)
Run Code Online (Sandbox Code Playgroud)

然后,为了测试,我这样做:

lgr.debug("Hello")
lgr.info("There")
Run Code Online (Sandbox Code Playgroud)

我的标准输出(控制台)将如下所示:

Hello
There
Run Code Online (Sandbox Code Playgroud)

我的filename.log文件将如下所示:

There
Run Code Online (Sandbox Code Playgroud)