Skip to content

fix: emit populate telemetry for new aggregates (stream_not_found) - #58

Merged
yordis merged 1 commit into
mainfrom
otel-es-read
Mar 13, 2026
Merged

yordis merged 1 commit into
mainfrom
otel-es-read

Conversation

@yordis

@yordis yordis commented Mar 12, 2026 •

Copy link
Copy Markdown
Member

Summary

Emit commanded.aggregate.populate telemetry for all aggregate loads, including new aggregates where stream_forward returns {:error, :stream_not_found}. Previously the span only fired when events were consumed, leaving a gap in traces for new aggregate commands.

Changes

  • Move populate telemetry from rebuild_from_event_stream to wrap the entire rebuild_from_events flow
  • stream_not_found: span fires with count: 0 (captures stream lookup latency)
  • Existing aggregates: span fires with count: N (unchanged behavior)

Testing

  • Add test for new aggregate path (stream_not_found, count: 0)
  • Split reload test to explicitly assert on reload populate (count: N)

@cursor

cursor Bot commented Mar 12, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Low risk: changes are limited to telemetry/tracing instrumentation around aggregate loading, with added tests to cover stream_not_found and reload scenarios.

Overview
Adds new [:commanded, :aggregate, :load, :start|:stop] telemetry around the full rebuild_from_events/1 event-store read, emitting count: 0 for {:error, :stream_not_found} and wrapping existing aggregates’ reloads.

Updates OpenTelemetry instrumentation (AggregatePopulate) to create a parent commanded.aggregate.load span and keep commanded.aggregate.populate as a child span only when events are applied, and expands tests/docs to assert the new load vs populate behavior and attributes.

Written by Cursor Bugbot for commit 352c285. This will update automatically on new commits. Configure here.

@coderabbitai

coderabbitai Bot commented Mar 12, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

Adds aggregate "load" telemetry around event-store streaming and applies events to rebuild state; instruments OpenTelemetry with load start/stop handlers and updates internal builder functions to return event counts for instrumentation. Public APIs remain unchanged.

Changes

Cohort / File(s) Summary
Aggregate State Builder
lib/commanded/aggregates/aggregate_state_builder.ex
Added telemetry emit for `[:commanded, :aggregate, :load, :start
OpenTelemetry Handlers
lib/commanded/opentelemetry/aggregate_populate.ex
Attached new load handlers (`[:commanded, :aggregate, :load, :start
Tests — Aggregate Telemetry
test/aggregates/aggregate_telemetry_test.exs
Expanded tests to assert load:start/load:stop along with populate events; added scenarios for :stream_not_found and successful stream to verify counts and ordering; updated test setup to support application override.
Tests — OpenTelemetry Populate
test/opentelemetry/aggregate_populate_test.exs
Added assertions for load event handlers and a new describe block validating commanded.aggregate.load span attributes (UUID, version, count); teardown detaches load handlers.
Test Support
test/support/opentelemetry_case.ex
Added [:commanded, :aggregate, :load, :start] and [:commanded, :aggregate, :load, :stop] to the captured/detached events in test helpers.
Docs / Guides
guides/explanations/fork-differences.md
Documented new aggregate load telemetry, trace hierarchy (load → populate), and updated span coverage and PR references.

Sequence Diagram

sequenceDiagram
    participant ASB as Aggregate State Builder
    participant TM as Telemetry System
    participant OTH as OpenTelemetry Handlers
    participant ES as Event Store

    ASB->>TM: emit [:commanded, :aggregate, :load, :start]
    TM->>OTH: handle telemetry start
    OTH->>OTH: start span (commanded.aggregate.load)
    
    ASB->>ES: stream_forward (events)
    ES-->>ASB: stream or :stream_not_found
    ASB->>ASB: rebuild_from_event_stream (apply events) -> {state, count}

    ASB->>TM: emit [:commanded, :aggregate, :load, :stop] (count)
    TM->>OTH: handle telemetry stop
    OTH->>OTH: set span attrs (count, version) and end span

    ASB-->>Caller: return state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰✨ I hopped through streams both thin and deep,
Emitted starts, then counted sleeps;
Spans I sparked and closed with care,
Events applied — state rebuilt fair;
A telemetry carrot for every hare 🥕📊

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: ensuring populate telemetry is emitted for new aggregates when stream_not_found occurs.
Description check ✅ Passed The description clearly explains the problem, solution, and testing approach, directly relating to all changes in the pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch otel-es-read
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yordis yordis changed the title otel es read feat: add EventStore read operation instrumentation Mar 12, 2026
@yordis
yordis force-pushed the otel-es-read branch 2 times, most recently from f5d9ced to 7604dfa Compare March 12, 2026 19:51
Comment thread test/opentelemetry/event_store_test.exs Outdated
Comment thread lib/commanded/opentelemetry/event_store.ex Outdated
Comment thread lib/commanded/opentelemetry/event_store.ex Outdated
@yordis
yordis force-pushed the otel-es-read branch 2 times, most recently from c05656c to 303a30d Compare March 12, 2026 20:35
@yordis yordis changed the title feat: add EventStore read operation instrumentation feat: add EventStore adapter-level OpenTelemetry instrumentation Mar 12, 2026
@yordis
yordis force-pushed the otel-es-read branch 3 times, most recently from 88e9764 to de9c8b3 Compare March 12, 2026 20:38
Comment thread lib/commanded/event_store/adapters/event_store.ex Outdated
Comment thread test/opentelemetry/event_store_adapter_real_test.exs Outdated
Comment thread test/opentelemetry/event_store_adapter_real_test.exs Outdated
Comment thread lib/commanded/opentelemetry/event_store.ex Outdated
Comment thread lib/commanded/opentelemetry/event_store.ex Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread lib/commanded/opentelemetry/event_store.ex Outdated
@yordis yordis changed the title feat: add EventStore adapter-level OpenTelemetry instrumentation revert: remove EventStore adapter-level OpenTelemetry instrumentation Mar 13, 2026
@yordis yordis closed this Mar 13, 2026
@yordis yordis reopened this Mar 13, 2026
@yordis yordis changed the title revert: remove EventStore adapter-level OpenTelemetry instrumentation fix: emit populate telemetry for new aggregates (stream_not_found) Mar 13, 2026
@yordis
yordis force-pushed the otel-es-read branch 2 times, most recently from 020564e to 499fbab Compare March 13, 2026 16:33
@yordis
yordis marked this pull request as ready for review March 13, 2026 16:34
Move populate telemetry to wrap the entire rebuild_from_events flow so it
fires for both stream_not_found (new aggregates) and event consumption
(existing aggregates). Previously it only fired when events were consumed,
leaving a gap in traces for new aggregate commands.

Add tests for both paths: new aggregate (count: 0) and reload (count: N).

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/commanded/aggregates/aggregate_state_builder.ex`:
- Around line 93-121: When EventStore.stream_forward returns {:error,
:stream_not_found} the populate telemetry is never started because populate is
begun inside rebuild_from_event_stream/2; update the {:error, :stream_not_found}
branch in the load logic so it still invokes the populate telemetry path (either
by calling rebuild_from_event_stream/2 with an empty event stream or by
explicitly starting/stopping the populate telemetry/span with count: 0) so that
[:commanded, :aggregate, :populate, *] is emitted for new aggregates; reference
the load_prefix/load_start telemetry variables and the
rebuild_from_event_stream/2 helper when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 68ec80e3-48de-44e0-9576-ce318690305e

📥 Commits

Reviewing files that changed from the base of the PR and between 34c0890 and ec8b38c.

📒 Files selected for processing (5)
  • lib/commanded/aggregates/aggregate_state_builder.ex
  • lib/commanded/opentelemetry/aggregate_populate.ex
  • test/aggregates/aggregate_telemetry_test.exs
  • test/opentelemetry/aggregate_populate_test.exs
  • test/support/opentelemetry_case.ex

Comment thread lib/commanded/aggregates/aggregate_state_builder.ex
@yordis
yordis merged commit 1af575a into main Mar 13, 2026
4 of 5 checks passed
@yordis
yordis deleted the otel-es-read branch March 13, 2026 16:50
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