Fix span_name signal trigger not matching spans from previous batches#1621
Conversation
The span_name filter in signal trigger evaluation only checked spans in the current processing batch, missing spans that arrived in earlier batches. When a child span (e.g. "GitHub") arrived before the root span, the trigger would never fire: the first batch lacked root_span_finished, and the second batch lacked the child span name. Fix: also check the accumulated span_names from the database trace record, which merges span names across all batches via JSONB || on upsert. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Greptile SummaryThis PR fixes a bug where the Key points:
Confidence Score: 5/5Safe to merge — targeted, correct bug fix with comprehensive tests and no new risk vectors. The change is minimal and surgical: one OR-clause added to a single filter branch, three unit tests that directly validate the bug scenario and edge cases. The potential re-fire concern from persistent span_names is already mitigated by the pre-existing 1-hour cache lock in check_and_push_signals. The RETURNING-based upsert ensures the accumulated state is authoritative before filter evaluation. No security, data-loss, or reliability regressions identified. No files require special attention.
|
| Filename | Overview |
|---|---|
| app-server/src/db/trace.rs | Adds accumulated span_names check to span_name filter evaluation and three unit tests; logic is correct and deduplication is handled upstream by the existing signal trigger lock. |
Reviews (1): Last reviewed commit: "Fix span_name signal trigger not matchin..." | Re-trigger Greptile
|
This comment is an automated summary/review from the Greptile bot, not a change request. It gives the PR a 5/5 confidence score and concludes "Safe to merge" with no issues identified and no files requiring special attention. There are no actionable code changes requested — it's purely an informational summary of the PR's correctness. No changes needed. |
Summary
span_namefilter inevaluate_single_filternow also checks the accumulatedspan_namesfrom the database trace record (merged across all batches via JSONB||on upsert), in addition to the current batch's spans.Root cause
Spans arrive at the app-server in batches.
check_and_push_signals()runs after each batch is processed. Thespan_namefilter was only scanning the rawspansarray from the current batch:When child span "GitHub" arrived in batch 1 and the root span in batch 2:
root_span_finished= false (no root yet) → trigger skippedroot_span_finished= true, but "GitHub" not in this batch → trigger skippedThe fix checks the DB-accumulated
span_names(which merges names from all batches):Test plan
cargo checkpassescargo test --bin app-server db::trace::teststest_span_name_filter_uses_accumulated_db_span_names— the exact bug scenariotest_span_name_filter_matches_current_batch— regression: same-batch still workstest_span_name_ne_filter_with_accumulated_names— Ne operator correctness🤖 Generated with Claude Code
Note
Medium Risk
Moderate risk because it changes signal trigger evaluation semantics in the Rust backend, potentially affecting when/which signals fire; logic is straightforward and covered by new unit tests.
Overview
Fixes
span_namesignal trigger filters to consider DB-accumulated span names (traces.span_names) in addition to spans from the current processing batch, so triggers can fire when relevant spans arrive in different batches.Adds unit tests for cross-batch matching, same-batch regression, and
Neoperator behavior, and documents the trigger evaluation flow and batch/DB considerations inCLAUDE.md.Reviewed by Cursor Bugbot for commit fae96b0. Bugbot is set up for automated code reviews on this repo. Configure here.