Python 日志 logging 入门:别再只用 print 调试了
Python 日志 logging 入门:别再只用 print 调试了
print 够用,但不够好
写 Python 小脚本时,几乎人人都是从 print 开始调试的:哪里不对,就在那里打印一个变量。程序小的时候,这招确实够用。可一旦脚本变长、开始跑在后台、或者出了问题需要事后复盘,print 的短板就全暴露出来了:它没有时间,不知道这条信息是什么级别,输出混在终端里,程序一关就没了。更麻烦的是,调试用的 print 很容易被忘在代码里,上线后还在不停地往终端里吐东西。
Python 自带的 logging 模块就是为了解决这些问题。它不是更复杂的 print,而是一套“记录事情”的办法:每条日志自带时间、级别和来源,输出到哪里、记多细,都可以单独控制。
五个级别,先分清轻重
logging 有五个级别,从轻到重依次是 DEBUG、INFO、WARNING、ERROR、CRITICAL。写代码时先养成按级别说话的习惯:调试过程中的临时信息用 DEBUG,程序正常推进的关键节点用 INFO,出现了异常但还能继续的情况用 WARNING,某个功能失败了用 ERROR,整个程序无法继续才用 CRITICAL。
级别的真正价值在于过滤。开发时把级别设成 DEBUG,什么都能看到;上线后改成 WARNING,调试信息自动消失,不用逐行删 print。一处设置,全局生效,这是 print 永远做不到的。
三行代码跑起来
最简单的用法只需要三行:import logging;logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s");logging.info("程序启动")。basicConfig 做两件事:定级别,定格式。这里的格式让每条日志带上时间和级别,读起来一目了然。之后在代码里,哪里想记录就写一句 logging.info 或者 logging.error,不需要再操心输出格式。一个实用的小习惯是:给每个模块一个自己的记录器。logger = logging.getLogger(__name__),这样日志里能看出信息来自哪个模块,出问题定位快得多。
记到文件里,事后还能查
终端输出关掉就没了,文件不会。把日志同时写进文件,只需要在配置里加一个文件处理器:handler = logging.FileHandler("app.log", encoding="utf-8"),并设置格式后 addHandler。这样运行记录会留在 app.log 里。程序半夜跑崩了,第二天打开文件,按时间往回翻,就能看到崩之前最后几步做了什么。这比“当时终端里好像闪过一个报错”可靠得多。文件日志还可以长期保留、按天轮换,避免单个文件无限变大,标准库的 RotatingFileHandler 就能做到。
三个新手常踩的坑
第一个坑是级别设错:默认级别是 WARNING,info 和 debug 默认不会显示,很多人以为代码没执行,其实只是被过滤了。先检查级别,再怀疑逻辑。第二个坑是在循环里记太多日志:每处理一条数据就记一行,一万条数据就是一万行日志,文件和速度都受不了。循环里的日志要克制,记总数、记异常,少记每一条。第三个坑是把敏感信息写进日志:密码、令牌、用户隐私数据绝对不要出现在日志里。日志文件会被传阅、备份、长期保存,写进去就等于公开了。
从 print 到 logging,只改一个习惯
不需要一次学会全部配置。先从两件事开始:把调试用的 print 换成按级别的 logging 调用,给程序配一个带时间格式的输出。跑通之后,再加文件输出、再按模块分记录器。习惯一旦养成,排查问题的方式就变了:不再靠重新跑一遍去复现,而是打开日志,按时间线把事情经过读出来。这正是 logging 比 print 高明的地方——它记录的不只是结果,还有过程。
- 点赞
- 收藏
- 关注作者
评论(0)