前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解 Python 中的日志 logging 模块

深入理解 Python 中的日志 logging 模块

原创
作者头像
千万别过来
修改2023-11-17 11:09:46
3490
修改2023-11-17 11:09:46
举报
文章被收录于专栏:推荐算法学习推荐算法学习

1. 介绍

日志记录是软件开发中的一个重要环节,它可以帮助我们监控程序运行过程中的状态、诊断问题以及分析性能。Python 中通常使用 logging 模块,让我们能够方便地记录日志信息。

2. 案例与日志级别

在举例子之前先介绍以下日志级别,日志级别的高低可以通过数值表示,数值越高,日志级别越高。打开logging的源码可以发现,这些日志等级实际上是整数常量,因此比如logging.ERROR40在代码里面也就是等价的:

由上可知:

DEBUG < INFO < WARNING < ERROR < CRITICAL

日志级别

数值

描述

DEBUG

10

详细的诊断信息,用于开发和调试阶段

INFO

20

一般性的信息,例如程序启动、关闭或完成某个操作

WARNING

30

潜在的问题或异常情况,但并不会导致程序中断

ERROR

40

导致程序中断或无法完成某个操作的错误

CRITICAL

50

非常严重的错误,可能导致整个系统崩溃或数据丢失

接着一个简单的例子:

代码语言:javascript
复制
import logging

# 配置 logging 模块
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 记录日志信息
logging.debug("This is a debug message.")
logging.info("This is an info message.")
logging.warning("This is a warning message.")
logging.error("This is an error message.")
logging.critical("This is a critical message.")

在这个例子中,先使用 basicConfig() 进行初始化基本配置。我们设置了日志级别为 INFO,这意味着所有级别大于或等于 INFO的日志信息都会被输出(DEBUG不会输出)。

运行这个示例,将在控制台看到如下输出:

代码语言:javascript
复制
2023-11-16 13:16:32,871 - INFO - This is an info message.
2023-11-16 13:16:32,873 - WARNING - This is a warning message.
2023-11-16 13:16:32,873 - ERROR - This is an error message.
2023-11-16 13:16:32,874 - CRITICAL - This is a critical message.

这里有一点需要注意,如果是在jupyter上测试。第一次运行完之后修改basicConfig()里面的日志等级并不会改变。因为logging.basicConfig() 只会在第一次调用时设置日志记录器的配置。后续对 basicConfig() 的调用将被忽略。这时候如果想要修改日志等级,则需要使用:

代码语言:javascript
复制
logging.getLogger().setLevel(logging.ERROR)

3. 配置和自定义日志记录

在了解如何使用自定义 logging 之前,需要了解一些基本概念:

  • Logger:Logger 是 logging 模块的核心对象,用于记录日志信息。通常,我们会为每个模块或组件创建一个 Logger 对象。Logger 对象之间可以形成层次结构,以便更好地管理日志记录。
  • Handler:Handler 对象负责将日志信息输出到不同的目的地,例如控制台、文件或网络。一个 Logger 可以有多个 Handler,以实现不同级别的日志输出。
  • Formatter:Formatter 对象用于定义日志信息的格式。我们可以自定义 Formatter,以便按照需要展示日志信息。
  • Filter:Filter 对象用于对日志信息进行过滤,以便有选择地输出日志。

下面是一个例子:

代码语言:javascript
复制
import logging

# 创建一个名为 'my_logger' 的 Logger 对象
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)

# 创建一个 Handler,输出日志到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 创建一个 Handler,输出日志到文件
file_handler = logging.FileHandler('my_log.log')
file_handler.setLevel(logging.DEBUG)

# 创建一个 Formatter,定义日志信息的格式
console_formatter = logging.Formatter('我在控制台里面!%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_formatter = logging.Formatter('我在文件里面!%(asctime)s - %(name)s - %(levelname)s - %(message)s')


# 为 Handler 设置 Formatter
console_handler.setFormatter(console_formatter)
file_handler.setFormatter(file_formatter)

# 为 Logger 添加 Handler
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 记录日志信息
logger.debug("This is a debug message.")
logger.info("This is an info message.")
logger.warning("This is a warning message.")
logger.error("This is an error message.")
logger.critical("This is a critical message.")

logging.StreamHandler()是输出日志到控制台,logging.FileHandler('my_log.log')是输出日志到文件可以分别使用不同的formatter,最终展示效果如下。

4. 高级用法

logging 模块还提供了一些高级功能,例如日志过滤、日志旋转等。

4.1 日志过滤

我们可以使用 Filter 对象对日志信息进行过滤,有选择地输出日志:

代码语言:javascript
复制
class CustomFilter(logging.Filter):
    def filter(self, record):
        # 只输出包含 'important' 关键字的日志信息
        return 'important' in record.msg

# 为 Logger 添加自定义 Filter
logger.addFilter(CustomFilter())

# 记录日志信息
logger.info("This is an important info message.")
logger.info("This is a regular info message.")

这里重写了 filter() 方法,使其只允许包含 'important' 关键字的日志信息通过。

4.2 日志旋转

在长时间运行的程序中,日志文件可能会变得非常大。为了避免这个问题,可以使用日志旋转功能,这个在平时开发中很常见。logging 模块提供了一个 RotatingFileHandler 类,用于实现日志文件的自动旋转。以下是一个示例:

代码语言:javascript
复制
from logging.handlers import RotatingFileHandler

# 创建一个 RotatingFileHandler,最多保留 5 个日志文件,每个文件最大 1MB
rotating_handler = RotatingFileHandler('rotating_log.log', maxBytes=1024 * 1024, backupCount=5)
rotating_handler.setLevel(logging.DEBUG)
rotating_handler.setFormatter(formatter)

# 为 Logger 添加 RotatingFileHandler
logger.addHandler(rotating_handler)

# 记录日志信息
for i in range(10000):
    logger.debug(f"This is a debug message {i}.")

多次运行以上代码后,可以发现目录下生成多个文件,且rotating_log.log是最新文件。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 介绍
  • 2. 案例与日志级别
  • 3. 配置和自定义日志记录
  • 4. 高级用法
    • 4.1 日志过滤
      • 4.2 日志旋转
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档