65、Python之函数高级:装饰器实战,通用日志记录功能的动态添加

引言

从系统开发的规范性来说,日志的记录是一个规范化的要求,但是,有些程序员会觉得麻烦,反而不愿意记录日志,还是太年轻了……

其实,如果个人保护意识稍微强一些,一定会主动进行日志的记录的,无论是后续的BUG追踪、定位,或者与用户的掰扯(这种情况更多,用户非说自己做了什么,其实可能没有做什么,最后赖系统有问题)。

从规范性和自我保护来看,我们都很有必要记录日志,问题点在于怎么让日志记录变得更加灵活、方便。本文继续聊聊装饰器在日志记录上的实战应用,从而更加便捷地实现日志的记录。

本文的主要内容

1、关于日志的基本认知

2、日志记录的内置模块

3、装饰器实现灵活的日志记录

关于日志的基本认知

日志(Log)是应用程序在运行过程中生成的一系列记录,这些记录可以描述系统当时的状态、行为、事件及可能的错误等。日志中通常会包含时间戳、日志级别、消息内容、以及相关上下文信息。日志可以输出到控制台、写入文件、写入数据库或者推送到远程服务等。

日志的核心组成部分有:

1、时间戳(timestamp):记录事件的发生时间,很多时候定位问题,都是基于时间戳首先进行日志的检索。

2、日志级别(Log Level):标识日志所记录事件的严重程度,一般分为:DEBUG、INFO、WARNING、ERROR、CRITICAL等。

3、消息内容(Message Content):用于描述事件内容的信息,用于辅助定位事件类型、原因等。

4、上下文信息(Context Information):通常会记录所属模块、函数、参数等额外信息,便于帮助定位问题。

关于日志的作用,主要有以下几点:

1、便于开发过程中的调试、问题定位等。

2、用于监控系统的健康状态和性能指标。

3、出于审计和合规的需要,保持业务的连续性。

4、用户行为分析,比如运营侧提出的数据埋点的需要。

5、交流和沟通:模块与模块之间的协作,以及掰扯的需要。

日志记录的内置模块

接下来,我们看一下在Python中进行日志记录的最基本的做法。

在Python中,我们可以通过logging模块来进行日志的记录。使用起来比较简单,这里我们以实际代码演示该模块的使用。

直接看代码:

import logging
import timelogger = logging.getLogger('__name__')
logger.setLevel(logging.INFO)
logger.addHandler(logging.FileHandler('./log.txt'))def divide(a, b):logger.info(f'{time.strftime("%x %X", time.localtime())} 函数{divide.__name__}被调用 参数: {a},{b}')try:res = a / blogger.info(f'{time.strftime("%x %X", time.localtime())} 函数{divide.__name__}被调用 返回值: {res}')except Exception as e:# 参数exc_info表示记录异常信息logger.error(f'{time.strftime("%x %X", time.localtime())} 函数{divide.__name__}被调用 发生异常: {e}', exc_info=True)if __name__ == '__main__':divide(10, 2)time.sleep(3)divide(10, 0)

执行结果:

2a1973dc32b7d52631639f8b5d7b3fe8.jpeg

logging模块的使用比较简单,需要注意的是:

1、首先需要获取一个日志记录对象,并通过setLevel()设置其记录的日志级别,按照重要程度,>=设置级别的日志都会被记录,但是<设置级别的日志不会被记录。比如,logger.setLevel(logging.INFO),则DEBUG级别的日志是不会被记录的。

2、当需要记录异常的详细信息,比如调用栈信息,则在记录日志时,需要设置exc_info=True。

其他的内容就不展开了,感兴趣的同学可以自行查阅相关文档。

装饰器实现灵活的日志记录

如果每个函数内部都要写一遍日志处理的代码,似乎有些繁琐。涉及到通用功能的动态添加,我们很自然地就会想到装饰器。

接下来,我们通过装饰器来实现日志的统一处理。这次,我们通过类装饰器来实现,同时实现日志记录灵活的打开与关闭功能。

直接看代码:

import logging
import timeclass Logger:def __init__(self, log_path, is_enable=True):self.logger = logging.getLogger(log_path)self.logger.addHandler(logging.FileHandler(log_path))self.logger.setLevel(logging.INFO)self.is_enable = is_enabledef enable(self, is_enable):self.is_enable = is_enable@staticmethoddef get_time_str():return time.strftime("%x %X", time.localtime())def __call__(self, func):def wrap(*args, **kwargs):if self.is_enable:self.logger.info(f'{self.get_time_str()} 函数{func.__name__}被调用 参数: {args},{kwargs}')try:res = func(*args, **kwargs)if self.is_enable:self.logger.info(f'{self.get_time_str()} 函数{func.__name__}被调用 返回值: {res}')return resexcept Exception as e:if self.is_enable:self.logger.error(f'{self.get_time_str()} 函数{func.__name__}被调用 发生异常: {e}', exc_info=True)return wraplogger = Logger('./log.txt')@logger
def divide(a, b):return a / bif __name__ == '__main__':divide(10, 2)time.sleep(3)divide(10, 0)logger.enable(False)divide(10, 3)logger.enable(True)divide(5, 2)

执行结果:

8b4e06794a81d2abce157fc4eb932e64.jpeg

总结

本文简单介绍了日志的主要组成部分,以及日志记录的重要性。简单介绍了Python中利用logging模块进行日志记录的简单使用案例。最后,编写一个可以自行控制日志记录开关的类装饰器,来实现日志记录功能的动态扩充。

感谢您的拨冗阅读,希望对您有所帮助。

7ed0ad29272a99e4b6a7276480c8d217.jpeg

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python_openCV_计算图片中的区域的黑色比例

希望对原始图片进行处理&#xff0c;然后计算图片上的黑色和白色的占比 上图&#xff0c; 原始图片 import numpy as np import cv2 import matplotlib.pyplot as pltdef cal_black(img_file):#功能&#xff1a; 计算图片中的区域的黑色比例#取图片中不同的位置进行计算&…

关于武汉芯景科技有限公司的IIC缓冲器芯片XJ4307开发指南(兼容LTC4307)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、功能描述 1.总线超时&#xff0c;自动断开连接 当 SDAOUT 或 SCLOUT 为低电平时&#xff0c;将启动内部定时器。定时器仅在相应输入变为高电平时重置。如果在 30ms &#xff08;典型值&#xff09; 内没有变为高…

国产芯片LT9211D:MIPI转LVDS转换器,分辨率高达3840x2160 30Hz,碾压其它同功能芯片

以下为LT9211D&#xff1a;MIPI TO LVDS的芯片简单介绍&#xff0c;供各位参考 Lontium LT9211D是一款高性能MIPI DSI/CSI-2到双端口LVDS转换器。LT9211D反序列化 输入MIPI视频数据&#xff0c;解码数据包&#xff0c;转换格式化的视频数据流到LVDS发射机输出AP与移动显示面板或…

基于STM32L431小熊派设计的智能花盆(微信小程序+腾讯云IOT)(223)

文章目录 一、前言1.1 项目介绍【1】项目背景【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 系统框架图…

ppt模板简约下载哪个?这些模板简约又大气

中秋节&#xff0c;作为中国传统节日中最具诗意的一个&#xff0c;月圆人团圆的美好寓意总是让人心生向往。 想在国际网站上宣传这一传统节日的独特魅力&#xff0c;却担心自己的PPT不够吸引人&#xff1f;别急&#xff0c;使用精美免费的ppt模板&#xff0c;可以让你的演示瞬…

创新性处理Java编程技术问题的策略

在Java编程领域&#xff0c;解决技术问题的方式不断进化。本文将探讨一些创新性和针对性的技术问题处理方法&#xff0c;帮助开发者高效地应对挑战&#xff0c;提高代码质量和开发效率。 1. 动态代理与反射机制的优化 Java的动态代理和反射机制为程序员提供了强大的功能&#…

【性能】DJANGO + REDIS 缓存提速

不加REDIS缓存时&#xff0c;每次访问都要读取数据库&#xff0c;当访问量非常大的时候&#xff0c; 就会有很多次的数据库查询&#xff0c;会造成访问速度变慢&#xff0c;服务器资源占用较多等问题。 当使用了缓存后&#xff0c;访问情况变成了如下&#xff1a;访问一个网址时…

用户登录和注销

在Linux系统中&#xff0c;用户登录和注销是一个常见的操作&#xff0c;涉及到用户账户管理和服务管理等多个方面。下面分别介绍用户在图形界面和命令行下的登录和注销流程。 图形界面下的登录和注销 登录 登录界面&#xff1a; 当用户启动计算机时&#xff0c;通常会看到一…

Python Flask_APScheduler定时任务的正确(最佳)使用

描述 APScheduler基于Quartz的一个Python定时任务框架&#xff0c;实现了Quartz的所有功能。最近使用Flask框架使用Flask_APScheduler来做定时任务&#xff0c;在使用过程当中也遇到很多问题&#xff0c;例如在定时任务调用的方法中需要用到flask的app.app_context()时&#…

无影云电脑:在最破的电脑上玩最顶配的游戏

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点 我对云电脑很感兴趣&#xff0c;这几天我深度体验了无影云电脑的个人版.&#xff0c;我给大家分享下。这款云电脑到底能不能替代你的笔记本?到底能不能改变人们使用电脑的方式? 先说结论&#xff1a; (1)从草根创…

【Canvas与艺术】菊花孔雀螺旋

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>菊花孔雀螺旋</title><style type"text/css">…

vue3实现打飞机(雷电)

代码可直接运行直接玩&#xff0c;而且要自己加上一些随机事件都很简单了&#xff08;例如发射速度变快&#xff0c;子弹变大&#xff0c;敌人变慢等&#xff09; <template><div class"flex items-center justify-center h-100vh w-full"><div>S…

.net MAUI应用生命周期

.NET Multi-platform App UI (.NET MAUI) 应用通常有四种执行状态&#xff1a;“未运行”、“运行中”、“已停用”和“已停止”。 当应用从未运行状态转换为运行状态、从运行状态转换为已停用状态、从已停用状态转换为已停止状态、从已停止状态转换为运行状态&#xff0c;以及…

【Kubernetes】K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制

K8s 的鉴权管理&#xff08;二&#xff09;&#xff1a;基于属性 / 节点 / Webhook 的访问控制 1.基于属性的访问控制&#xff08;ABAC 鉴权&#xff09;2.基于节点的访问控制&#xff08;node 鉴权&#xff09;2.1 读取操作2.2 写入操作 3.基于 Webhook 的访问控制3.1 基于 We…

替换cython_bbox库中bbox_ious

说明一下问题&#xff1a;目标追踪代码里往往用到cython_bbox中的bbox_ious。但是该库需要用到 VC&#xff0c;按照有些麻烦。于是采用直接替换该方法&#xff0c;用纯代码实现&#xff0c;无需调用库。 File “src\cython_bbox.pyx”, line 17, in cython_bbox.bbox_overlaps…

深度学习-01 Pytorch

torchvision是一个用于计算机视觉任务的Python包&#xff0c;它是PyTorch的一个扩展库。它提供了一些流行的数据集、模型架构和图像转换函数&#xff0c;以方便用户进行计算机视觉任务的开发和研究。 1.torchvision中包含了许多常用的计算机视觉数据集&#xff0c;如MNIST、CIF…

【AcWing】861. 二分图的最大匹配(匈牙利算法)

匈牙利算法&#xff0c;他可以在比较快的时间复杂度之内告诉我们左边和右边成功匹配的最大数是多少 匹配指的是边的数量&#xff0c;成功的匹配指的是两个未被使用的点之间存在一条边(就不存在两条边共用了一个点的)。 匈牙利算法可以返回成功匹配的最大匹配数是多少。 #incl…

四、搭建网站服务器超详细步骤——解决宝塔界面无法登录问题

前言 本篇博客是搭建网站服务器的第四期&#xff0c;也到了中间的一节 先分享一下我在搭建网站时的个人感受&#xff0c;我在这个环节卡住了很久 后来突然醒悟了&#xff0c;然后成功进入了宝塔界面 现在就来分享一下&#xff0c;我所遇到的问题 小伙伴们坐好了 …

MySQL8 windows archive 安装

MySQL8超详细安装教程&#xff08;MySQL8安装图文教程&#xff09;_MySQL8安装包-CSDN博客 【补充&#xff1a;】 1.mysqld --install mysql // mysql是本次安装的服务命名&#xff0c;也可以叫做mysql8 etc. 2.手动卸载 2.1.net stop mysql 2.2.删除datadir // 即my.ini配置…

项目实战 ---- 商用落地视频搜索系统(9)---UI与上层service的交互优化

目录 背景 第一次优化(UI优化) 优化前UI 优化方向与问题 代码 修改效果 第二次优化(整合优化) 优化方向与问题 代码 优化效果 第三次优化(js层优化) 优化方向与问题 代码 优化效果 第四次优化(UI逻辑再优化) 优化方向与问题 代码 优化效果 第五次优化(纯U…