看项目时,发现一个性能监控装饰器,感觉挺有意思的。于是借鉴了他的思路,自己重新写了我认为更简洁的代码。
作用:可以放在类上和方法上,如果放在类上,则监控所有方法。根据设置的阈值,判断方法执行是否超时了,如果超时,那么就记录到日志文件当中去。
代码如下:
import logging
import sys
import time
from functools import wraps
from time import sleeplogging.basicConfig(level=logging.INFO,# 时间 日志Logger的名称 级别 信息format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',handlers=[logging.StreamHandler(sys.stdout), # 控制台输出logging.FileHandler('app.log', 'a') # 文件输出]
)
logging = logging.getLogger(__name__)# threshold:阈值,默认为1s
def monitor_performance(threshold : int = 1):def decorator(func_or_class):if isinstance(func_or_class, type): # 处理类装饰器class WrappedClass(func_or_class):# 该方法会拦截访问实例的方法def __getattribute__(self, name):attr = super().__getattribute__(name)# 拦截非私有方法if callable(attr) and not name.startswith("_"):# 保留函数的基础信息@wraps(attr)def wrapped_method(*args, **kwargs):start_time = time.time()res = attr(*args, **kwargs)end_time = time.time()duration = end_time - start_timeif duration > threshold:logging.info(f"{func_or_class.__name__}.{name}耗时{end_time - start_time}s,超过了阈值{threshold}s")return resreturn wrapped_methodreturn attrreturn WrappedClasselse: # 处理函数装饰器@wraps(func_or_class)def wrapped_method(*args, **kwargs):start_time = time.time()res = func_or_class(*args, **kwargs)end_time = time.time()duration = end_time - start_timeif duration > threshold:logging.info(f"{func_or_class.__name__}耗时{end_time - start_time}s,超过了阈值{threshold}s")return resreturn wrapped_methodreturn decorator# @monitor_performance()
class Person:@monitor_performance()def test(self):sleep(3)print(".........")Person().test()
输出如下: