【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

相关文章

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Python Websockets库的使用指南

《PythonWebsockets库的使用指南》pythonwebsockets库是一个用于创建WebSocket服务器和客户端的Python库,它提供了一种简单的方式来实现实时通信,支持异步和同步... 目录一、WebSocket 简介二、python 的 websockets 库安装三、完整代码示例1.

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain