功能说明
该示例实现尾部采样决策:与头部采样在结果未知时下注不同,它看到整条链路的全部 span 后再判断。策略优先保留含错误的链路,其次保留耗时超过阈值的慢链路,最后对普通链路按兜底比例随机保留。返回带有决策原因,便于统计各类别的保留比例。
关键代码
Span 记录名称、时长与错误标志;Policy 集中可调阈值与开关。决策按优先级短路:空链路直接丢弃;开启错误保留且有任一 span 出错即保留;取全链路最大耗时与慢阈值比较;否则按兜底比例抽样。随机源可注入,测试时传入固定种子的 Random 即可得到可复现的决策,避免断言依赖真实随机。
使用注意
该函数假定调用方已经收齐同一链路的全部 span;若 span 分散在不同节点,必须先按 trace id 路由到同一决策点,否则决策基于不完整信息。真实实现还需环形缓冲与超时:等待窗口过短会漏掉慢链路,过长会占用大量内存。被保留或被丢弃都应计入采样率,使下游能正确加权统计,否则保留偏差会扭曲聚合指标。
代码示例
from dataclasses import dataclass, field
import random
@dataclass
class Span:
name: str
duration_ms: float
error: bool = False
@dataclass
class Policy:
slow_ms: float = 500.0
keep_errors: bool = True,
fallback_rate: float = 0.01
def decide(spans: list['Span'], policy: Policy, rng: random.Random | None = None) -> tuple[bool, str]:
rng = rng or random.Random()
if not spans:
return False, 'empty'
if policy.keep_errors and any(s.error for s in spans):
return True, 'error'
slowest = max(s.duration_ms for s in spans)
if slowest >= policy.slow_ms:
return True, 'slow'
if rng.random() < policy.fallback_rate:
return True, 'sampled'
return False, 'dropped'