2026-07-02 03:22:12 +08:00
|
|
|
|
"""追踪 DTO。
|
|
|
|
|
|
|
|
|
|
|
|
定义链路追踪相关的值对象,包括追踪 ID、请求 ID、Span ID、Span、
|
|
|
|
|
|
Span 状态与追踪上下文。除 Span 外的 DTO 均为 ``dataclass(frozen=True)``,
|
|
|
|
|
|
Span 为 ``frozen=False`` 以支持 ``endSpan`` 回填状态,仅依赖标准库,用于
|
|
|
|
|
|
跨层传递追踪信息以支持可观测性与审计。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
from enum import StrEnum
|
|
|
|
|
|
from typing import Any
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
from yuxi.channels.contract.errors import ValidationError
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class TraceId:
|
|
|
|
|
|
"""追踪 ID。
|
|
|
|
|
|
|
|
|
|
|
|
标识一次完整链路追踪的全局唯一 ID,跨多个 Span 共享,用于聚合同一次
|
|
|
|
|
|
请求的全部日志与指标。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
value: 追踪 ID 字符串。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
value: str
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
|
"""校验 value 非空。
|
|
|
|
|
|
|
|
|
|
|
|
``value`` 必须非空,在构造时即抛出 ``ValidationError``,避免空追踪
|
|
|
|
|
|
ID 导致链路聚合失效(INV-8)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.value:
|
|
|
|
|
|
raise ValidationError("value", "must not be empty")
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class RequestId:
|
|
|
|
|
|
"""请求 ID。
|
|
|
|
|
|
|
|
|
|
|
|
标识一次外部请求的唯一 ID,用于审计日志与请求级别关联,区别于链路
|
|
|
|
|
|
追踪 ID(多次请求可能共享同一 TraceId)。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
value: 请求 ID 字符串。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
value: str
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
|
"""校验 value 非空。
|
|
|
|
|
|
|
|
|
|
|
|
``value`` 必须非空,在构造时即抛出 ``ValidationError``,避免空请求
|
|
|
|
|
|
ID 导致审计日志关联失效(INV-8)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.value:
|
|
|
|
|
|
raise ValidationError("value", "must not be empty")
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class SpanId:
|
|
|
|
|
|
"""Span ID。
|
|
|
|
|
|
|
|
|
|
|
|
标识链路追踪中单个 Span 的唯一 ID,用于定位链路中的具体操作节点。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
value: Span ID 字符串。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
value: str
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
|
"""校验 value 非空。
|
|
|
|
|
|
|
|
|
|
|
|
``value`` 必须非空,在构造时即抛出 ``ValidationError``,避免空 Span
|
|
|
|
|
|
ID 导致链路节点定位失效(INV-8)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.value:
|
|
|
|
|
|
raise ValidationError("value", "must not be empty")
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
class SpanStatus(StrEnum):
|
|
|
|
|
|
"""Span 状态。
|
|
|
|
|
|
|
|
|
|
|
|
标识 Span 的执行结果状态,用于追踪数据聚合与异常归因。继承
|
|
|
|
|
|
``str, Enum`` 以支持 JSON 序列化与字符串比较。
|
|
|
|
|
|
|
|
|
|
|
|
取值:
|
|
|
|
|
|
OK: 执行成功。
|
|
|
|
|
|
ERROR: 执行失败。
|
|
|
|
|
|
UNSET: 未设置(待补充)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
OK = "ok"
|
|
|
|
|
|
ERROR = "error"
|
|
|
|
|
|
UNSET = "unset"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=False)
|
|
|
|
|
|
class Span:
|
|
|
|
|
|
"""Span。
|
|
|
|
|
|
|
|
|
|
|
|
描述链路追踪中的一个操作节点,关联追踪 ID 与父 Span,记录操作名称与
|
|
|
|
|
|
起始时间,用于构建调用链路拓扑。``frozen=False`` 以支持 ``endSpan``
|
|
|
|
|
|
回填状态、错误信息与结束时间。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
span_id: 当前 Span ID。
|
|
|
|
|
|
trace_id: 所属追踪 ID。
|
|
|
|
|
|
parent_span_id: 父 Span ID(根 Span 为 None)。
|
|
|
|
|
|
name: Span 名称(操作标识)。
|
|
|
|
|
|
started_at: Span 起始时间。
|
|
|
|
|
|
status: Span 执行状态(默认 UNSET,endSpan 时回填)。
|
|
|
|
|
|
error: 错误信息(异常时填充,默认 None)。
|
|
|
|
|
|
ended_at: Span 结束时间(endSpan 时回填,默认 None)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
span_id: SpanId
|
|
|
|
|
|
trace_id: TraceId
|
|
|
|
|
|
parent_span_id: SpanId | None
|
|
|
|
|
|
name: str
|
|
|
|
|
|
started_at: datetime
|
|
|
|
|
|
status: SpanStatus = SpanStatus.UNSET
|
|
|
|
|
|
error: dict[str, Any] | None = None
|
|
|
|
|
|
ended_at: datetime | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class TraceContext:
|
|
|
|
|
|
"""追踪上下文。
|
|
|
|
|
|
|
|
|
|
|
|
跨层传递的追踪上下文,携带当前 Span 与采样标记,用于在管道各环节
|
|
|
|
|
|
保持链路连续性并控制采样开销。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
trace_id: 所属追踪 ID。
|
|
|
|
|
|
span_id: 当前 Span ID。
|
|
|
|
|
|
parent_span_id: 父 Span ID(根 Span 为 None)。
|
|
|
|
|
|
sampled: 是否采样(默认 False)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
trace_id: TraceId
|
|
|
|
|
|
span_id: SpanId
|
|
|
|
|
|
parent_span_id: SpanId | None = None
|
|
|
|
|
|
sampled: bool = False
|