python - 在 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
有没有更好的方法来处理它?
解决方案
根据基本日志记录教程 — 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)
或通过其他logging
API手动添加处理程序、调整级别、设置格式等--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
# ####################################################
推荐阅读
- android - Android 10 双自拍相机回归?
- html - CSS - 滚动时让导航栏粘在固定顶部的导航栏上?
- backbone.js - 为什么我的backbone.js 集合没有加载正确的数据列表?
- node.js - 我正在尝试在 express 中创建一个全局变量(也使用猫鼬),但是当页面刷新时应用程序会不断删除该变量
- python - 通过按下另一个类中的按钮来隐藏一个类中的标签
- ios - 命令 xcodebuild 失败,退出代码为 70 - Nativescript
- python - 将订单添加到使用 Beautiful Soap 接收的数据时出错
- c# - Unity3D:我怎样才能让我的玩家去我用鼠标点击的地方,没有导航网格代理?
- java - 数据结构可以在不使用任何数组的情况下具有 O(1) 访问时间吗?
- sql - 在 Rails 中的仪表板视图上处理繁重 SQL 查询的最佳方法