Python 高阶函数:日志的高级用法

news2025/7/13 10:42:26

日志装饰器的 **7 个高阶优化方案**,结合了生产环境最佳实践和调试深度需求:

 

---

 

### 一、**智能动态采样装饰器**  

解决高频函数日志过多问题,自动根据错误率调整日志频率

```python

from collections import defaultdict

import time

 

class AdaptiveLogger:

    def __init__(self, base_interval=1.0, error_threshold=3):

        self.func_stats = defaultdict(lambda: {'total':0, 'errors':0})

        self.base_interval = base_interval

        self.error_threshold = error_threshold

 

    def __call__(self, func):

        @wraps(func)

        def wrapper(*args, **kwargs):

            stats = self.func_stats[func.__name__]

            stats['total'] += 1

            

            # 错误率超过阈值时开启详细日志

            if stats['errors'] > self.error_threshold:

                log_level = logging.DEBUG

            else:

                log_level = logging.INFO

 

            # 采样控制

            if time.time() - stats.get('last_log', 0) > self.base_interval:

                logging.log(log_level, f"Sampling call to {func.__name__}")

                stats['last_log'] = time.time()

 

            try:

                return func(*args, **kwargs)

            except Exception:

                stats['errors'] += 1

                raise

        return wrapper

 

# 使用示例

adaptive_logger = AdaptiveLogger()

@adaptive_logger

def high_frequency_api():

    pass

```

 

---

 

### 二、**全链路追踪装饰器**  

跨函数追踪调用关系,生成可视化调用树

```python

import threading

from graphviz import Digraph

 

class TraceVisualizer:

    _local = threading.local()

 

    def __init__(self, output_file="call_graph"):

        self.graph = Digraph(comment='Call Graph')

        self.output_file = output_file

 

    def __call__(self, func):

        @wraps(func)

        def wrapper(*args, **kwargs):

            if not hasattr(self._local, 'call_stack'):

                self._local.call_stack = []

 

            parent = self._local.call_stack[-1] if self._local.call_stack else None

            node_id = f"{func.__name__}_{id(args)}_{id(kwargs)}"

            

            self.graph.node(node_id, func.__name__)

            if parent:

                self.graph.edge(parent, node_id)

            

            self._local.call_stack.append(node_id)

            try:

                result = func(*args, **kwargs)

            finally:

                self._local.call_stack.pop()

            

            if not self._local.call_stack:

                self.graph.render(self.output_file, cleanup=True)

            

            return result

        return wrapper

 

# 使用示例

tracer = TraceVisualizer()

@tracer

def a(): b()

@tracer 

def b(): c()

@tracer

def c(): pass

 

a() # 生成call_graph.pdf

```

 

---

 

### 三、**内存时间线记录装饰器**  

记录函数生命周期内的内存变化曲线(需 `matplotlib`)

```python

import psutil

import matplotlib.pyplot as plt

 

def memory_timeline(func):

    @wraps(func)

    def wrapper(*args, **kwargs):

        process = psutil.Process()

        timeline = []

        

        def record_memory():

            while getattr(threading.current_thread(), "do_monitor", True):

                timeline.append(process.memory_info().rss / 1024**2)

                time.sleep(0.01)

        

        monitor_thread = threading.Thread(target=record_memory)

        monitor_thread.start()

        

        try:

            result = func(*args, **kwargs)

        finally:

            monitor_thread.do_monitor = False

            monitor_thread.join()

            

            plt.plot(timeline)

            plt.title(f"Memory Usage of {func.__name__}")

            plt.ylabel("MB")

            plt.show()

        

        return result

    return wrapper

 

# 使用示例

@memory_timeline

def process_large_data():

    data = [np.random.rand(1000,1000) for _ in range(10)]

    time.sleep(1)

```

 

---

 

### 四、**AI异常诊断装饰器**  

接入大模型自动分析错误原因(需 OpenAI API)

```python

import openai

 

def ai_diagnosis(api_key):

    def decorator(func):

        @wraps(func)

        def wrapper(*args, **kwargs):

            try:

                return func(*args, **kwargs)

            except Exception as e:

                error_info = f"""

                Error Type: {type(e).__name__}

                Message: {str(e)}

                Args: {args}

                Kwargs: {kwargs}

                Traceback: {traceback.format_exc()}

                """

                

                response = openai.ChatCompletion.create(

                    model="gpt-4",

                    messages=[{

                        "role": "user",

                        "content": f"分析以下Python错误原因,用中文给出解决建议:\n{error_info}"

                    }]

                )

                

                logging.error("AI诊断结果:\n" + response.choices[0].message.content)

                raise

        return wrapper

    return decorator

 

# 使用示例

@ai_diagnosis(api_key="sk-...")

def buggy_function():

    pass

```

 

---

 

### 五、**实时仪表盘装饰器**  

将运行数据推送至Web仪表盘(需 `websockets`)

```python

from websockets.sync.client import connect

import json

 

def live_dashboard(websocket_url):

    def decorator(func):

        @wraps(func)

        def wrapper(*args, **kwargs):

            start_time = time.time()

            mem_before = psutil.Process().memory_info().rss

            

            try:

                result = func(*args, **kwargs)

                status = "success"

            except Exception as e:

                status = f"error: {str(e)}"

                raise

            finally:

                data = {

                    "function": func.__name__,

                    "duration": time.time() - start_time,

                    "memory_delta": psutil.Process().memory_info().rss - mem_before,

                    "status": status,

                    "timestamp": datetime.now().isoformat()

                }

                

                with connect(websocket_url) as ws:

                    ws.send(json.dumps(data))

            

            return result

        return wrapper

    return decorator

 

# 使用示例(需配合前端展示)

@live_dashboard("ws://localhost:8000/dashboard")

def monitored_task():

    pass

```

 

---

 

### 六、**版本感知日志装饰器**  

自动记录代码版本和输入数据哈希

```python

import hashlib

import subprocess

 

def version_aware(func):

    @wraps(func)

    def wrapper(*args, **kwargs):

        # 获取Git版本

        try:

            git_version = subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode().strip()

        except:

            git_version = "unknown"

        

        # 计算输入参数哈希

        input_hash = hashlib.sha256()

        for arg in args:

            input_hash.update(str(arg).encode())

        for k, v in kwargs.items():

            input_hash.update(f"{k}={v}".encode())

        

        logging.info(f"🔖 CODE VERSION: {git_version[:8]}")

        logging.info(f"🔑 INPUT HASH: {input_hash.hexdigest()[:16]}")

        

        return func(*args, **kwargs)

    return wrapper

 

# 使用示例

@version_aware

def versioned_processing(data):

    pass

```

 

---

 

### 七、**量子化时间记录装饰器**  

发现隐藏的时间异常(适合高频交易等场景)

```python

import time

import numpy as np

from scipy import stats

 

def quantum_time_monitor(window_size=100):

    def decorator(func):

        history = []

        

        @wraps(func)

        def wrapper(*args, **kwargs):

            start = time.perf_counter_ns()

            result = func(*args, **kwargs)

            elapsed = time.perf_counter_ns() - start

            

            history.append(elapsed)

            if len(history) > window_size:

                history.pop(0)

                

                # 检测时间分布异常

                z_scores = np.abs(stats.zscore(history))

                if np.any(z_scores > 3):

                    logging.warning(f"⏱️ 时间异常! 当前值 {elapsed/1e6:.2f}ms, "

                                  f"均值 {np.mean(history)/1e6:.2f}ms ± {np.std(history)/1e6:.2f}ms")

            

            return result

        return wrapper

    return decorator

 

# 使用示例

@quantum_time_monitor()

def low_latency_trade():

    time.sleep(0.001 + random.random()*0.0001)

```

 

---

 

### **最佳实践组合方案**

1. **开发阶段**:  

   ```python

   @debug_tracer() # 详细错误追踪

   @memory_timeline # 内存分析

   @trace_execution # 参数追踪

   def critical_function():

       pass

   ```

 

2. **生产环境**:  

   ```python

   @adaptive_logger # 智能采样

   @version_aware # 版本追踪

   @quantum_time_monitor() # 性能监控

   def production_api():

       pass

   ```

 

3. **故障排查**:  

   ```python

   @live_dashboard("ws://monitor.example.com") # 实时监控

   @ai_diagnosis(API_KEY) # 智能诊断

   def troubleshooting():

       pass

   ```

 

---

 

这些方案可根据实际需求自由组合,建议先实施 **全链路追踪 + 智能动态采样** 作为基础监控层,再逐步添加 AI 诊断等高级功能。关键是要建立统一的日志分析平台(如 ELK 或 Grafana)来聚合所有装饰器产生的数据。

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

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

相关文章

贪心、动态规划、其它算法基本原理和步骤

目录 1. 贪心1.1 贪心算法的基本步骤1.2 贪心算法实战1.2.1 贪心的经典问题1.2.2 贪心解决数组与子序列问题1.2.3 贪心解决区间调度问题1.2.4 贪心解决动态决策问题1.2.5 贪心解决一些复杂场景应用 2. 动态规划2.1 动态规划的基本步骤和一些优化2.2 动态规划实战2.2.1 斐波那契…

python-各种文件(txt,xls,csv,sql,二进制文件)读写操作、文件类型转换、数据分析代码讲解

1.文件txt读写标准用法 1.1写入文件 要读取文件,首先得使用 open() 函数打开文件。 file open(file_path, moder, encodingNone) file_path:文件的路径,可以是绝对路径或者相对路径。mode:文件打开模式,r 代表以…

ctfshow-大赛原题-web702

因为该题没有理解到位,导致看wp也一直出错,特此反思一下。 参考yu22x师傅的文章 :CTFSHOW大赛原题篇(web696-web710)_ctfshow 大赛原题-CSDN博客 首先拿到题目: // www.zip 下载源码 我们的思路就是包含一个css文件,…

Triton(2)——Triton源码接结构

1 triton 3.0.0 源码结构 triton docs/:项目文档 cmake/:构建配置相关 bin/:工具、脚本 CmakeLists.txt:cmake 配置文件 LSCENSE README.md Pyproject.toml:python 项目配置文件 utils/:项目配置文…

容器docker入门学习

这里写目录标题 容器容器的软件厂商 dockerdocker引擎 虚拟化虚拟化技术 docker安装详解1、安装检查2、安装yum相关的工具3、安装docker-ce软件4、查看docker版本5、启动docker服务6、设置docker开机启动7、查看有哪些docker容器运行进程8、查看容器里有哪些镜像9、下载nginx软…

HarmonyOS NEXT开发教程:全局悬浮窗

今天跟大家分享一下HarmonyOS开发中的悬浮窗。 对于悬浮窗,可能有的同学会想到使用层叠布局是否可以实现,将悬浮窗叠在导航栏组件Tabs上,像这样: Stack({alignContent:Alignment.BottomEnd}){Tabs({barPosition:BarPosition.End…

解锁元生代:ComfyUI工作流与云原生后端的深度融合

目录 蓝耘元生代:智算新势力崛起​ ComfyUI 工作流创建详解​ ComfyUI 初印象​ 蓝耘平台上搭建 ComfyUI 工作流​ 构建基础工作流实操​ 代码示例与原理剖析​ 云原生后端技术全景 云原生后端概念解析​ 核心技术深度解读​ 蓝耘元生代中两者的紧密联系​…

STM32 基本GPIO控制

目录 GPIO基础知识 ​编辑IO八种工作模式 固件库实现LED点灯 蜂鸣器 按键基础知识 ​编辑继电器 震动传感器 433M无线模块 GPIO基础知识 GPIO(General-Purpose input/output,通用输入/输出接口) 用于感知外部信号(输入模式)和控制外部设备&…

汽车免拆诊断案例 | 2019款大众途观L车鼓风机偶尔不工作

故障现象 一辆2019款大众途观L车,搭载DKV发动机和0DE双离合变速器,累计行驶里程约为8万km。车主进厂反映,鼓风机偶尔不工作。 故障诊断  接车后试车,鼓风机各挡位均工作正常。用故障检测仪检测,空调控制单元&#x…

FastAPI与SQLAlchemy数据库集成

title: FastAPI与SQLAlchemy数据库集成 date: 2025/04/17 15:33:34 updated: 2025/04/17 15:33:34 author: cmdragon excerpt: FastAPI与SQLAlchemy的集成通过创建虚拟环境、安装依赖、配置数据库连接、定义数据模型和实现路由来完成。核心模块包括数据库引擎、会话工厂和声…

免费将静态网站部署到服务器方法(仅支持HTML,CSS,JS)

原视频链接:把HTML免费部署到网站上,实现别人也能访问的教程来啦QAQ_哔哩哔哩_bilibili 注意:仅支持HTML、CSS、JS。不支持Vue等框架。 1.打开网站www.wordpress.org 点击红框按钮 点击红框按钮下载wordpress模板文件并解压。 将自己编写的…

51单片机实验一:点亮led灯

目录 一、实验环境与实验器材 二、实验内容及实验步骤 1.用keil 软件创建工程,C文件编写程序,编译生成hex文件​编辑 2.用STC烧写hex文件,点亮第一个LED灯 3.使用法2,点除第一个以外的LED灯 一、实验环境与实验器材 环境&am…

PyCharm 开发工具 修改字体大小及使用滚轮没有反应

PyCharm 开发工具 修改字体大小及使用滚轮没有反应 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是PyCharm 开发工具。前后每一小节的内容是有学习/理解关联性,希望对您有用~ PyCharm 开发工具 修改字体大小…

zookeeper启动报错have small server identifier

解决方案: 1、查看myid是否有重复 2、查看server.X 与myid的X是否一致 3、启动顺序为myid从小到大的服务器顺序

1.Framer Motion 中 motion/react 和 motion/react-client 的用法和区别

背景知识:服务器端渲染 (SSR) 和客户端渲染 (CSR) 在最新的 Motion for React(原 Framer Motion)12.x 及更高版本中,官方提供了两个入口模块:motion/react 和 motion/react-client。二者对外 API 完全一致&#xff0c…

简易 Python 爬虫实现,10min可完成带效果源码

目录 准备工作 编写爬虫代码 运行爬虫 查看结果 遇到的问题及解决 总结 前言和效果 本文记录了使用 Python 实现一个简单网页爬虫的过程,目标是爬取 quotes.toscrape.com 的名言和作者,并将结果保存到文本文件。以下是完整步骤,包含环境…

【学习笔记】Py网络爬虫学习记录(更新中)

目录 一、入门实践——爬取百度网页 二、网络基础知识 1、两种渲染方式 2、HTTP解析 三、Request入门 1、get方式 - 百度搜索/豆瓣电影排行 2、post方式 - 百度翻译 四、数据解析提取三种方式 1、re正则表达式解析 (1)常用元字符 &#xff0…

旅游资源网站登录(jsp+ssm+mysql5.x)

旅游资源网站登录(jspssmmysql5.x) 旅游资源网站是一个为旅游爱好者提供全面服务的平台。网站登录界面简洁明了,用户可以选择以管理员或普通用户身份登录。成功登录后,用户可以访问个人中心,进行修改密码和个人信息管理。用户管理模块允许管…

C语言链接数据库

目录 使用 yum 配置 mysqld 环境 查看 mysqld 服务的版本 创建 mysql 句柄 链接数据库 使用数据库 增加数据 修改数据 查询数据 获取查询结果的行数 获取查询结果的列数 获取查询结果的列名 获取查询结果所有数据 断开链接 C语言访问mysql数据库整体源码 通过…

中间件--ClickHouse-9--MPP架构(分布式计算架构)

1、MPP 架构基础概念 MPP(Massively Parallel Processing 大规模并行处理) 是一种分布式计算架构,专门设计用来高效处理大规模数据集。在这种架构下*,数据库被分割成多个部分,每个部分可以在不同的服务器节点上并行处理*。这意味着&#xff…