"""追踪 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 from yuxi.channels.contract.errors import ValidationError @dataclass(frozen=True) class TraceId: """追踪 ID。 标识一次完整链路追踪的全局唯一 ID,跨多个 Span 共享,用于聚合同一次 请求的全部日志与指标。 字段: value: 追踪 ID 字符串。 """ value: str def __post_init__(self) -> None: """校验 value 非空。 ``value`` 必须非空,在构造时即抛出 ``ValidationError``,避免空追踪 ID 导致链路聚合失效(INV-8)。 """ if not self.value: raise ValidationError("value", "must not be empty") @dataclass(frozen=True) class RequestId: """请求 ID。 标识一次外部请求的唯一 ID,用于审计日志与请求级别关联,区别于链路 追踪 ID(多次请求可能共享同一 TraceId)。 字段: value: 请求 ID 字符串。 """ value: str def __post_init__(self) -> None: """校验 value 非空。 ``value`` 必须非空,在构造时即抛出 ``ValidationError``,避免空请求 ID 导致审计日志关联失效(INV-8)。 """ if not self.value: raise ValidationError("value", "must not be empty") @dataclass(frozen=True) class SpanId: """Span ID。 标识链路追踪中单个 Span 的唯一 ID,用于定位链路中的具体操作节点。 字段: value: Span ID 字符串。 """ value: str def __post_init__(self) -> None: """校验 value 非空。 ``value`` 必须非空,在构造时即抛出 ``ValidationError``,避免空 Span ID 导致链路节点定位失效(INV-8)。 """ if not self.value: raise ValidationError("value", "must not be empty") 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