Skip to content

feat(telemetry): per-stage review spans for stage-level observability - #103

Merged
mountainowl merged 2 commits into
mainfrom
feat/review-stage-spans
Jun 16, 2026
Merged

feat(telemetry): per-stage review spans for stage-level observability#103
mountainowl merged 2 commits into
mainfrom
feat/review-stage-spans

Conversation

@mountainowl

Copy link
Copy Markdown
Owner

Makes bubo emit richer observability data, not an observability tool — exactly the ask: bubo provides the metrics/traces; you bring Prometheus/Grafana/Tempo/Honeycomb/whatever.

What

Each review is one trace. llm_review.run now has a child span per stage, so a trace shows where the wall-clock actually went (spoiler: it's the agent, not bubo):

llm_review.run                  repo, mr_iid, sha, run_id
├─ llm_review.checkout          repo, sha
├─ llm_review.provenance        repo            (only when governance is on)
├─ llm_review.agent             repo, model, tokens_input/output/total, cost_usd, exit_code
└─ llm_review.post              repo, dry_run, findings_posted/planned/skipped

So any OTel backend can break latency, tokens, and cost down by stage and by model without bubo shipping a dashboard.

How

  • ReviewTelemetry.span now uses start_as_current_span, so nested span() calls become real children (was start_span, which left them as siblings). Disabled-noop and exception-propagation behavior preserved.
  • New set_span_attrs(span, **attrs) helper (mirrors add_event).
  • The worker wraps each stage in a child span; the agent/post spans get token/cost/count attributes.
  • No new dependency (existing OTel SDK), no-op when telemetry is off (the default), zero behavior change to the review itself.

Verify

416 tests pass, incl. a new in-memory-exporter test asserting the agent span is a child of the run span and carries its attributes. ruff + mypy + mkdocs --strict clean; cz valid; no footer. docs/telemetry.md gains a span-tree section.

Note: trivial CHANGELOG [Unreleased] overlap with the open docs PR #100 — keep both bullets.

mountainowl and others added 2 commits June 16, 2026 14:52
Make `ReviewTelemetry.span` context-propagating (start_as_current_span) so
nested spans form a real trace tree, and wrap each worker stage in a child
span under llm_review.run: checkout, provenance, agent, post. The agent span
carries token/cost/exit attributes; the post span carries posted/planned/
skipped counts. New `set_span_attrs` helper. No new dependency and a no-op when
telemetry is off — Bubo emits richer observability *data* (latency/tokens/cost
by stage + model) for any OTel backend to consume; it doesn't ship a dashboard.
Adds an in-memory-exporter test asserting child-of-run nesting + attributes;
docs/telemetry.md gains a span-tree section.
@mountainowl
mountainowl merged commit d871f30 into main Jun 16, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant