在IPython Notebook中从logging模块获取输出

205

当我在IPython Notebook中运行以下代码时,我看不到任何输出:

import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug("test")

有人知道如何让我在笔记本中看到“test”消息吗?


你使用的IPython版本是什么,因为这在1.0中有效? - Viktor Kerkez
@ViktorKerkez ipython3 notebook --version 返回 1.0.0 - Kyle Brandt
当我尝试运行你的代码时,我得到了这个。 - Viktor Kerkez
@ViktorKerkez:是啊,我也不明白,我想我应该提交一个问题... - Kyle Brandt
10个回答

201

尝试以下操作:

import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logging.debug("test")

根据logging.basicConfig

通过创建一个带有默认格式化程序的StreamHandler并将其添加到根记录器中,为记录系统执行基本配置。如果未为根记录器定义处理程序,则函数debug()、info()、warning()、error()和critical()会自动调用basicConfig()。

如果为根记录器已经配置了处理程序,则此函数不执行任何操作。

看起来像是IPython Notebook在某个地方调用了basicConfig(或设置了处理程序)。


4
在普通的IPython控制台中也会发生同样的情况:除非创建了根logger,否则不会打印任何内容。 - 0 _
1
这个解决方案在 ipykernel 4.5 中再次可用(可能早在4.4版本中就可用了)。https://github.com/jupyter/notebook/issues/1397 - pylang
41
无法继续使用了,与Jupyter Notebook 5.3.0不再兼容。 - Sam
1
请注意,在更改 logging.basicConfig 生效之前,似乎需要重新启动笔记本内核。 - cchwala
请注意,这将在根记录器上设置日志级别,而不是在任何特定处理程序上。您可以随后按处理程序设置日志级别。 - robertspierre
显示剩余2条评论

92

如果你仍然想要使用basicConfig,请按照以下方式重新加载日志模块

from importlib import reload  # Not needed in Python 2
import logging
reload(logging)
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', level=logging.DEBUG, datefmt='%I:%M:%S')

19
针对任何试图在Python 3中执行此操作的人:reload现在是imp.reload - kuzzooroo
13
从Python 3.5开始,由于imp模块被弃用,因此应该使用importlib.reload - Webucator
2
如果有人在使用Spyder时遇到了日志记录问题(尝试修改记录器行为却一直不成功),这个链接可能会解决你一整天的问题。https://github.com/spyder-ide/spyder/issues/2572 非常感谢! - FrenchKheldar
reload 帮助了我,因为我在 Jupyter 控制台中没有看到日志消息。Grazie) - undefined

40

我的理解是IPython会启动日志记录,所以basicConfig无法正常工作。这里是适用于我的设置(我希望它看起来不那么丑陋,因为我想将其用于几乎所有的笔记本):

import logging
logger = logging.getLogger()
fhandler = logging.FileHandler(filename='mylog.log', mode='a')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fhandler.setFormatter(formatter)
logger.addHandler(fhandler)
logger.setLevel(logging.DEBUG)
现在当我运行时:
logging.error('hello!')
logging.debug('This is a debug message')
logging.info('this is an info message')
logging.warning('tbllalfhldfhd, warning.')

在与我的笔记本相同的目录中,我会得到一个名为“mylog.log”的文件,其中包含:

2015-01-28 09:49:25,026 - root - ERROR - hello!
2015-01-28 09:49:25,028 - root - DEBUG - This is a debug message
2015-01-28 09:49:25,029 - root - INFO - this is an info message
2015-01-28 09:49:25,032 - root - WARNING - tbllalfhldfhd, warning.
请注意,如果不重新启动IPython会话并重新运行此命令,则会向文件中写入重复条目,因为现在定义了两个文件处理程序。

4
为了使这个看起来不那么“丑陋”,将代码放在你的Python路径上的一个模块中,然后进行导入。这样更加美观,而且未来升级也更加方便。 - alexis
1
或者使用 logging.config.fileConfig('logging.conf') 并将所有设置放在其中。 - K.-Michael Aye

29
请注意,logging模块的默认流是stderr,因此在IPython和Jupyter笔记本中,除非您将流配置为stdout,否则可能看不到任何输出:
import logging
import sys

logging.basicConfig(format='%(asctime)s | %(levelname)s : %(message)s',
                     level=logging.INFO, stream=sys.stdout)

logging.info('Hello world!')

23

对我有效的是现在使用的(Jupyter,笔记本服务器为:5.4.1,IPython 7.0.1)

import logging
logging.basicConfig()
logger = logging.getLogger('Something')
logger.setLevel(logging.DEBUG)

现在我可以使用记录器来打印信息,否则我只会看到默认级别(logging.WARNING)或更高级别的消息。


3
可以,需要运行basicConfig()才能使它正常工作。 - Brandt

15

您可以通过运行 %config Application.log_level="INFO" 来配置日志记录。

有关更多信息,请参见IPython内核选项


2
欢迎来到 StackOverflow 并感谢您的帮助。您可以通过添加一些解释使您的答案更好。 - Kenzo_Gilead
1
这对我来说是最有用的答案! - IanS
1
你能加几行代码举个例子吗?调用哪个记录器句柄来打印日志消息? - Sam
至少ipython 7.9.0(或jupyter 6.0.2)忽略了建议的代码,因为它不支持从运行控制台中使用此类。 运行%config以查看支持的类,Application不是其中之一。这里是ipython 7.9.0。 - stason

14

在日志记录版本3.8中,force参数已添加, 可以删除任何现有的处理程序,这使得basicConfig能够运行。此功能在IPython版本7.29.0和Jupyter Lab版本3.2.1上可用。

import logging
logging.basicConfig(level=logging.DEBUG,
                    force = True)
logging.debug("test")

1
请有人删除所有过时的答案。这就是正确的做法!谢谢! - Daniel Darabos

5

我为文件设置了一个日志记录器,并希望它显示在笔记本上。结果发现添加文件处理程序会清除默认的流处理程序。

logger = logging.getLogger()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# Setup file handler
fhandler  = logging.FileHandler('my.log')
fhandler.setLevel(logging.DEBUG)
fhandler.setFormatter(formatter)

# Configure stream handler for the cells
chandler = logging.StreamHandler()
chandler.setLevel(logging.DEBUG)
chandler.setFormatter(formatter)

# Add both handlers
logger.addHandler(fhandler)
logger.addHandler(chandler)
logger.setLevel(logging.DEBUG)

# Show the handlers
logger.handlers

# Log Something
logger.info("Test info")
logger.debug("Test debug")
logger.error("Test error")

FYI - 这里的 logger 是根记录器。我认为最好的做法是创建一个新的记录器,例如使用 getLogger(__name__)。这是文档推荐的做法,在此处的第二段中有说明:https://docs.python.org/3/library/logging.html#logger-objects - william_grisaitis

5

我希望能够简单明了地回答这个问题,并提供精美样式的输出,以下是我的建议:

import sys
import logging

logging.basicConfig(
    format='%(asctime)s [%(levelname)s] %(name)s - %(message)s',
    level=logging.INFO,
    datefmt='%Y-%m-%d %H:%M:%S',
    stream=sys.stdout,
)
log = logging.getLogger('notebook')

然后你可以在笔记本的任何地方使用log.info() 或者其他日志级别,输出结果如下:

2020-10-28 17:07:08 [INFO] notebook - Hello world
2020-10-28 17:12:22 [INFO] notebook - More info here
2020-10-28 17:12:22 [INFO] notebook - And some more

在Jupyter Lab中,stream=sys.stdout对我很有用。 - irene

1

设置

import logging

# make a handler
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# add it to the root logger
logging.getLogger().addHandler(handler)

使用自己的日志记录器记录日志

# make a logger for this notebook, set verbosity
logger = logging.getLogger(__name__)
logger.setLevel('DEBUG')

# send messages
logger.debug("debug message")
logger.info("so much info")
logger.warning("you've veen warned!")
logger.error("bad news")
logger.critical("really bad news")

2021-09-02 18:18:27,397 - __main__ - DEBUG - debug message
2021-09-02 18:18:27,397 - __main__ - INFO - so much info
2021-09-02 18:18:27,398 - __main__ - WARNING - you've veen warned!
2021-09-02 18:18:27,398 - __main__ - ERROR - bad news
2021-09-02 18:18:27,399 - __main__ - CRITICAL - really bad news

捕获其他库的日志

logging.getLogger('google').setLevel('DEBUG')

from google.cloud import storage

client = storage.Client()

2021-09-02 18:18:27,415 - google.auth._default - DEBUG - Checking None for explicit credentials as part of auth process...
2021-09-02 18:18:27,416 - google.auth._default - DEBUG - Checking Cloud SDK credentials as part of auth process...
2021-09-02 18:18:27,416 - google.auth._default - DEBUG - Cloud SDK credentials not found on disk; not using them
...

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