Python Logging 模块完全解读

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Python Logging 模块完全解读

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()


LOGGERroot,因为这是默认 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.errorlogging.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(3, 4)}
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 模块提供了向日志消息添加各种详细信息的速记表。


微信图片_20220429121541.jpg


fig


让我们更改日志信息格式以显示 TIMELEVELMESSAGE


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__ 变量。

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
14天前
|
安全 大数据 程序员
Python operator模块的methodcaller:一行代码搞定对象方法调用的黑科技
`operator.methodcaller`是Python中处理对象方法调用的高效工具,替代冗长Lambda,提升代码可读性与性能。适用于数据过滤、排序、转换等场景,支持参数传递与链式调用,是函数式编程的隐藏利器。
53 4
|
8天前
|
存储 数据库 开发者
Python SQLite模块:轻量级数据库的实战指南
本文深入讲解Python内置sqlite3模块的实战应用,涵盖数据库连接、CRUD操作、事务管理、性能优化及高级特性,结合完整案例,助你快速掌握SQLite在小型项目中的高效使用,是Python开发者必备的轻量级数据库指南。
88 0
|
2月前
|
存储 安全 数据处理
Python 内置模块 collections 详解
`collections` 是 Python 内置模块,提供多种高效数据类型,如 `namedtuple`、`deque`、`Counter` 等,帮助开发者优化数据处理流程,提升代码可读性与性能,适用于复杂数据结构管理与高效操作场景。
103 0
|
11月前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
320 62
|
3月前
|
数据安全/隐私保护 Python
抖音私信脚本app,协议私信群发工具,抖音python私信模块
这个实现包含三个主要模块:抖音私信核心功能类、辅助工具类和主程序入口。核心功能包括登录
|
6月前
|
Python
Python教程:os 与 sys 模块详细用法
os 模块用于与操作系统交互,主要涉及夹操作、路径操作和其他操作。例如,`os.rename()` 重命名文件,`os.mkdir()` 创建文件夹,`os.path.abspath()` 获取文件绝对路径等。sys 模块则用于与 Python 解释器交互,常用功能如 `sys.path` 查看模块搜索路径,`sys.platform` 检测操作系统等。这些模块提供了丰富的工具,便于开发中处理系统和文件相关任务。
237 14
|
10月前
|
Python
Python Internet 模块
Python Internet 模块。
210 74
|
7月前
|
人工智能 自然语言处理 Shell
[oeasy]python070_如何导入模块_导入模块的作用_hello_dunder_双下划线
本文介绍了如何在Python中导入模块及其作用,重点讲解了`__hello__`模块的导入与使用。通过`import`命令可以将外部模块引入当前环境,增强代码功能。例如,导入`__hello__`模块后可输出“Hello world!”。此外,还演示了如何使用`help()`和`dir()`函数查询模块信息,并展示了导入多个模块的方法。最后,通过一个实例,介绍了如何利用`jieba`、`WordCloud`和`matplotlib`模块生成词云图。总结来说,模块是封装好的功能部件,能够简化编程任务并提高效率。未来将探讨如何创建自定义模块。
86 8
|
7月前
|
缓存 Shell 开发工具
[oeasy]python071_我可以自己做一个模块吗_自定义模块_引入模块_import_diy
本文介绍了 Python 中模块的导入与自定义模块的创建。首先,我们回忆了模块的概念,即封装好功能的部件,并通过导入 `__hello__` 模块实现了输出 "hello world!" 的功能。接着,尝试创建并编辑自己的模块 `my_file.py`,引入 `time` 模块以获取当前时间,并在其中添加自定义输出。
103 5
|
11月前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
269 63

推荐镜像

更多