Skip to content

Add trace metrics: event counts, execution duration, and per-type child spans - #1

Open
pedroamaral-cvfx wants to merge 3 commits into
mainfrom
claude/add-trace-metrics-GF4mb
Open

Add trace metrics: event counts, execution duration, and per-type child spans#1
pedroamaral-cvfx wants to merge 3 commits into
mainfrom
claude/add-trace-metrics-GF4mb

Conversation

@pedroamaral-cvfx

Copy link
Copy Markdown

Summary

Enriches OpenTelemetry spans with additional observable data to support monitoring and Datadog timeseries dashboards for Commanded CQRS applications.

Problem

The existing instrumentation creates spans for command dispatch, aggregate execution, event handling, and process management — but the spans lack quantitative data needed for operational dashboards:

  • No execution timing as a queryable attribute — span timestamps capture duration implicitly, but an explicit attribute is needed for easy filtering/aggregation in tracing backends
  • No event type names in aggregate spans — commanded.event_count existed but without the actual type names
  • No per-event-type breakdown — Datadog's "Generate Metrics from Spans" operates on spans (not span events or array attributes), so a list attribute like commanded.events cannot produce per-type timeseries

Changes

1. Execution duration on all spans (commanded.execution.duration_ms)

All four instrumentation modules (aggregate, application, event_handler, process_manager) now capture the telemetry measurements[:duration] and set it as commanded.execution.duration_ms (converted from native time units via :erlang.convert_time_unit/3). A shared native_to_ms/1 helper was added to OpentelemetryCommanded.Util.

2. Event/command type name lists as span attributes

  • Aggregate spans now include commanded.events — a list of event type name strings
  • Process manager spans now include commanded.commands — a list of dispatched command type name strings

3. Per-type child spans for Datadog metrics

For each domain event emitted by an aggregate, a zero-duration child span commanded.event.emitted is created with commanded.event_type and commanded.aggregate_uuid. For each command dispatched by a process manager, a commanded.command.dispatched child span is created with commanded.command_type and commanded.process_uuid.

Metric Datadog Query
Total events/time count(*) where @span.name:commanded.event.emitted
Events by type/time count(*) grouped by @commanded.event_type
Commands by type count(*) grouped by @commanded.command_type

New span attributes

Attribute Span Type
commanded.execution.duration_ms All integer
commanded.events Aggregate string[]
commanded.commands Process Manager string[]

New child spans

Span name Parent Attributes
commanded.event.emitted commanded.aggregate.execute commanded.event_type, commanded.aggregate_uuid
commanded.command.dispatched commanded.process_manager.handle commanded.command_type, commanded.process_uuid

Test plan

  • mix test — all existing and new tests pass
  • Aggregate success: child span with correct parent and event type
  • Aggregate error: no child spans emitted
  • Process manager success: child span with correct command type
  • Duration attribute present on all span types

claude added 2 commits March 21, 2026 01:20
Enrich OpenTelemetry spans with more observable data:
- Add `commanded.events` (list of event type names) to aggregate spans
- Add `commanded.commands` (list of command type names) to process manager spans
- Add `commanded.execution.duration_ms` to all span types (aggregate, application,
  event handler, process manager) by capturing telemetry measurements duration
- Add `native_to_ms/1` helper to Util for converting Erlang native time units

https://claude.ai/code/session_01Koa4DN6w78SgchqkWu28B6
Create child spans for each domain event emitted (aggregate) and each
command dispatched (process manager) to enable per-type metrics in
Datadog via "Generate Metrics from Spans":

- `commanded.event.emitted` child spans with `commanded.event_type`
  and `commanded.aggregate_uuid` attributes on aggregate execution
- `commanded.command.dispatched` child spans with `commanded.command_type`
  and `commanded.process_uuid` attributes on process manager handling

This enables Datadog users to create timeseries like:
  count(*) where @span.name:commanded.event.emitted
  grouped by @commanded.event_type

https://claude.ai/code/session_01Koa4DN6w78SgchqkWu28B6
@pedroamaral-cvfx

Copy link
Copy Markdown
Author

this was done on the phone, just a quick chat where I asked how could we make some metrics available through tracing

Robot doing the robot (1)

@pedroamaral-cvfx pedroamaral-cvfx self-assigned this Mar 23, 2026
@pedroamaral-cvfx

Copy link
Copy Markdown
Author

disregard this comment, just fixing the PR list view

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.

2 participants