Quarkus OpenTelemetry ParentBased采样器失效问题求助
我在Quarkus应用中使用OpenTelemetry的DropTargetsSampler过滤特定链路(/foo、/bar),但切换为ParentBased采样器后,子调用未按预期被过滤。相关代码如下:
@Produces @DefaultBean fun dropTargetsSampler(): Sampler { val dropTargets = listOf("/foo", "/bar") val rootSampler = DropTargetsSampler(Sampler.alwaysOn(), dropTargets) return Sampler.parentBasedBuilder(rootSampler) .setLocalParentSampled(Sampler.alwaysOn()) .setLocalParentNotSampled(Sampler.alwaysOff()) .setRemoteParentSampled(Sampler.alwaysOn()) .setRemoteParentNotSampled(Sampler.alwaysOff()) .build() }
调试时发现DropTargetsSampler始终使用AlwaysOnSampler,未考虑父子调用的过滤逻辑。预期DropTargetsSampler应基于ParentBased采样器的规则工作,但实际仅显示为AlwaysOn。请问这是配置错误还是存在Bug?
你的配置逻辑搞反了——应该让DropTargetsSampler作为ParentBased采样器各分支的判断依据,而非用ParentBased包裹DropTargetsSampler后给分支直接设置alwaysOn。
当前代码中,ParentBased的根采样器是DropTargetsSampler,但你给localParentSampled、remoteParentSampled等分支直接指定了alwaysOn采样器,这会导致存在父Span时,直接走这些分支的alwaysOn逻辑,完全跳过DropTargetsSampler的过滤规则,自然子调用不会被过滤。
正确的做法是让ParentBased的所有需要采样判断的分支都复用DropTargetsSampler,示例代码如下:
@Produces @DefaultBean fun dropTargetsSampler(): Sampler { val dropTargets = listOf("/foo", "/bar") // 先构建带过滤逻辑的基础采样器 val dropSampler = DropTargetsSampler(Sampler.alwaysOn(), dropTargets) // 让ParentBased的所有采样分支都应用过滤逻辑 return Sampler.parentBasedBuilder(dropSampler) .setLocalParentSampled(dropSampler) .setLocalParentNotSampled(Sampler.alwaysOff()) .setRemoteParentSampled(dropSampler) .setRemoteParentNotSampled(Sampler.alwaysOff()) .build() }
这样配置后,所有需要判断采样的场景(根Span、已采样的本地/远程父Span)都会经过DropTargetsSampler的过滤,子调用也会被正确处理。
另外需注意:检查DropTargetsSampler的匹配规则是否符合预期——它默认匹配的是Span名称还是URL?如果是URL,要确保Span的属性中包含对应的URL字段,否则过滤逻辑不会生效。
内容的提问来源于stack exchange,提问作者ethan

