看項目時,發現一個性能監控裝飾器,感覺挺有意思的。于是借鑒了他的思路,自己重新寫了我認為更簡潔的代碼。
作用:可以放在類上和方法上,如果放在類上,則監控所有方法。根據設置的閾值,判斷方法執行是否超時了,如果超時,那么就記錄到日志文件當中去。
代碼如下:
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()
輸出如下:
?