30天拿下Python之logging模块

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 30天拿下Python之logging模块

概述

在上一节,我们介绍了Python的collections模块,包括:collections模块中一些常用的函数和类。在这一节,我们将介绍Python的logging模块。logging模块是一个用于记录和调试的标准库,它提供了一种灵活的方式来记录不同级别的消息,比如:调试信息、错误信息、警告信息等。这个模块非常有用,因为它可以帮助开发者理解应用程序在运行时到底发生了什么。当程序出现错误或异常时,通过合理的日志记录,我们可以迅速定位问题,了解问题的来龙去脉。

logging的基本使用

在Python中,logging模块的使用比较简单。导入logging模块后,通过调用basicConfig方法可以进行基本的配置。比如:可以设置日志级别、日志输出位置、日志格式等。

import logging
logging.basicConfig(level = logging.INFO,
                    format = '%(asctime)s - %(levelname)s - %(message)s',
                    filename = 'app.log',
                    filemode = 'w')

进行上述的基本配置后,我们就可以创建logger对象,并调用其各种方法来记录日志信息了。

logger = logging.getLogger('my_logger')
logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')

执行上述的示例代码后,会在当前目录下生成app.log文件,其内容如下。

2023-09-24 19:44:43,086 - INFO - Info message
2023-09-24 19:44:43,086 - WARNING - Warning message
2023-09-24 19:44:43,086 - ERROR - Error message
2023-09-24 19:44:43,086 - CRITICAL - Critical message

可以看到,logger.debug函数写入的调试信息没有出现在文件中。这是因为,我们指定了日志级别为logging.INFO,比该日志级别低的信息会被过滤掉,不会写入日志文件中。

logging的选项设置

logging模块提供了很多选项来配置日志记录的行为,以下是一些常见的选项。

日志记录器名称:每个记录器都有一个名称,可以通过名称来获取和配置特定的记录器。

日志级别:一共有五个级别的日志记录,从低到高依次为:DEBUG、INFO、WARNING、ERROR、

CRITICAL。我们可以设置日志记录器的级别,这样低于该级别的所有消息都不会被记录。比如:如果级别设置为WARNING,那么DEBUG和INFO级别的消息将不会被记录。

日志格式:可以通过设置日志记录器的格式字符串来改变日志消息的显示方式。比如:可以包含时间戳、日志级别、消息、线程名等。

日志输出地:日志消息可以输出到多种地方,比如:控制台、文件等。可以使用多种Handler来实现,比如:输出到控制台使用StreamHandler、输出到文件使用FileHandler等。

日志旋转:如果日志文件可能会变得很大,我们需要在满足某个条件(比如:日志文件达到一定大小)时创建一个新的日志文件,这可以通过使用RotatingFileHandler或TimedRotatingFileHandler等处理程序来实现。

日志过滤:可以通过使用过滤器来进一步定制哪些消息应该被记录。比如:我们可以设置一个过滤器,只有包含特定关键字的消息才会被记录。

在下面的示例代码中,我们创建了一个名为'my_logger'的日志记录器,并设置了其级别为DEBUG。然后,我们创建了一个写入日志文件的处理器和一个输出到控制台的处理器,并设置了他们的级别。我们还定义了日志消息的格式,并将其应用到了两个处理器上。最后,我们用这个记录器记录了一条警告信息。

import logging
# 创建一个logger
logger = logging.getLogger('my_logger')
# 设置日志级别
logger.setLevel(logging.DEBUG)
 
# 创建一个Handler,用于写入日志文件
fileHandler = logging.FileHandler('app.log')
# 设置日志级别
fileHandler.setLevel(logging.DEBUG)
# 创建一个Handler,用于输出到控制台
consoleHandler = logging.StreamHandler()
# 设置日志级别
consoleHandler.setLevel(logging.INFO)
# 定义Handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fileHandler.setFormatter(formatter)
consoleHandler.setFormatter(formatter)
# 给logger添加Handler
logger.addHandler(fileHandler)
logger.addHandler(consoleHandler)
# 记录一条日志
# 输出:2023-09-24 20:06:26,828 - my_logger - WARNING - a warning info
logger.warn('a warning info')
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
日志旋转
在logging模块中,可以使用RotatingFileHandler和TimedRotatingFileHandler来实现日志旋转。
RotatingFileHandler根据日志文件的大小来旋转日志文件。可以通过设置maxBytes参数来指定每个日志文件的大小,同时通过backupCount参数来指定保留的备份文件数量。当日志文件达到设定的最大大小时,原日志文件将被重命名并备份,同时开始写入新的日志文件。
TimedRotatingFileHandler则根据时间间隔来旋转日志文件。可以通过设置interval参数来指定时间间隔,同时通过backupCount参数来指定保留的备份文件数量。当达到设定的时间间隔时,原日志文件将被重命名并备份,同时开始写入新的日志文件。
import logging
import logging.handlers
 
# 创建一个Logger对象
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# 创建一个RotatingFileHandler对象
maxSize = 1 << 20
handler = logging.handlers.RotatingFileHandler('app.log', maxBytes = maxSize, backupCount = 5)
 
# 设置日志级别和格式
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
# 记录日志消息
logger.info('Info message')

在上面的示例代码中,我们创建了一个RotatingFileHandler对象,并指定了日志文件的最大大小为1MB字节,同时保留5个备份文件。当日志文件达到设定的最大大小时,原日志文件将被重命名并备份,同时开始写入新的日志文件。

logging.Filter类

logging.Filter类用于过滤日志消息。它有一个名为filter的函数,用于确定是否应该记录或传递日志消息。我们可以创建一个Filter类的派生类,并覆盖其filter函数。该函数接受一个日志记录对象作为参数,并返回一个布尔值,用于表示是否应该记录或传递该日志消息。如果该函数返回True,则日志消息将被记录或传递,否则将被忽略。

import logging  
 
LOG_FORMAT = '%(levelname)s %(asctime)s - %(message)s'
logging.basicConfig(filename = "app.log", level = logging.DEBUG, format = LOG_FORMAT)
my_logger = logging.getLogger('my_logger')
my_logger.setLevel(logging.DEBUG)
# 创建一个名为my_handler的处理器,并将其添加到my_logger中
my_handler = logging.StreamHandler()
my_handler.setLevel(logging.DEBUG)
my_handler.setFormatter(logging.Formatter(LOG_FORMAT))
my_logger.addHandler(my_handler)
 
# 创建一个名为filter的过滤器,并将其添加到my_handler中
class CustomFilter(logging.Filter):
    def filter(self, record):
        return 'Hope' in record.msg
filter = CustomFilter()
my_handler.addFilter(filter)
 
# 记录一些消息
my_logger.debug('Hello Hope')
my_logger.info('Hello World')
my_logger.warning('Hope web site')
my_logger.error('GitHub web site')

在上面的示例代码中,我们首先使用basicConfig方法定义了一个基本的日志配置。然后,创建了一个名为my_logger的记录器,并将其级别设置为DEBUG。接下来,我们创建了一个名为my_handler的处理器,并将其添加到my_logger中。我们还创建了一个名为filter的过滤器,并将其添加到my_handler中,以过滤掉日志信息中不包含"Hope"字符串的日志。最后,我们使用my_logger记录了几条不同级别的日志消息。执行上面的代码后,只有“Hello Hope”和“Hope web site”这两条日志信息会被保存和输出。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
4月前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
166 62
|
5天前
|
人工智能 自然语言处理 Shell
[oeasy]python070_如何导入模块_导入模块的作用_hello_dunder_双下划线
本文介绍了如何在Python中导入模块及其作用,重点讲解了`__hello__`模块的导入与使用。通过`import`命令可以将外部模块引入当前环境,增强代码功能。例如,导入`__hello__`模块后可输出“Hello world!”。此外,还演示了如何使用`help()`和`dir()`函数查询模块信息,并展示了导入多个模块的方法。最后,通过一个实例,介绍了如何利用`jieba`、`WordCloud`和`matplotlib`模块生成词云图。总结来说,模块是封装好的功能部件,能够简化编程任务并提高效率。未来将探讨如何创建自定义模块。
28 8
|
3天前
|
缓存 Shell 开发工具
[oeasy]python071_我可以自己做一个模块吗_自定义模块_引入模块_import_diy
本文介绍了 Python 中模块的导入与自定义模块的创建。首先,我们回忆了模块的概念,即封装好功能的部件,并通过导入 `__hello__` 模块实现了输出 &quot;hello world!&quot; 的功能。接着,尝试创建并编辑自己的模块 `my_file.py`,引入 `time` 模块以获取当前时间,并在其中添加自定义输出。
18 4
|
3月前
|
Python
Python Internet 模块
Python Internet 模块。
139 74
|
4月前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
150 63
|
4月前
|
数据可视化 Python
如何在Python中解决模块和包的依赖冲突?
解决模块和包的依赖冲突需要综合运用多种方法,并且需要团队成员的共同努力和协作。通过合理的管理和解决冲突,可以提高项目的稳定性和可扩展性
|
4月前
|
Python
Python的模块和包
总之,模块和包是 Python 编程中非常重要的概念,掌握它们可以帮助我们更好地组织和管理代码,提高开发效率和代码质量
140 61
|
4月前
|
测试技术 Python
手动解决Python模块和包依赖冲突的具体步骤是什么?
需要注意的是,手动解决依赖冲突可能需要一定的时间和经验,并且需要谨慎操作,避免引入新的问题。在实际操作中,还可以结合使用其他方法,如虚拟环境等,来更好地管理和解决依赖冲突😉。
|
4月前
|
持续交付 Python
如何在Python中自动解决模块和包的依赖冲突?
完全自动解决所有依赖冲突可能并不总是可行,特别是在复杂的项目中。有时候仍然需要人工干预和判断。自动解决的方法主要是提供辅助和便捷,但不能完全替代人工的分析和决策😉。
|
2月前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
36 3

热门文章

最新文章