Python Logging 模块完全解读

640?wx_fmt=jpeg


蓝三金,人生苦短,我用 Python。

博客:https://blog.csdn.net/qq_20084101

本文作者已加入Python中文社区专栏作者计划

Python 中的 logging 模块可以让你跟踪代码运行时的事件,当程序崩溃时可以查看日志并且发现是什么引发了错误。Log 信息有内置的层级——调试(debugging)、信息(informational)、警告(warnings)、错误(error)和严重错误(critical)。你也可以在 logging 中包含 traceback 信息。不管是小项目还是大项目,都推荐在 Python 程序中使用 logging。本文将简单清晰地介绍如何使用 logging 模块。

为什么使用 logging?

当你运行一个 Python 脚本时,你可能想要知道脚本的哪个部分在执行,并且检视变量的当前值。

通常,可以只使用 print() 打印出你想要的信息。在小程序中,可能靠这个就足够了。

但问题是,当你处理有很多个模块的大项目时,就需要一个更加灵活的方法。

为什么?

因为代码需要经历开发、调试、审查、测试或者上线等不同阶段。在开发时你想要打印的信息类型可能和上线后你想看到的信息类型完全不同。

也就是说,在“测试”时,你可能只想看警告和错误信息,然而在“调试”时,你可能还想看到跟调试相关的信息。

如果你还想打印出使用的模块以及代码运行的时间,那么你的代码很容易变得混乱。

使用 logging 模块,这些问题就能很容易地解决。

logging 模块可以:

  1. 控制信息层级,仅记录需要的信息。

  2. 控制显示或者保存日志的时机。

  3. 使用内置信息模板控制日志格式。

  4. 知晓信息来自于哪个模块。

基本 logging 例子

logging 模块是 Python 的标准库,要使用 logging,只需要使用 logging.basicConfig() 进行基本设置。事实上,这也是可选的。

然后就可以调用 logging.{level}(message) 在控制台中显示信息。

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

def hypotenuse(a, b):
    """计算三角形斜边"""
    return (a**2 + b**2)**0.5

logging.info("{a}, {b} 的斜边是 {c}".format(a=3, b=4, c=hypotenuse(a=3, b=4)))
#> INFO:root:3, 4 的斜边是 5.0

打印出的日志信息遵循默认格式: {LEVEL}:{LOGGER}:{MESSAGE}

上面的例子中, LEVEL 就是 INFO,因为调用的是 logging.info()

LOGGER 为 root,因为这是默认 logger。

logger(日志记录器)类似于一个实体,你可以创建并配置它来记录不同类型和格式的消息。

你可以配置一个输出到控制台的 logger 和另一个将日志发送到文件的 logger,它们具有不同的日志记录级别,并且特定于给定模块。

最后,输出的信息就是我传递给 logging.info() 的字符串。

那么如果不设置 logging.basicConfig(level=logging.INFO) 会怎么样?

答案是 日志信息不会被打印出来

为什么?要知道这个需要先了解 logging 的级别。

logging 的 5 个级别

logging 有 5 个不同层次的日志级别,可以将给定的 logger 配置为这些级别:

  1. DEBUG:详细信息,用于诊断问题。Value=10。

  2. INFO:确认代码运行正常。Value=20。

  3. WARNING:意想不到的事情发生了,或预示着某个问题。但软件仍按预期运行。Value=30。

  4. ERROR:出现更严重的问题,软件无法执行某些功能。Value=40。

  5. CRITICAL:严重错误,程序本身可能无法继续运行。Value=50。

现在,让我们回答之前提出的问题。默认 logger 是 root,其默认的 basicConfig 级别是 WARNING。也就是说,只有来自 logging.warning或者更高级别的信息才会被记录下来。

因此,logging.info() 中的信息不会被打印出来。这也是为什么 basicConfig 被设为 INFO

如果级别使用 logging.ERROR 代替,只有来自 logging.error 和 logging.critical 的信息会被记录。

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

def hypotenuse(a, b):
    """计算三角形斜边"""
    return (a**2 + b**2)**0.5

kwargs = {'a':3'b':4'c':hypotenuse(34)}

logging.debug("a = {a}, b = {b}".format(**kwargs))
logging.info("{a}, {b} 的斜边是 {c}".format(**kwargs))
logging.warning("a={a} 和 b={b} 相等".format(**kwargs))
logging.error("a={a} 和 b={b} 不能为负".format(**kwargs))
logging.critical("{a}, {b} 的斜边是 {c}".format(**kwargs))

#> ERROR:root:a=3 和 b=4 不能为负
#> CRITICAL:root:3, 4 的斜边是 5.0

将日志记入文件

要从 root logger 将日志消息发送到文件,需要在 logging.basicConfig() 中设置 file 参数:

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

现在,所有后续日志消息都将直接记录到当前工作目录中的“sample.log“文件。如果要将其记录到另一个目录中的文件,请给出完整的文件路径。

如何更改 logging 格式

logging 模块提供了向日志消息添加各种详细信息的速记表。

640?wx_fmt=png

fig

让我们更改日志信息格式以显示 TIMELEVEL 和 MESSAGE

import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s :: %(levelname)s :: %(message)s')

logging.info("当当当!")
#> 2019-03-10 19:41:09,057 :: INFO :: 当当当!

不要对所有模块使用 root logger

让我们看下面的代码:

# 1. myprojectmodule.py
import logging
logging.basicConfig(filename='module.log')

#-----------------------------

# 2. main.py (从 myprojectmodule.py 导入代码)
import logging
import myprojectmodule  # 运行 myprojectmodule.py 中的代码,将生成 `module.log` 文件

logging.basicConfig(filename='main.log')  # 无效!

如果项目中有一个或多个模块。这些模块使用基本根模块。然后,当导入模块 myprojectmodule.py 时,将运行该模块的所有代码并配置 logger。

一旦配置好,main 文件中的 root logger 将不能再更改 root logger 设置。因为,一旦设置好 logging.basicConfig(),就不能再更改它。

如果想在不同文件中使用不同 logger,就需要创建一个新的 logger。

如何创建一个新的 logger?

可以使用 logger.getLogger(name) 方法创建一个新的 logger。如果存在同名的 logger,则将使用该 logger。

可以给 logger 取任何名字,但是通常使用 __name__ 变量:

zhi

chi

zuo

zhe


640?wx_fmt=jpeg


长按扫码鼓励作者

点 击 投 稿


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

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

640?wx_fmt=jpeg

▼ 点击成为社区注册会员          「在看」一下,一起PY!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值