Python Logging 模块完全解读

论坛 期权论坛 期权     
Python中文社区   2019-6-16 04:39   6454   0


蓝三金,人生苦短,我用 Python。
博客:https://blog.csdn.net/qq_20084101
本文作者已加入Python中文社区专栏作者计划
Python 中的 logging 模块可以让你跟踪代码运行时的事件,当程序崩溃时可以查看日志并且发现是什么引发了错误。Log 信息有内置的层级——调试(debugging)、信息(informational)、警告(warnings)、错误(error)和严重错误(critical)。你也可以在 logging 中包含 traceback 信息。不管是小项目还是大项目,都推荐在 Python 程序中使用 logging。本文将简单清晰地介绍如何使用 logging 模块。
[h1]为什么使用 logging?[/h1]当你运行一个 Python 脚本时,你可能想要知道脚本的哪个部分在执行,并且检视变量的当前值。
通常,可以只使用
  1. print()
复制代码
打印出你想要的信息。在小程序中,可能靠这个就足够了。
但问题是,当你处理有很多个模块的大项目时,就需要一个更加灵活的方法。
为什么?
因为代码需要经历开发、调试、审查、测试或者上线等不同阶段。在开发时你想要打印的信息类型可能和上线后你想看到的信息类型完全不同。
也就是说,在“测试”时,你可能只想看警告和错误信息,然而在“调试”时,你可能还想看到跟调试相关的信息。
如果你还想打印出使用的模块以及代码运行的时间,那么你的代码很容易变得混乱。
使用
  1. logging
复制代码
模块,这些问题就能很容易地解决。
  1. logging
复制代码
模块可以:
  • 控制信息层级,仅记录需要的信息。
  • 控制显示或者保存日志的时机。
  • 使用内置信息模板控制日志格式。
  • 知晓信息来自于哪个模块。
[h1]基本 logging 例子[/h1]
  1. logging
复制代码
模块是 Python 的标准库,要使用 logging,只需要使用
  1. logging.basicConfig()
复制代码
进行基本设置。事实上,这也是可选的。
然后就可以调用
  1. logging.{level}(message)
复制代码
在控制台中显示信息。
  1. import logging
  2. logging.basicConfig(level=logging.INFO)
  3. def hypotenuse(a, b):
  4.     """计算三角形斜边"""
  5.     return (a**2 + b**2)**0.5
  6. logging.info("{a}, {b} 的斜边是 {c}".format(a=3, b=4, c=hypotenuse(a=3, b=4)))
  7. #> INFO:root:3, 4 的斜边是 5.0
复制代码
打印出的日志信息遵循默认格式:
  1. {LEVEL}:{LOGGER}:{MESSAGE}
复制代码

上面的例子中,
  1. LEVEL
复制代码
就是
  1. INFO
复制代码
,因为调用的是
  1. logging.info()
复制代码
  1. LOGGER
复制代码
  1. root
复制代码
,因为这是默认 logger。
logger(日志记录器)类似于一个实体,你可以创建并配置它来记录不同类型和格式的消息。
你可以配置一个输出到控制台的 logger 和另一个将日志发送到文件的 logger,它们具有不同的日志记录级别,并且特定于给定模块。
最后,输出的信息就是我传递给
  1. logging.info()
复制代码
的字符串。
那么如果不设置
  1. logging.basicConfig(level=logging.INFO)
复制代码
会怎么样?
答案是 日志信息不会被打印出来。
为什么?要知道这个需要先了解 logging 的级别。
[h1]logging 的 5 个级别[/h1]
  1. logging
复制代码
有 5 个不同层次的日志级别,可以将给定的 logger 配置为这些级别:
  • DEBUG:详细信息,用于诊断问题。Value=10。
  • INFO:确认代码运行正常。Value=20。
  • WARNING:意想不到的事情发生了,或预示着某个问题。但软件仍按预期运行。Value=30。
  • ERROR:出现更严重的问题,软件无法执行某些功能。Value=40。
  • CRITICAL:严重错误,程序本身可能无法继续运行。Value=50。
现在,让我们回答之前提出的问题。默认 logger 是
  1. root
复制代码
,其默认的 basicConfig 级别是
  1. WARNING
复制代码
。也就是说,只有来自
  1. logging.warning
复制代码
或者更高级别的信息才会被记录下来。
因此,
  1. logging.info()
复制代码
中的信息不会被打印出来。这也是为什么 basicConfig 被设为
  1. INFO
复制代码

如果级别使用
  1. logging.ERROR
复制代码
代替,只有来自
  1. logging.error
复制代码
  1. logging.critical
复制代码
的信息会被记录。
  1. import logging
  2. logging.basicConfig(level=logging.ERROR)
  3. def hypotenuse(a, b):
  4.     """计算三角形斜边"""
  5.     return (a**2 + b**2)**0.5
  6. kwargs = {'a':3, 'b':4, 'c':hypotenuse(3, 4)}
  7. logging.debug("a = {a}, b = {b}".format(**kwargs))
  8. logging.info("{a}, {b} 的斜边是 {c}".format(**kwargs))
  9. logging.warning("a={a} 和 b={b} 相等".format(**kwargs))
  10. logging.error("a={a} 和 b={b} 不能为负".format(**kwargs))
  11. logging.critical("{a}, {b} 的斜边是 {c}".format(**kwargs))
  12. #> ERROR:root:a=3 和 b=4 不能为负
  13. #> CRITICAL:root:3, 4 的斜边是 5.0
复制代码
[h1]将日志记入文件[/h1]要从 root logger 将日志消息发送到文件,需要在
  1. logging.basicConfig()
复制代码
中设置 file 参数:
  1. import logging
  2. logging.basicConfig(level=logging.INFO, filename='sample.log')
复制代码
现在,所有后续日志消息都将直接记录到当前工作目录中的“sample.log“文件。如果要将其记录到另一个目录中的文件,请给出完整的文件路径。
[h1]如何更改 logging 格式[/h1]logging 模块提供了向日志消息添加各种详细信息的速记表。


fig让我们更改日志信息格式以显示
  1. TIME
复制代码
  1. LEVEL
复制代码
  1. MESSAGE
复制代码
  1. import logging
  2. logging.basicConfig(level=logging.INFO, format='%(asctime)s :: %(levelname)s :: %(message)s')
  3. logging.info("当当当!")
  4. #> 2019-03-10 19:41:09,057 :: INFO :: 当当当!
复制代码
[h1]不要对所有模块使用 root logger[/h1]让我们看下面的代码:
  1. # 1. myprojectmodule.py
  2. import logging
  3. logging.basicConfig(filename='module.log')
  4. #-----------------------------
  5. # 2. main.py (从 myprojectmodule.py 导入代码)
  6. import logging
  7. import myprojectmodule  # 运行 myprojectmodule.py 中的代码,将生成 `module.log` 文件
  8. logging.basicConfig(filename='main.log')  # 无效!
复制代码
如果项目中有一个或多个模块。这些模块使用基本根模块。然后,当导入模块
  1. myprojectmodule.py
复制代码
时,将运行该模块的所有代码并配置 logger。
一旦配置好,
  1. main
复制代码
文件中的 root logger 将不能再更改 root logger 设置。因为,一旦设置好
  1. logging.basicConfig()
复制代码
,就不能再更改它。
如果想在不同文件中使用不同 logger,就需要创建一个新的 logger。
[h1]如何创建一个新的 logger?[/h1]可以使用
  1. logger.getLogger(name)
复制代码
方法创建一个新的 logger。如果存在同名的 logger,则将使用该 logger。
可以给 logger 取任何名字,但是通常使用
  1. __name__
复制代码
变量:
zhi

chi

zuo

zhe







长按扫码鼓励作者
点 击 投 稿

热 门 推 荐
为你的Python程序加密
爬取豆瓣电影榜单构建知识图谱

用Python分析《都挺好》中的人物关系
用Pandas库实现MySQL数据库的读写
推荐Python中文社区旗下的几个服务类公众号

▼ 点击成为社区注册会员          「在看」一下,一起PY!
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:200
帖子:40
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP