【python】Python中的日志模块logging使用技巧与应用实战

2024-08-21 05:52

本文主要是介绍【python】Python中的日志模块logging使用技巧与应用实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:python综合应用,基础语法到高阶实战教学
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • Python中日志模块logging
    • 一、日志模块基础
      • 1.1 导入日志模块
      • 1.2 配置日志
      • 1.3 记录日志
      • 1.4 示例代码
    • 二、日志模块的高级特性
      • 2.1 Logger对象
      • 2.2 Handler对象
      • 2.3 Formatter对象
      • 2.4 示例代码:日志输出到文件
      • 2.5 日志级别和过滤器
      • 2.6 日志轮转
      • 2.7 日志配置文件
      • 2.8 示例代码:使用配置文件
      • 注意事项
      • 日志的其他一些高级用法
        • 1. 日志上下文(Context)
        • 2. 异步日志
        • 3. 日志监控和警报
        • 4. 日志的归档和清理
        • 5. 安全性考虑

Python中日志模块logging

在Python开发中,日志记录是一个非常重要的环节。它不仅有助于开发者追踪程序的执行流程,还能在出现问题时提供关键信息,帮助快速定位并解决问题。Python标准库中的logging模块提供了灵活且强大的日志记录功能,支持将日志输出到不同的目标(如文件、终端等),并支持不同级别的日志记录(如调试、信息、警告、错误等)。本文将结合实际案例,详细介绍logging模块的基础用法和高级特性。

一、日志模块基础

1.1 导入日志模块

首先,我们需要导入logging模块。这是使用日志功能的前提。

import logging

1.2 配置日志

在使用logging模块之前,我们可以配置日志的基本设置,如设置日志级别、输出格式等。以下是一个简单的配置示例:

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
  • level: 设置日志级别,可以选择DEBUGINFOWARNINGERRORCRITICAL
  • format: 设置日志输出格式,上述格式中包含了时间、级别和消息。

1.3 记录日志

配置好日志后,我们就可以使用logging模块记录日志了。例如:

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

1.4 示例代码

下面是一个结合上述内容的示例代码,演示如何在代码中使用logging模块:

import logging# 配置日志
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')def divide(x, y):try:result = x / yexcept ZeroDivisionError:logging.error("Attempted to divide by zero")else:logging.info(f"The result of {x}/{y} is {result}")if __name__ == "__main__":# 记录日志logging.debug("Program starts")# 调用函数divide(10, 2)divide(8, 0)# 记录日志logging.debug("Program ends")

在这里插入图片描述

在这个例子中,我们定义了一个divide函数,该函数尝试执行除法运算。如果发生ZeroDivisionError,则记录一个错误日志;否则,记录一个信息日志。通过配置日志,我们可以清晰地看到程序的执行流程,包括开始、结束以及可能发生的异常情况。

二、日志模块的高级特性

2.1 Logger对象

Logger对象是logging模块中用于记录日志的主要接口。我们可以创建自己的Logger对象,也可以使用默认的根Logger对象。Logger对象提供了debug()info()warning()error()critical()等方法来记录不同级别的日志。

2.2 Handler对象

Handler对象用于指定日志的输出目标,如文件、终端、网络等。Handler对象可以添加到Logger对象中,以处理相应级别的日志消息。logging模块提供了多种Handler,如FileHandler(将日志写入文件)、StreamHandler(将日志输出到终端)等。

2.3 Formatter对象

Formatter对象用于指定日志消息的输出格式。通过Formatter,我们可以自定义日志消息的显示方式,包括日期、时间、日志级别、消息内容等。

2.4 示例代码:日志输出到文件

下面是一个将日志输出到文件的示例代码:

import logging# 创建一个Logger对象
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)# 创建一个Formatter对象,指定日志消息的格式
format = '%(asctime)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(format)# 创建一个FileHandler对象,将日志输出到文件
file_handler = logging.FileHandler('output.txt')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)# 将FileHandler对象添加到Logger对象中
logger.addHandler(file_handler)# 创建一个StreamHandler对象,将日志输出到终端
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)# 将StreamHandler对象也添加到Logger对象中
logger.addHandler(console_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")# 移除一个Handler(如果需要的话)
# logger.removeHandler(file_handler)# 关闭所有Handlers(通常不需要手动调用,因为Python解释器会在退出时自动处理)
# 但如果程序需要长时间运行,并且希望定期关闭和重新打开日志文件,那么可能需要这样做
# for handler in logger.handlers[:]:
#     handler.close()
#     logger.removeHandler(handler)# 注意:在上面的代码中,我们没有显式地导入sys模块,但如果你打算将日志输出到标准输出(即终端),
# 并且想要使用sys.stdout作为StreamHandler的参数,那么你需要先导入sys模块:
# import sys
# 完整的示例,包括导入sys模块
import logging
import sys# 创建一个Logger对象
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)# 创建一个Formatter对象,指定日志消息的格式
format = '%(asctime)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(format)# 创建一个FileHandler对象,将日志输出到文件
file_handler = logging.FileHandler('output.txt')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)# 创建一个StreamHandler对象,将日志输出到终端
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)# 将Handlers添加到Logger对象中
logger.addHandler(file_handler)
logger.addHandler(console_handler)# 记录日志
logger.debug("This debug message will appear in the console but not in the file")
logger.info("This info message will appear in both the console and the file")
logger.warning("This is a warning")
logger.error("This is an error")
logger.critical("This is a critical error")

在这里插入图片描述
并且将日志输出到文件
在这里插入图片描述

2.5 日志级别和过滤器

logging模块中,日志级别用于控制日志消息的输出。默认情况下,只有级别大于或等于Logger对象设置的级别的日志消息才会被处理。此外,我们还可以使用过滤器(Filter)来进一步控制哪些日志消息应该被处理。

2.6 日志轮转

对于长时间运行的应用程序,日志文件可能会变得非常大。为了管理这些文件,我们可以使用日志轮转(Log Rotation)功能。然而,logging模块本身并不直接支持日志轮转,但我们可以使用第三方库(如logrotate,在Linux环境下,或者RotatingFileHandler,它是logging.handlers模块的一部分)来实现这一功能。

2.7 日志配置文件

对于复杂的应用程序,直接在代码中配置日志可能会变得繁琐且难以维护。为了解决这个问题,logging模块支持从配置文件中读取日志配置。配置文件可以是Python文件、JSON文件或YAML文件等。使用配置文件可以让我们将日志配置与应用程序代码分离,从而更容易地进行修改和维护。

2.8 示例代码:使用配置文件

下面是一个使用JSON配置文件配置日志的示例。首先,我们创建一个名为logging_config.json的配置文件:

{"version": 1,"disable_existing_loggers": false,"formatters": {"simple": {"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"}},"handlers": {"console": {"class": "logging.StreamHandler","level": "DEBUG","formatter": "simple","stream": "ext://sys.stdout"},"file": {"class": "logging.FileHandler","level": "INFO","formatter": "simple","filename": "app.log"}},"loggers": {"my_app": {"handlers": ["console", "file"],"level": "DEBUG","propagate": false}},
"root": {"handlers": ["console"],"level": "INFO"}
}

然后,在Python代码中,我们可以使用logging.config.dictConfig()函数来加载这个配置文件,并应用配置:


import json
import logging.config# 加载日志配置文件
with open('logging_config.json', 'r') as f:config = json.load(f)
logging.config.dictConfig(config)# 获取配置好的Logger对象
logger = logging.getLogger('my_app')# 记录日志
logger.debug("This debug message will appear in the console and the file")
logger.info("This info message will appear in both the console and the file")
logger.warning("This is a warning")
logger.error("This is an error")
logger.critical("This is a critical error")# 注意:由于我们在配置文件中将'my_app' logger的propagate属性设置为False,
# 设置propagate参数为False,表示不再传递消息到父记录器
# 因此'my_app' logger的日志消息不会传播到root logger。
# 如果我们尝试获取root logger并记录日志,它只会按照root logger的配置(即只输出到控制台)来工作。
root_logger = logging.getLogger()
root_logger.info("This info message from the root logger will only appear in the console")

在这里插入图片描述
看下生成的日志文件
在这里插入图片描述

注意事项

  1. 配置文件中的路径:在配置文件中指定的文件路径(如filename)是相对于当前工作目录的。确保你的应用程序知道在哪里查找这些文件。

  2. 日志级别:每个handler和logger都可以有自己的日志级别。handler的级别决定了哪些级别的日志消息会被该handler处理,而logger的级别决定了哪些级别的日志消息会被发送到该logger的handlers。

  3. 传播(Propagation):默认情况下,如果一个logger没有处理一个日志消息(即它的级别高于logger的级别),那么该消息会被传播到它的父logger。但是,我们可以通过将logger的propagate属性设置为False来阻止这种传播。

  4. 日志配置的性能:在大型应用程序中,日志配置可能会对性能产生影响。确保你仔细规划你的日志策略,以避免不必要的性能开销。

  5. 安全性和隐私:在记录日志时,要特别注意不要记录敏感信息(如密码、个人身份信息等)。始终确保你的日志策略符合你的组织的安全和隐私政策。

  6. 调试和排错:日志是调试和排错的重要工具。确保你的日志策略足够详细,以便在需要时能够提供足够的上下文信息。但是,也要避免记录过多的日志,因为这可能会使问题变得更加难以诊断。

日志的其他一些高级用法

1. 日志上下文(Context)

在复杂的系统中,日志消息可能来自于不同的线程、不同的模块或不同的请求。为了更容易地追踪和关联这些日志消息,我们可以在日志消息中包含上下文信息,如用户ID、请求ID、线程ID等。

虽然Python的logging模块本身不直接支持日志上下文,但我们可以通过几种方式来实现:

  • 使用logging.extra:在记录日志时,可以通过在日志记录方法(如debug(), info(), warning()等)中传递一个extra参数来附加额外的上下文信息。这些信息将作为日志记录的一部分被格式化。

  • 使用上下文管理器:可以编写自定义的上下文管理器,该管理器在进入上下文时设置全局变量或线程局部变量来存储上下文信息,并在退出上下文时清除它们。然后,在日志格式化器中使用这些信息。

  • 使用第三方库:有些第三方库(如structlog)提供了更高级的日志功能,包括自动上下文管理。

2. 异步日志

在异步Python程序中(使用asyncio库),日志记录可能需要特别注意。由于异步代码的执行方式(即事件循环中的协程调度),直接在协程中调用阻塞的日志记录方法(如文件写入)可能会影响程序的性能。

为了解决这个问题,可以使用logging模块的异步支持(如果可用)或编写自定义的异步日志处理器。然而,需要注意的是,Python标准库中的logging模块直到较新的版本才开始提供对异步日志的原生支持。

3. 日志监控和警报

在生产环境中,仅仅记录日志是不够的。我们还需要监控系统中的日志,以便在出现问题时及时得到警报。这通常涉及到日志的集中管理、分析和警报系统。

  • 日志集中管理:可以使用日志聚合工具(如Logstash、Fluentd等)将来自不同源和系统的日志收集到一个中心位置。

  • 日志分析:使用日志分析工具(如Splunk、ELK Stack等)对收集的日志进行搜索、分析和可视化。

  • 警报系统:配置警报规则,以便在检测到特定日志模式(如错误日志、异常日志等)时发送警报(如电子邮件、短信、Slack通知等)。

4. 日志的归档和清理

随着时间的推移,日志文件会积累得越来越多,占用大量的磁盘空间。因此,需要定期归档和清理旧的日志文件。

  • 日志轮转:如前所述,可以使用RotatingFileHandler或第三方工具(如logrotate)来定期轮转日志文件。

  • 归档:将旧的日志文件压缩并存储到归档目录中,以便在需要时检索。

  • 清理:删除过期的日志文件以释放磁盘空间。

5. 安全性考虑

在记录日志时,必须特别注意安全性,以避免敏感信息的泄露。

  • 避免记录敏感信息:确保不要在日志中记录密码、个人身份信息(PII)、密钥等敏感信息。

  • 日志文件的访问控制:确保只有授权用户才能访问日志文件。

  • 加密日志存储:如果日志需要存储在不受信任的位置(如云服务提供商的存储桶),请考虑对日志进行加密。

  • 审计日志:对于需要符合特定法规(如GDPR、HIPAA等)的应用程序,可能需要记录审计日志以证明合规性。

通过以上方法,可以有效地管理和利用Python程序中的日志,从而提高软件的可维护性、可靠性和安全性。

这篇关于【python】Python中的日志模块logging使用技巧与应用实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092310

相关文章

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

解读GC日志中的各项指标用法

《解读GC日志中的各项指标用法》:本文主要介绍GC日志中的各项指标用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基础 GC 日志格式(以 G1 为例)1. Minor GC 日志2. Full GC 日志二、关键指标解析1. GC 类型与触发原因2. 堆

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语