Python日志系统详解:Logging模块最佳实践

Python日志系统详解:Logging模块最佳实践

在开发Python应用程序时,日志记录是排查问题、监控系统状态、优化性能的重要手段。Python标准库中提供了强大的logging模块,使开发者可以轻松实现灵活的日志系统。本文将详细介绍Python的logging模块,并分享一些在实际项目中提高日志质量和管理效率的最佳实践。
在这里插入图片描述

1. logging模块的基本概念

logging模块中,主要涉及以下几个核心概念:

  1. Logger:日志记录的入口,用于创建日志消息的对象。可以通过logger对象设置日志的级别和过滤条件。
  2. Handler:用于定义日志的输出位置,可以将日志输出到控制台、文件、远程服务器等。常用的HandlerStreamHandler(输出到控制台)和FileHandler(输出到文件)。
  3. Formatter:格式化日志内容,使日志输出更加易读。格式包括时间、日志级别、日志消息等信息。
  4. Log Level:日志级别,用于过滤日志消息,常见的级别有DEBUGINFOWARNINGERRORCRITICAL

这些组件的组合可以形成一个灵活的日志系统,使得我们可以针对不同需求生成和输出日志。
在这里插入图片描述

2. logging的基本用法

以下是一个使用logging模块的简单示例:

import logging

# 配置基本的日志设置
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 创建日志记录器
logger = logging.getLogger(__name__)

# 记录不同级别的日志
logger.debug('这是一个DEBUG日志')
logger.info('这是一个INFO日志')
logger.warning('这是一个WARNING日志')
logger.error('这是一个ERROR日志')
logger.critical('这是一个CRITICAL日志')

在这个例子中,basicConfig用于配置日志的基本信息,包括日志的级别和格式。运行后,logger对象会输出INFO及以上级别的日志到控制台。
在这里插入图片描述

3. 日志级别的选择

日志级别是日志系统的重要参数,根据应用场景合理选择日志级别,能够帮助过滤无关信息,提升日志的可读性:

  • DEBUG:用于开发和调试时记录详细的信息。
  • INFO:记录程序运行的正常信息,例如启动和停止等。
  • WARNING:记录潜在的问题,程序可能正常运行,但未来可能出错。
  • ERROR:记录发生的错误,但不影响程序继续运行。
  • CRITICAL:记录系统崩溃或重要模块出错等重大问题。

日志级别的最佳实践

建议在开发阶段将日志级别设置为DEBUG,在生产环境中设置为INFO或更高的级别,以避免日志过于冗长。
在这里插入图片描述

4. 配置Handler和Formatter

logging模块允许通过添加多个HandlerFormatter,使日志记录更灵活。以下示例将日志输出到控制台和文件中,并设置不同的日志格式:

import logging

# 创建日志记录器
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)

# 创建控制台处理器和文件处理器
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('app.log')

# 设置不同的日志级别
console_handler.setLevel(logging.INFO)
file_handler.setLevel(logging.ERROR)

# 定义格式
console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 应用格式到处理器
console_handler.setFormatter(console_formatter)
file_handler.setFormatter(file_formatter)

# 添加处理器到logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 记录日志
logger.info('这是INFO级别的日志,将输出到控制台')
logger.error('这是ERROR级别的日志,将输出到文件')

在这个示例中:

  • 控制台处理器console_handler将INFO及以上级别的日志输出到控制台;
  • 文件处理器file_handler将ERROR及以上级别的日志输出到app.log文件。

通过不同的HandlerFormatter组合,可以实现不同级别和格式的日志输出。
在这里插入图片描述

5. 使用配置文件管理日志配置

在大型项目中,直接在代码中配置logging参数会导致代码冗长、不便维护。可以通过外部配置文件(如YAMLJSON)管理日志配置,提高可维护性。

使用logging.config.fileConfig

以下是一个基于.ini配置文件的示例:

# logging_config.ini
[loggers]
keys=root

[handlers]
keys=consoleHandler, fileHandler

[formatters]
keys=simpleFormatter, detailedFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler, fileHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=ERROR
formatter=detailedFormatter
args=('app.log', 'a')

[formatter_simpleFormatter]
format=%(asctime)s - %(levelname)s - %(message)s

[formatter_detailedFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

然后在Python代码中读取这个配置文件:

import logging
import logging.config

# 读取日志配置文件
logging.config.fileConfig('logging_config.ini')

# 获取日志记录器
logger = logging.getLogger()

# 记录日志
logger.info('这是INFO日志')
logger.error('这是ERROR日志')

在这里插入图片描述

6. 进阶:为多模块项目配置日志

在大型项目中,通常会有多个模块,每个模块可能需要独立的日志记录器。可以使用__name__创建独立的logger实例,使每个模块都有自己的日志配置。例如:

# 在模块 module1.py 中
import logging

logger = logging.getLogger(__name__)

def foo():
    logger.info("Module1 - foo函数执行")
# 在模块 module2.py 中
import logging

logger = logging.getLogger(__name__)

def bar():
    logger.info("Module2 - bar函数执行")

在项目的主文件中配置日志:

import logging
import module1
import module2

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

module1.foo()
module2.bar()

这样每个模块的日志都会记录模块名称,使调试更加方便。
在这里插入图片描述

7. 日志异常信息

为了记录更多调试信息,遇到异常时记录详细的堆栈信息是非常有帮助的。可以使用exc_info参数:

try:
    1 / 0
except ZeroDivisionError:
    logger.exception("捕获到ZeroDivisionError异常")

logger.exception会自动捕获异常的堆栈信息并记录到日志中,使错误排查更加高效。
在这里插入图片描述

8. 结语

Python的logging模块为日志记录提供了灵活的支持。在实际开发中,合理地使用日志级别、配置HandlerFormatter,并引入配置文件进行集中管理,可以极大提高日志系统的可维护性和有效性。希望本文的讲解能帮助你更好地掌握logging模块,为项目构建高效的日志系统。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/903929.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

「Mac畅玩鸿蒙与硬件14」鸿蒙UI组件篇4 - Toggle 和 Checkbox 组件

在鸿蒙开发中,Toggle 和 Checkbox 是常用的交互组件,分别用于实现开关切换和多项选择。Toggle 提供多种类型以适应不同场景,而 Checkbox 支持自定义样式及事件回调。本篇将详细介绍这两个组件的基本用法,并通过实战展示它们的组合应用。 关键词 Toggle 组件Checkbox 组件开…

探索现代软件开发中的持续集成与持续交付(CI/CD)实践

探索现代软件开发中的持续集成与持续交付(CI/CD)实践 随着软件开发的飞速进步,现代开发团队已经从传统的开发模式向更加自动化和灵活的开发流程转变。持续集成(CI) 与 持续交付(CD) 成为当下主…

Linux上配置NFS服务

架设一台NFS服务器,并按照以下要求配置: 1、开放/nfs/shared目录,供所有用户查询资料: 2、开放/nfs/upload目录,为192.168.xxx.0/24网段主机可以上传目录,并将所有用户及所属的组映射为nfs-upload,其UID和…

docker占用磁盘过多问题

我在windows系统上用docker,安装在C盘环境下,我发现C盘占用了大量的空间,查找后发现是docker的映像文件占用的,于是开始清理,中间还踩个坑,记录一下,下次需要的时候方便找。 踩坑 我本想移动映…

如何批量注册多个Outlook邮箱账号并避免关联

批量注册多个Outlook邮箱账号时,如何避免账号之间的关联性是一个重要的考量因素。会在此文一起探讨如何高效且安全地批量注册多个Outlook邮箱账号,并提供一些实用的建议来确保这些账号不会被关联。 一、Outlook邮箱批量注册机制 在深入注册流程之前&…

LCR 024. 反转链表 最细图片逐行解析过程

LCR 024. 反转链表 给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例…

MySQL 数据库备份与恢复全攻略

MySQL 数据库备份与恢复全攻略 引言 在现代应用中,数据库是核心组件之一。无论是个人项目还是企业级应用,数据的安全性和完整性都至关重要。为了防止数据丢失、损坏或意外删除,定期备份数据库是必不可少的。本文将详细介绍 MySQL 数据库的备…

国标GB28181摄像机接入EasyGBS国标GB28181公网平台,IPC和NVR的具体技术要求有哪些?

随着科技的飞速发展,视频监控技术已经成为各行各业不可或缺的安全保障手段。在众多视频监控解决方案中,网络摄像机(IPC)和网络视频录像机(NVR)作为构建现代化视频监控系统的两大核心组件,发挥着…

qt QHBoxLayout详解

QHBoxLayout 是 Qt 框架中用于创建水平布局的类。它将子控件以横向的方式排列,并自动调整大小,以适应父窗口的尺寸变化。 重要方法 QHBoxLayout(QWidget *parent nullptr):创建一个 QHBoxLayout 对象,并指定其父窗口部件。addWi…

Linux更改符号链接

目录 1. 删除旧链接 2. 创建新的符号链接 例如我的电脑上有两个版本的cuda,11.8和12.4 1. 删除旧链接 rm cuda 2. 创建新的符号链接 ln -s /usr/local/cuda-11.8/ /usr/local/cuda

【Oracle实验】字段为空的,无法通过排除判断

Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.场景描述 需求:查询不是某个机构的数据。 同事SQL:where substr(bank_code,1,9) not in(014009001); 看SQL似乎没什么问题,分析…

总结围绕临床预测模型做的一些事情

📜总结近期围绕临床预测模型做的一些事情🍹 思考预测模型如何进入到临床实践? 预测模型在临床上的角色定位是“辅助临床决策”, 即预测模型提供的信息要与人的选择进行结合做出决策, 从已有的研究来看,预测…

C++ 整型大数运算(大整数运算)项目

C 整型大数运算项目 一、项目介绍二、项目变量成员三、项目实现构造函数加法减法乘法先计算再进位边计算边进位 除法与取模判断输入输出 四、项目源代码展示在 Big_integer.h 中:在 Big_integer.cpp 中: 五、测试准确性六、优化方向 一、项目介绍 整型大…

Cesium基础-(Entity)-(Box)

** 里边包含Vue、React框架代码详细步骤、以及代码详细解释 ** 3、Box 盒子 以下是 BoxGeometry 类的属性、方法和静态方法,以表格形式展示: 属性 属性名类型默认值描述minimumCartesian3盒子的最小 x, y, 和 z 坐标。maximumCartesian3盒子的最大 x, y, 和 z 坐标。vertex…

第三十三篇:TCP协议如何避免/减少网络拥塞,TCP系列八

一、流量控制 一般来说,我们总是希望数据传输得更快一些,但是如果发送方把数据发送得太快,接收方可能来不及接收,造成数据的丢失,数据重发,造成网络资源的浪费甚至网络拥塞。所谓的流量控制(fl…

Flutter Image和Text图文组件实战案例

In this section, we’ll go through the process of building a user interface that showcases a product using the Text and Image widgets. We’ll follow Flutter’s best practices to ensure a clean and effective UI structure. 在本节中,我们将使用“Te…

---synchronized 关键字---

在多线程编程中,由于代码的并发执行,导致了不同的线程在修改相同的变量会导致变量的值错误 比如 变量 c 2,这里有线程A 和 B一起使用 c变量并对他加1,这时就会有多中情况 这里要注意的是变量c是储存在内存中的,而线…

EDA --软件开发之路

之前一直在一家做数据处理的公司,从事c开发,公司业务稳定,项目有忙有闲,时而看下c,数据库,linux相关书籍,后面跳槽到了家eda公司,开始了一段eda开发之路。 eda 是 electric design …

分布式 ID 生成策略(二)

在上一篇文章,分布式 ID 生成策略(一),我们讨论了基于数据库的 ID 池策略,今天来看另一种实现,基于雪花算法的分布式 ID 生成策略。 如图所示,我们用 41 位时间戳 12 位机器 ID 10 位序列号&a…

大数据新视界 -- 大数据大厂之大数据重塑影视娱乐产业的未来(4 - 3)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…