Python的Logging模块高级用法-日志处理

👽发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。

探索Python中的日志处理:Logging模块的高级用法

在Python应用程序中,日志处理是一项至关重要的任务,它有助于跟踪应用程序的状态、诊断问题以及记录关键信息。Python提供了内置的Logging模块,使得日志记录变得简单而强大。在本文中,我们将探索Logging模块的高级用法,包括日志级别、格式化、处理程序等方面的功能。

1. 日志级别

Logging模块支持多个日志级别,从最低的DEBUG到最高的CRITICAL。使用不同的级别可以控制日志信息的输出粒度,以及对应用程序的影响程度。以下是Python Logging模块支持的日志级别:

  • DEBUG:用于详细的调试信息。
  • INFO:用于确认应用程序的正常运行。
  • WARNING:用于指示潜在的问题,但不影响应用程序的正常工作。
  • ERROR:用于指示应用程序中的错误,可能影响部分功能的正常运行。
  • CRITICAL:用于指示严重错误,可能导致应用程序崩溃。
import logging

logging.basicConfig(level=logging.DEBUG)

logging.debug('这是一个DEBUG级别的日志信息')
logging.info('这是一个INFO级别的日志信息')
logging.warning('这是一个WARNING级别的日志信息')
logging.error('这是一个ERROR级别的日志信息')
logging.critical('这是一个CRITICAL级别的日志信息')

2. 格式化

Logging模块允许开发者对日志信息进行格式化,以便更好地理解和分析日志内容。可以在日志处理器中指定格式化字符串,其中可以包含特定的占位符,如日志级别、时间戳、模块名等。

import logging

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

logging.debug('这是一个DEBUG级别的日志信息')

3. 处理程序

Logging模块支持将日志信息发送到不同的处理程序,例如文件、控制台、网络等。通过添加不同的处理程序,可以根据需要将日志信息发送到不同的目的地。

import logging

# 创建一个FileHandler处理程序,将日志信息写入文件
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.ERROR)

# 创建一个StreamHandler处理程序,将日志信息输出到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# 创建一个格式化字符串
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 将格式化字符串应用到处理程序
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 添加处理程序到Logger对象
logger = logging.getLogger(__name__)
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 发送日志信息
logger.debug('这是一个DEBUG级别的日志信息')
logger.error('这是一个ERROR级别的日志信息')

4. 过滤器

Logging模块还提供了过滤器的功能,可以根据需求对日志信息进行筛选和过滤。过滤器可以基于日志级别、模块名等条件来过滤日志信息,使得日志记录更加精确和有效。

import logging

class DebugFilter(logging.Filter):
    def filter(self, record):
        return record.levelno == logging.DEBUG

# 创建一个Logger对象
logger = logging.getLogger(__name__)

# 创建一个FileHandler处理程序
file_handler = logging.FileHandler('debug.log')
file_handler.setLevel(logging.DEBUG)

# 创建一个格式化字符串
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 创建一个DebugFilter过滤器
debug_filter = DebugFilter()

# 将格式化字符串应用到处理程序
file_handler.setFormatter(formatter)

# 将过滤器应用到处理程序
file_handler.addFilter(debug_filter)

# 添加处理程序到Logger对象
logger.addHandler(file_handler)

# 发送日志信息
logger.debug('这是一个DEBUG级别的日志信息')
logger.info('这是一个INFO级别的日志信息')

5. 配置文件

Logging模块支持从配置文件中加载配置信息,使得日志处理的配置更加灵活和可配置化。通过配置文件,开发者可以指定日志级别、格式化、处理程序等信息,并根据需要进行调整和修改,而不需要修改源代码。

# logging.conf
[loggers]
keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=sampleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=sampleFormatter
args=(sys.stdout,)

[formatter_sampleFormatter]
format=%(asctime)s - %(levelname)s - %(message)s
# 使用配置文件进行日志配置
import logging
import logging.config

logging.config.fileConfig('logging.conf')

logger = logging.getLogger(__name__)

logger.debug('这是一个DEBUG级别的日志信息')
logger.info('这是一个INFO级别的日志信息')

6. 日志轮转

日志轮转是一种常见的日志管理技术,它可以在日志文件达到一定大小或者在特定时间间隔后,自动将当前日志文件重命名并创建一个新的日志文件,以避免日志文件过大或者过期。Python的Logging模块提供了相应的轮转处理程序,方便开发者实现日志轮转功能。

import logging
from logging.handlers import RotatingFileHandler

# 创建一个Logger对象
logger = logging.getLogger(__name__)

# 创建一个RotatingFileHandler处理程序
file_handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=3)
file_handler.setLevel(logging.DEBUG)

# 创建一个格式化字符串
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 将格式化字符串应用到处理程序
file_handler.setFormatter(formatter)

# 添加处理程序到Logger对象
logger.addHandler(file_handler)

# 发送日志信息
for i in range(10):
    logger.debug(f'这是第{i+1}条DEBUG级别的日志信息')

7. 日志归档

日志归档是另一种常见的日志管理技术,它可以根据时间周期性地将日志文件进行归档,例如按照每天、每周或者每月生成一个新的日志文件。Python的Logging模块也提供了相应的归档处理程序,可以轻松实现日志的自动归档功能。

import logging
from logging.handlers import TimedRotatingFileHandler

# 创建一个Logger对象
logger = logging.getLogger(__name__)

# 创建一个TimedRotatingFileHandler处理程序
file_handler = TimedRotatingFileHandler('app.log', when='midnight', interval=1, backupCount=3)
file_handler.setLevel(logging.DEBUG)

# 创建一个格式化字符串
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 将格式化字符串应用到处理程序
file_handler.setFormatter(formatter)

# 添加处理程序到Logger对象
logger.addHandler(file_handler)

# 发送日志信息
for i in range(10):
    logger.debug(f'这是第{i+1}条DEBUG级别的日志信息')

8. 自定义处理程序

除了使用Logging模块提供的内置处理程序外,开发者还可以自定义处理程序来满足特定的需求。通过自定义处理程序,可以将日志信息发送到自定义的目的地,例如数据库、消息队列等,以满足特定场景下的日志记录需求。

import logging

class CustomHandler(logging.Handler):
    def emit(self, record):
        # 自定义处理逻辑
        log_entry = self.format(record)
        # 将日志信息发送到自定义目的地
        print(f"CustomHandler: {log_entry}")

# 创建一个Logger对象
logger = logging.getLogger(__name__)

# 创建一个自定义处理程序
custom_handler = CustomHandler()
custom_handler.setLevel(logging.DEBUG)

# 创建一个格式化字符串
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 将格式化字符串应用到处理程序
custom_handler.setFormatter(formatter)

# 添加处理程序到Logger对象
logger.addHandler(custom_handler)

# 发送日志信息
logger.debug('这是一个DEBUG级别的日志信息')

9. 异常处理中的日志记录

在异常处理中记录日志是一种常见的做法,它可以帮助开发者及时捕获和排查应用程序中的异常情况,从而提升应用程序的稳定性和可靠性。

import logging

# 创建一个Logger对象
logger = logging.getLogger(__name__)

try:
    # 尝试执行可能会抛出异常的代码
    result = 10 / 0
except Exception as e:
    # 在异常处理中记录日志
    logger.exception('发生了一个异常')

10. 日志记录最佳实践

在使用Logging模块记录日志时,除了掌握各种高级功能外,还有一些最佳实践值得我们注意。这些最佳实践可以帮助我们更好地利用Logging模块,提高日志记录的效率和可维护性。

  • 适当选择日志级别: 使用适当的日志级别可以控制日志信息的输出量,避免在生产环境中输出过多的调试信息。

  • 格式化一致性: 保持日志格式的一致性可以方便日志信息的查阅和分析,建议在整个应用程序中采用相同的日志格式。

  • 异常处理中的日志记录: 在异常处理中记录日志可以帮助我们及时捕获和排查异常情况,建议在应用程序的关键异常处理逻辑中添加相应的日志记录。

  • 日志轮转和归档: 对于日志文件的管理,建议使用日志轮转和归档功能,以避免日志文件过大或者过期。

  • 自定义处理程序: 根据实际需求,可以考虑自定义处理程序,将日志信息发送到自定义的目的地,以满足特定场景下的日志记录需求。

11. 日志记录的性能考量

除了功能和最佳实践外,我们还需要考虑日志记录对应用程序性能的影响。尽管Logging模块提供了强大的功能,但不合理的日志记录方式可能会导致性能下降,特别是在高负载的生产环境中。

  • 慎用DEBUG级别: 在生产环境中,避免过度使用DEBUG级别的日志记录,因为它们会产生大量的输出,并可能影响应用程序的性能。建议在生产环境中仅记录必要的信息。

  • 异步日志记录: 对于高并发的应用程序,考虑使用异步日志记录器来提高性能。异步记录器可以将日志信息缓冲并异步地写入到目标处理程序,从而减少对主线程的阻塞。

  • 日志记录器的层级结构: 合理构建日志记录器的层级结构可以帮助我们更好地管理和控制日志记录的性能。尽量避免在每个模块中都创建一个独立的日志记录器,而是应该根据业务逻辑和模块功能来组织日志记录器的层级结构。

12. 性能优化技巧

为了进一步提高日志记录的性能,我们可以采取一些优化技巧来减少日志记录对应用程序性能的影响。

  • 批量处理: 将多条日志信息合并成一条进行批量处理,可以减少IO操作和资源消耗,提高日志记录的效率。

  • 使用更快的处理程序: 对于性能敏感的场景,可以考虑使用更快速的处理程序,如MemoryHandler或QueueHandler,以减少日志记录对应用程序性能的影响。

  • 禁用不必要的处理程序: 定期审查和禁用不必要的处理程序,可以减少日志记录的开销,提高应用程序的性能。

总结

Python中的Logging模块提供了丰富的功能和灵活的配置选项,使得日志记录变得简单而强大。通过本文的介绍,我们深入探讨了Logging模块的高级用法,包括日志级别、格式化、处理程序、过滤器、配置文件等方面的功能。我们还分享了一些日志记录的最佳实践,如适当选择日志级别、保持日志格式的一致性、在异常处理中记录日志等。此外,我们还探讨了日志记录对应用程序性能的影响以及性能优化技巧,帮助开发者更好地管理和维护应用程序的日志信息,提高应用程序的质量和性能。

总的来说,合理地使用Logging模块提供的功能和最佳实践,以及考虑日志记录对应用程序性能的影响并采取相应的性能优化措施,将有助于提高应用程序的可靠性、可维护性和性能,为应用程序的稳定运行和问题排查提供更好的支持。

在这里插入图片描述

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

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

相关文章

lementui el-menu侧边栏占满高度且不超出视口

做了几次老是忘记,这次整理好逻辑做个笔记方便重复利用; 问题:elementui的侧边栏是占不满高度的;但是使用100vh又会超出视口高度不美观; 解决办法: 1.获取到侧边栏底部到视口顶部的距离 2.获取到视口的高…

【动态规划】dp 路径问题(不同路径、路径最小和、地下城游戏...)

文章目录 1. 前言 - 理解动态规划算法1.5 关于dp路径问题2. 例题2.1_不同路径Warning. 关于状态表示 3. 算法题3.1_不同路径II3.2_珠宝的最高价值3.3_下降路径最小和3.4_最小路径和3.5_地下城游戏关于状态表示的两种选法: 1. 前言 - 理解动态规划算法 关于 动态规划…

Pytorch 之torch.nn初探 池化--Pooling Layers

任务描述 本关任务:本关提供了一个Variable 类型的变量x,要求按照条件创建一个Conv2d变量conv,一个MaxPool2d变量pool,对x应用卷积和最大池化操作并赋值给变量outpout_pool,并输出outpout_pool 的大小。 相关知识 P…

Blerden4.1基础操作方法

软件安装 下载软件地址 中文文档 偏好设置 编辑——》偏好设置——》界面——》设置分辨率缩放 1.20 方便观看字体 设置快捷键 是为了方便几个3d软件都变成同一种操作方式 这样就不会自己搞混了 编辑——》偏好设置——》键位映射——》3D视图——》3D视图(全局…

将windows作为网关

开启转发 reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v IPEnableRouter /D 1 /f开启routing and remote access服务 这样局域网里面别的设备能通过windows进行上网 参考:https://www.cnblogs.com/chrishg/articles/12861053.html

Springboot+Vue项目-基于Java+MySQL的房屋租赁系统(附源码+演示视频+LW)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…

OceanBase V4.2特性解析:用 Show Trace 快速定位数据库性能瓶颈

在数据库日常运维中,当遇到慢SQL问题时,若无法迅速查明原因,将极大地影响用户的使用感受,甚至可能引发业务或服务的中断。相较于单机数据库,分布式数据库系统因其涉及多个节点和多组件的协同工作,集群规模可…

短视频流媒体平台的系统设计

1. 功能需求: 我们的系统有两类参与者 内容创作者 •上传任何类型的视频(格式编解码器)•视频可以被删除•视频元数据•必填项: 标题,作者,描述•选填项: 分类/标签列表•可以随时更新•当视频对观众可用时,向内容创作…

怎么把相机储存卡里的照片导出来?介绍两种方法

随着摄影技术的不断发展和普及,相机已成为我们记录生活、捕捉美好瞬间的设备。然而,对于许多摄影爱好者来说,如何将相机储存卡里的照片安全、高效地导出到电脑或其他设备中,却成为了一个令人头疼的问题。本文将为您详细介绍从相机…

17.C++常用的算法_集合算法

文章目录 遍历算法1. set_intersection()代码工程运行结果 2. set_union()代码工程运行结果 3. set_difference()代码工程运行结果 遍历算法 1. set_intersection() 代码工程 /*1.求交集的两个集合必须是有序序列*/ /*2.目标容器开辟空间需要从两个容器中取较小值*/ /*3.set…

小程序中使用HTTPS调用自带文本安全内容检测接口(msg_sec_check)的实现方法

在小程序中调用自带的文本安全内容检测接口,你需要使用小程序提供的wx.request方法。以下是一个示例代码: javascript代码: // 假设你已经获取了access_token,如果不知道如何获取,可以参考我上一篇文章 const access_token 你的access_tok…

【结构型模式】外观模式

​一、外观模式概述 外观模式定义与意图:外观类为复杂的子系统提供了一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。(对象结构型模式) 外观模式的特点: 1.又叫做门面模式&#xf…

电磁炉原理笔记

电磁炉加热原理 【电磁炉工作原理,电涡流感应加热原理】 https://www.bilibili.com/video/BV11M411M7Wt/?share_sourcecopy_web&vd_source44c5c5fe44538189ece80f09460cf625 我是看的这个科普视频; 总结一下就是下图: 线圈的磁场影响…

链表判环问题

1、为什么slow走一步,fast走两步,会不会错过?请证明。 假设slow进环的时候fast和slow之间的距离时N,slow进环以后,fast开始追击slow每走一步,fast走2步,他们之间的距离缩小1. fast和slow之间的…

“三步走”带你拿下C++类与对象(下)

在学习了“上”篇和“中”篇后,我们对类和对象以及一些析构函数有了一定的理解,本文我们将继续深入讲解有关的其他内容。 一、初始化列表的引入 我们以之前的队列为例子(创建两个队列一个用于入栈一个用于出栈) 这个myqueue对内…

全志R329 AP6256 蓝牙调试

1、在全志r329平台移植AP6256,移植了一个星期,记录下过程。 2、本来产品只需要wifi,不需要蓝牙的。但是我们使用的是正基AP6256的wifi、BT二合一的模组。 该模块只要有BT功能就需要做BT的3C认证。 好吧。 1、获取调试蓝牙的几个工具 两个方法: 1.1、方法一:自己交叉…

蓝桥杯2024年第十五届省赛真题-爬山

贪心优先队列的题&#xff0c;贪心会漏一个情况&#xff0c;不知道怎么处理&#xff0c;这里直接打表了 2 1 1 48 49 答案是30&#xff0c;贪心是31 专有名词&#xff1a;hack-有新的测试点过不了 #include<bits/stdc.h> using namespace std; #define endl \n #define …

QT C++ sqlite 对多个数据库的操作

//本文描述&#xff0c;QT 对多数据库的操作。 //你可能会想&#xff0c;多数据库的操作时&#xff0c;查询语句怎么知道是哪个数据库。 //QT提供了这样一种构造函数 QSqlQuery(const QSqlDatabase &db) //指定数据库 //在QT6.2.4 MSVC2019调试通过。 //效果见下图&am…

HarmonyOs开发:导航tabs组件封装与使用

前言 主页的底部导航以及页面顶部的切换导航&#xff0c;无论哪个系统&#xff0c;哪个App&#xff0c;都是最常见的功能之一&#xff0c;虽然说在鸿蒙中有现成的组件tabs可以很快速的实现&#xff0c;但是在使用的时候&#xff0c;依然有几个潜在的问题存在&#xff0c;第一&a…

12. MyBatis(二)

源码位置&#xff1a;MyBatis_demo 上篇文章我们学习了MyBatis的定义以及增删查改操作&#xff0c;并且学习了如何在xml文件中编写SQL时使用#{}的方式将参数和对象的属性映射到SQL语句中&#xff0c;上篇的内容已经足以应对大部分场景&#xff0c;本篇文章我们就要学习一下MyBa…