Skip to content

feat(local): surface trace IDs, attribute table, and fix AI filter#1133

Merged
MathurAditya724 merged 3 commits into
mainfrom
issue-1132-local-output
Jun 24, 2026
Merged

feat(local): surface trace IDs, attribute table, and fix AI filter#1133
MathurAditya724 merged 3 commits into
mainfrom
issue-1132-local-output

Conversation

@jared-outpost

@jared-outpost jared-outpost Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Improves sentry local serve output so events are easier to correlate and scan, and fixes -f ai missing GenAI activity that lives on child spans.

  • Trace IDs: error/transaction/log tail lines now carry a short [trace:…] token, and JSON output includes trace_id (logs read it from the sentry.trace.trace_id attribute) — lets humans and agents group related events.
  • Attribute table: new --attributes/-a flag renders an indented, aligned table grouped into user-custom vs SDK-default sections, sorted by key. JSON exposes the same split under attributes.{user,sdk}.
  • AI filter fix: -f ai previously only checked trace-root attributes, so Vercel-AI-style transactions (POST /api/ai/chat) where gen_ai.* lives on child spans were missed. The filter now scans child span attributes too.
  • User log attributes are rendered alphabetically so repeated lines align column-for-column.

Testing

bun run lint, tsc --noEmit, and the formatter/local test suites (920 formatter tests + local command tests) all pass. Added tests for the AI child-span filter, trace ID extraction/rendering across human + JSON output, log attribute ordering, and collectSpanAttributes.

Closes #1132

Improve `sentry local serve` output so events are easier to correlate
and scan, and make `-f ai` catch GenAI activity on child spans.

- Surface a short `[trace:…]` token on error, transaction, and log tail
  lines, and add `trace_id` to JSON output (logs read it from the
  `sentry.trace.trace_id` attribute). Lets agents group related events.
- Add `--attributes`/`-a` to render an indented, aligned attribute table
  grouped into user-custom vs SDK-default sections, sorted by key. JSON
  output exposes the same split under `attributes.{user,sdk}`.
- Fix `-f ai` missing Vercel-AI-style transactions: `gen_ai.*` attributes
  live on child spans of the HTTP handler, not the trace root, so the
  filter now scans child span attributes too.
- Render user log attributes alphabetically so repeated lines align.

Fixes #1132
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-1133/

Built to branch gh-pages at 2026-06-23 22:47 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

✅ Patch coverage is 92.08%. Project has 5053 uncovered lines.
✅ Project coverage is 81.4%. Comparing base (base) to head (head).

Files with missing lines (2)
File Patch % Lines
src/lib/formatters/local.ts 93.98% ⚠️ 5 Missing and 3 partials
src/commands/local/server.ts 0.00% ⚠️ 3 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    81.35%    81.40%    +0.05%
==========================================
  Files          392       392         —
  Lines        27070     27160       +90
  Branches     17566     17617       +51
==========================================
+ Hits         22019     22107       +88
- Misses        5051      5053        +2
- Partials      1832      1832         —

Generated by Codecov Action

@jared-outpost jared-outpost Bot marked this pull request as ready for review June 23, 2026 20:03
@jared-outpost jared-outpost Bot requested a review from MathurAditya724 June 23, 2026 20:03
@jared-outpost

jared-outpost Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Marked ready — CI is green: Build, Unit Tests, E2E, Lint & Typecheck, CodeQL, semgrep, and secret scan all passed. Self-review turned up nothing to fix. @MathurAditya724 requested for review since you filed #1132.

@jared-outpost

jared-outpost Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Not enabling auto-merge — this exceeds the small-change gate (716 lines / 6 files changed, plus new public API surface: the --attributes flag and exported formatAttributeTable). Leaving it for human review by @MathurAditya724 / a maintainer.

@MathurAditya724 MathurAditya724 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this against #1132. This is a good direction and CI is green, but I don't think it's ready to merge yet because the -f ai fix is still incomplete.

Blocking finding:

  • src/lib/formatters/local.ts:844-855 detects AI activity on child spans only by calling inferSemanticOp(spanAttrs). inferSemanticOp only returns gen_ai for gen_ai.operation.name, gen_ai.tool.name, or gen_ai.agent.name (src/lib/formatters/semantic-display.ts:121-129). Other GenAI attributes that this same formatter already treats as GenAI display inputs, such as gen_ai.request.model, gen_ai.response.model, gen_ai.provider.name, gen_ai.data_source.id, and gen_ai.usage.*, can still be missed by -f ai when they live only on child spans. Since the linked issue describes missing gen_ai.* child-span data, the filter should detect GenAI/MCP by semantic key prefix or align inferSemanticOp with the GenAI display formatter.

Non-blocking risks:

  • src/lib/formatters/local.ts:330-350 omits several semantic/instrumentation namespaces already recognized elsewhere, including graphql., aws.s3., cloudevents., feature_flag., process., and error.. Those will be shown as user attributes, which weakens the claimed SDK-default vs user-custom split.
  • src/lib/formatters/local.ts:391-406 flattens all child span attributes into one map, so duplicate keys across child spans silently overwrite earlier values. That may hide multiple AI calls/models/token counts in one transaction.

I would add a regression test where -f ai matches a transaction whose child span has only gen_ai.request.model or gen_ai.usage.input_tokens and no gen_ai.operation.name/tool/agent key.

The -f ai filter relied on inferSemanticOp, which only flags gen_ai for
gen_ai.operation.name/tool/agent keys. Spans carrying only
gen_ai.request.model or gen_ai.usage.* (e.g. Vercel AI generations) were
missed. Detect the full gen_ai.*/mcp.* namespace by key prefix instead.

Also widen SDK_ATTRIBUTE_PREFIXES to cover graphql., aws.s3.,
cloudevents., feature_flag., process., and error. namespaces so the
attribute-table SDK/user split matches the semantic display formatter.
@github-actions github-actions Bot added the risk: high PR risk score: high label Jun 23, 2026
@jared-outpost

jared-outpost Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 4741e5e addressing the review.

Blocking finding (fixed): transactionHasAiActivity no longer relies on inferSemanticOp. It now detects AI activity by matching the full gen_ai.*/mcp.* namespace via key prefix (new hasAiAttributes in semantic-display.ts), so a child span carrying only gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.provider.name, etc. is matched even without an operation.name/tool/agent key. Added regression tests for the gen_ai.request.model-only and gen_ai.usage.input_tokens-only child-span cases (plus a gen_ai.provider.name-only trace root).

Non-blocking #1 (fixed): widened SDK_ATTRIBUTE_PREFIXES to include graphql., aws.s3., cloudevents., feature_flag., process., and error. so the attribute-table SDK/user split lines up with what the semantic display formatter recognizes.

Non-blocking #2 (won't fix here): the child-span attribute flattening in collectAllAttributes does collapse duplicate keys across spans. That's a deliberate tradeoff for a top-level scan — the table is meant to summarize, not enumerate every span. Preserving per-span values would change the JSON envelope shape (attributes.{user,sdk} -> per-span arrays) and is a larger design call I'd rather not bundle into this fix. Happy to open a follow-up if you'd prefer per-span breakdown.

@jared-outpost jared-outpost Bot requested a review from MathurAditya724 June 23, 2026 22:32
Comment thread src/lib/formatters/local.ts
formatLogJson sanitized log attribute values but passed keys through raw,
so C1 controls or BiDi overrides in envelope-supplied attribute key names
survived JSON.stringify and could drive terminal injection. Apply
stripBidi() to the key, matching buildJsonAttributes.

@MathurAditya724 MathurAditya724 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the latest head (916d2007) against my previous findings.

The blocking -f ai issue is fixed: transactionHasAiActivity now uses prefix-based hasAiAttributes detection for gen_ai.*/mcp.*, so child spans with only gen_ai.request.model or gen_ai.usage.input_tokens are included. The added regression tests cover those cases. The SDK/user attribute grouping concern was also addressed by widening SDK_ATTRIBUTE_PREFIXES.

The remaining child-span attribute flattening behavior is a reasonable non-blocking tradeoff for this PR. CI is green. No remaining blocking findings from me.

@MathurAditya724 MathurAditya724 merged commit 53784d5 into main Jun 24, 2026
30 checks passed
@MathurAditya724 MathurAditya724 deleted the issue-1132-local-output branch June 24, 2026 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve sentry local output: trace ID, attributes, filter

1 participant