一個簡單的分布式追蹤系統

1. 準備工作

導入必要的庫

import contextvars
import time
from typing import Any, Optional, Dict, List, Union
from dataclasses import dataclass, field

2. 定義上下文變量

# 定義兩個上下文變量,存儲當前 Span 和 Trace
_current_span: contextvars.ContextVar[Optional["Span"]] = contextvars.ContextVar("current_span", default=None
)_current_trace: contextvars.ContextVar[Optional["Trace"]] = contextvars.ContextVar("current_trace", default=None
)

3. 數據模型定義

3.1 SpanContext 類

@dataclass
class SpanContext:"""Span 的上下文信息(用于跨進程傳遞)"""trace_id: strspan_id: stris_remote: bool = False

3.2 Span 類

@dataclass
class Span:"""表示一個操作的時間段追蹤"""name: strcontext: SpanContextparent: Optional["Span"] = Nonestart_time: float = field(default_factory=time.time)end_time: Optional[float] = Noneattributes: Dict[str, Any] = field(default_factory=dict)events: List[Dict[str, Any]] = field(default_factory=list)status: str = "UNSET"def end(self, status: str = "OK") -> None:"""結束 Span 并記錄狀態"""self.end_time = time.time()self.status = statusdef add_event(self, name: str, attributes: Optional[Dict[str, Any]] = None) -> None:"""添加事件到 Span"""self.events.append({"name": name,"timestamp": time.time(),"attributes": attributes or {}})def __enter__(self) -> "Span":"""支持 with 語句"""return selfdef __exit__(self, exc_type, exc_val, exc_tb) -> None:"""自動結束 Span"""self.end("ERROR" if exc_type else "OK")

3.3 Trace 類

@dataclass
class Trace:"""完整的追蹤鏈"""root_span: Spanspans: List[Span] = field(default_factory=list)def add_span(self, span: Span) -> None:"""添加 Span 到 Trace"""self.spans.append(span)

4. 追蹤 API 實現

4.1 輔助函數

def generate_id() -> str:"""生成追蹤ID(簡化版)"""return f"id-{int(time.time() * 1000)}"def get_current_span() -> Optional[Span]:"""獲取當前 Span"""return _current_span.get()def get_current_trace() -> Optional[Trace]:"""獲取當前 Trace"""return _current_trace.get()

4.2 核心函數

def start_span(name: str, attributes: Optional[Dict[str, Any]] = None) -> Span:"""創建并激活一個新 Span:param name: Span 名稱:param attributes: 附加屬性:return: 新創建的 Span"""parent = get_current_span()context = SpanContext(trace_id=parent.context.trace_id if parent else generate_id(),span_id=generate_id())span = Span(name=name, context=context, parent=parent)if attributes:span.attributes.update(attributes)# 設置當前 Span_current_span.set(span)# 如果是根 Span,則創建 Traceif parent is None:trace = Trace(root_span=span)_current_trace.set(trace)else:trace = get_current_trace()if trace:trace.add_span(span)return spandef end_span(status: str = "OK") -> None:"""結束當前 Span 并返回父 Span"""current = get_current_span()if current:current.end(status)_current_span.set(current.parent)

5. 數據導出器

class ConsoleExporter:"""將追蹤數據打印到控制臺"""@staticmethoddef export(trace: Trace) -> None:print("\n=== Exporting Trace ===")print(f"Trace ID: {trace.root_span.context.trace_id}")for span in trace.spans:duration = (span.end_time or time.time()) - span.start_timeprint(f"Span: {span.name} ({duration:.3f}s), Status: {span.status}")

6. 使用示例

6.1 同步代碼示例

# 示例 1: 同步代碼
with start_span("main_operation", {"type": "sync"}):# 當前 Span 是 "main_operation"with start_span("child_operation"):# 當前 Span 是 "child_operation"get_current_span().add_event("processing_start")time.sleep(0.1)get_current_span().add_event("processing_end")# 手動創建 Spanspan = start_span("manual_span")time.sleep(0.05)span.end()# 導出追蹤數據
if trace := get_current_trace():ConsoleExporter.export(trace)

=== Exporting Trace ===
Trace ID: id-1751643441896
Span: main_operation (0.152s), Status: OK
Span: child_operation (0.101s), Status: OK
Span: manual_span (0.050s), Status: OK

6.2 異步代碼示例(可選)

import asyncioasync def async_task():with start_span("async_operation"):print(f"Current span: {get_current_span().name}")await asyncio.sleep(0.1)async def main():tasks = [async_task() for _ in range(3)]await asyncio.gather(*tasks)# 運行異步示例
asyncio.run(main())

Current span: async_operation
Current span: async_operation
Current span: async_operation

7. 可視化追蹤數據(可選)

import matplotlib.pyplot as pltdef visualize_trace(trace: Trace):fig, ax = plt.subplots(figsize=(10, 6))for i, span in enumerate(trace.spans):duration = (span.end_time or time.time()) - span.start_timeax.barh(span.name, duration, left=span.start_time, alpha=0.6)ax.text(span.start_time, i, f"{duration:.3f}s", va='center')ax.set_xlabel('Time')ax.set_title('Trace Visualization')plt.show()if trace := get_current_trace():visualize_trace(trace)

在這里插入圖片描述
代碼:https://github.com/zhouruiliangxian/Awesome-demo/blob/main/Distributed-Tracing/%E7%AE%80%E6%98%93%E5%88%86%E5%B8%83%E5%BC%8F%E8%BF%BD%E8%B8%AA%E7%B3%BB%E7%BB%9F.ipynb

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/913114.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/913114.shtml
英文地址,請注明出處:http://en.pswp.cn/news/913114.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Qt】事件處理、事件分發器、事件過濾器

事件處理 一. 事件事件處理鼠標事件處理按鍵事件處理定時器事件處理窗口事件處理 二. 事件分發器三. 事件過濾器 雖然 Qt 是跨平臺的 C 開發框架,Qt 的很多能力其實是操作系統提供的,只不過 Qt 封裝了系統 API,程序是運行在操作系統上的&…

廣東省省考備考(第三十八天7.4)——言語理解:邏輯填空(題目訓練)

錯題解析 本題可從第二空入手,橫線處搭配“理論”,且根據“使得”可知,橫線處與前文構成因果關系,即“遺傳學的空白和古生物證據的缺乏”導致他的理論在某些方面存在不足,A項“捉襟見肘”指拉一拉衣襟,就露…

5G網絡切片技術

5G中的網絡切片技術是一種通過虛擬化將單一物理網絡劃分為多個獨立、可定制的虛擬網絡的技術,旨在滿足不同應用場景對網絡性能、帶寬、時延等需求的差異化要求。以下從技術原理、核心價值、應用場景、實現方式及未來趨勢五個維度展開分析:一、技術原理&a…

算法學習筆記:7.Dijkstra 算法——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在計算機科學領域,圖論算法一直占據著重要地位,其中 Dijkstra 算法作為求解單源最短路徑問題的經典算法,被廣泛應用于路徑規劃、網絡路由等多個場景。無論是算法競賽、實際項目開發,還是計算機考研 408 的備考,Dijkstr…

匯編 函數調用棧

前言 網上很多對函數棧的解釋,說的不是很清楚感覺,尤其是對到底是誰的棧,以及指令的微小但是很致命的細節沒說,特寫本文,一是幫助自己記憶,二是為了幫助大家,如有疏忽錯誤請指正。 核心概念 首先…

基于Apache MINA SSHD配置及應用

Apache MINA SSHD 是一個基于 Java 的 SSH 服務器和客戶端實現,它是 Apache MINA 項目的一部分,提供了完整的 SSH 協議支持。 主要特性 SSH 協議支持: 支持 SSH2 協議 兼容大多數 SSH 客戶端 支持多種加密算法和密鑰交換方法 服務器功能…

Excel 如何讓數據自動按要求排序或篩選?

讓數據按要求排序和篩選是Excel數據處理的基礎核心功能,也是進行有效分析前必做的準備工作。下面我們分開講解這兩個功能。 一、排序 (Sort):讓數據井井有條 排序的目的是重新排列數據行的順序,以便更好地觀察和比較。 1. 快速單列排序 (最…

Django 安裝使用教程

一、Django 簡介 Django 是一個高級 Python Web 框架,鼓勵快速開發和簡潔實用的設計。它內置 ORM、認證系統、后臺管理、表單處理、路由控制等功能,廣泛用于開發企業級網站、內容管理系統、電商平臺等。 二、環境準備 2.1 安裝 Python Django 基于 Py…

前沿交叉:Fluent與深度學習驅動的流體力學計算體系

基礎模塊 流體力學方程求解 1、不可壓縮N-S方程數值解法(有限差分/有限元/偽譜法) Fluent工業級應用:穩態/瞬態流、兩相流仿真(圓柱繞流、入水問題) Tecplot流場可視化與數據導出 2、CFD數據的AI預處理 基于P…

五、Flutter動畫

目錄1. Flutter 中動畫的基本概念是什么?2. 解釋 AnimationController 和 Tween 的作用3. 如何實現一個補間(Tween)動畫?4. 什么是隱式動畫?舉例說明5. 如何實現自定義復雜動畫?1. Flutter 中動畫的基本概念…

全網唯一/Qt結合ffmpeg實現手機端采集攝像頭推流到rtsp或rtmp/可切換前置后置攝像頭/指定分辨率幀率

一、前言說明 之前已經實現了Qt結合ffmpeg在安卓上運行,所有在win上的功能,在安卓上都已經實現,比如編碼保存到MP4文件,正常解碼音視頻文件播放等,唯獨還差一個功能,盡管用的不多,但是還是有一…

Install Ubuntu 24.04 System

1.制作安裝鏡像盤(U盤) 下載rufus制作工具(網址:https://www.xiaomoxz.com/nexus/bi1/rufus4.shtml?bd_vid8643969197265870719) 2. 設置U盤啟動: F2進入BIOS 3. Install Ubuntu 24.04 Ubuntu下載地址:…

solidjs 處理復雜類型的響應式

solidjs 處理復雜類型的響應式 在 solidjs 里響應式一般直接用 createSignal 就可以,但 createSignal 一般用于基礎數據類型。 雖然復雜類型也是可以使用,但基于起細粒度響應性的特性。 一般復雜的數據使用 createSignal 就不是那么友好了。 所以 cre…

爬蟲技術-獲取瀏覽器身份認證信息(如 Cookie、Token、Session 等)

方法一:通過瀏覽器開發者工具查看和提取 Cookie / Token 📌 示例場景: 你在使用一個網站時已經登錄了,想看看這個網站是如何保存你的身份憑證的。 🔧 操作過程: 打開瀏覽器(例如 Chrome&#xf…

[密碼學實戰]GMT 0136-2024《密碼應用HTTP接口規范》解析

[密碼學實戰]GM/T 0136-2024《密碼應用HTTP接口規范》解析國家密碼管理局于2025年7月1日正式實施GM/T 0136-2024標準,該規范首次統一了密碼服務的HTTP接口設計,為國產密碼技術的規模化應用鋪平道路。本文結合標準原文,深入剖析其技術細節并給…

Docker 國內鏡像列表(免費長期)

Docker 可用鏡像源列表(7月1日更新-長期維護)_dockerhub國內鏡像源列表-CSDN博客

BlenderFBXExporter 導出fbx被修改問題

1) 解決增加A節點的問題 https://github.com/A-Ribeiro/CustomBlenderFBXExporter 2)找出blendshape 不一致,生成blendshape key name映射map 文件compare.txt C:\Users\49938\Documents\DazToUnreal\zhang01\UpdatedFBX\zhang01_fix7.fbx…

AI時代下的IT服務管理轉型:趨勢、挑戰與破局之道

近年來,人工智能(AI)與自動化技術的迅猛發展,正以前所未有的速度重塑企業運營的各個層面。特別是在IT服務管理(ITSM)領域,AI的介入不僅提高了問題響應效率,也推動了組織從“被動響應…

三體融合實戰:Django+訊飛星火+Colossal-AI的企業級AI系統架構

目錄 技術棧關鍵詞:Django 5.0 訊飛星火4.0Ultra Colossal-AI 1.2 WebSocket 聯邦學習 ? 核心架構設計 🛠? 一、Django深度集成訊飛星火API(免費版) 1. 獲取API憑證 2. 流式通信改造(解決高并發阻塞&#xff09…

多模態數據融合預警:從IoT傳感器到衛星監測的可視化方案升級

你有沒有想過,為什么有些城市在暴雨來臨時能提前數小時發布內澇預警,而有些地方卻只能“等水來了才反應”? 背后的關鍵,就是多模態數據融合預警系統——它把來自IoT傳感器、無人機、地面雷達、氣象站、甚至衛星的數據整合在一起&a…