首页 > 解决方案 > 在 Python 中为脚本或交互式会话设置日志记录

问题描述

我希望能够从 jupyter notebook 登录到 stderr,而无需编写有关登录 jupyter notebook 本身的任何信息,并且我希望能够在脚本启动时登录到文件。

默认情况下,在 jupyter notebook 中,日志记录设置为警告,因此我需要将其修改为 code.py 中的信息。

我在模块中有一些代码:

code.py

import logging
logger = logging.getLogger()

handler = logging.StreamHandler(sys.stderr)
if logger.level == 30:
    logger.setLevel(logging.INFO)
logger.handlers = [handler] + logger.handlers

def do_something_cool():
        logger.info("You are cool")

在 jupyter notebook 中,它以我想要的方式出现。

当我从脚本中使用此函数时,我会执行以下操作:

my_script.py
if __name__ == '__main__':
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    handler = logging.FileHandler(str(DIRECTORY / 'log_model_info.log'))
    logger.addHandler(handler)

对我来说,我在做的事情看起来像一个黑客code.py 有没有更好的方法来处理它?

标签: pythonjupyter-notebook

解决方案


根据基本日志记录教程 — Python 2.7.15 文档,您可以通过任一设置日志记录logging.basicConfig(),例如:

logging.basicConfig(stream=sys.stderr, level=logging.INFO)   # stream=sys.stderr is the default,
                                                             # so you can omit it

或者,到一个文件:

logging.basicConfig(filename='log_model_info.log', level=logging.INFO)        

或通过其他loggingAPI手动添加处理程序、调整级别、设置格式等--logger.addHandler()logger.setLevel()


对于您的特定情况,basicConfig()应该足够了:用于stream交互式控制台(或完全省略它,因为它stream=sys.stderr是默认设置)和filename脚本,如下面的示例所示。在这两种情况下,您都需要将级别至少调整为 INFO,因为根记录器的默认值是 WARN。

如果您只使用根记录器,也不需要获取Logger对象——使用模块级记录功能。

因此,您的第一个代码将变为:

import logging
logging.basicConfig(level=logging.INFO)

def do_something_cool():
    logging.info("You are cool")

第二个:

import logging
logging.basicConfig(filename='log_model_info.log', level=logging.INFO)

这也是我的无人值守脚本的典型日志记录设置代码 - 只是为了让您了解自定义logging设置代码的样子:

# set up logging #####################################
import sys,logging,logging.handlers,os.path
#place log alongside the script
log_file=os.path.splitext(__file__)[0]+".log"
l = logging.getLogger()
l.setLevel(logging.INFO)
f = logging.Formatter('%(asctime)s %(process)d:%(thread)d %(name)s %(levelname)-8s %(message)s')
h=logging.StreamHandler(sys.stdout)
h.setLevel(logging.NOTSET)
h.setFormatter(f)
l.addHandler(h)
h=logging.handlers.RotatingFileHandler(log_file,maxBytes=1024**2,backupCount=1)
h.setLevel(logging.NOTSET)
h.setFormatter(f)
l.addHandler(h)
del h,f
#hook to log unhandled exceptions
def excepthook(type,value,traceback):
    logging.error("Unhandled exception occured",exc_info=(type,value,traceback))
    #Don't need another copy of traceback on stderr
    if old_excepthook!=sys.__excepthook__:
        old_excepthook(type,value,traceback)
old_excepthook = sys.excepthook
sys.excepthook = excepthook
del log_file,os
# ####################################################

推荐阅读