Skip to content

Observability

Arc instruments its own pipelines. Every command and query that runs produces activities on a named source, so once you subscribe to it your tracing backend shows where time went inside Arc without you adding anything to your handlers.

This is emitted telemetry rather than an extension point. Arc registers the activity sources itself; what you do is subscribe to them.

Arc publishes everything under a single activity source named Cratis.Arc. Add it wherever you configure OpenTelemetry:

builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource("Cratis.Arc")
.AddAspNetCoreInstrumentation());

Nothing else is required. The sources are registered when the host is built, so a subscriber either sees the spans or does not — there is no Arc-side switch to turn tracing on.

All of these are Internal activities.

SpanRaised whenIdentifies
cratis.arc.command.executea command runs through the pipelinethe command type
cratis.arc.command.validatethat command’s validation stage runsthe command type
cratis.arc.command.filtera command filter runsthe command type
cratis.arc.command.actiona controller-based command action is invokedthe route template
cratis.arc.query.performa query runs through the pipelinethe query name
cratis.arc.query.filtera query filter runsthe query name
cratis.arc.query.actiona controller-based query action is invokedthe route template
cratis.arc.identity.resolveidentity details are resolved for a request

execute and validate nest inside the request span your ASP.NET Core instrumentation already creates, so a slow command shows up as a slow child of the HTTP span rather than as an unattributed gap.

The split between validate and execute is the one worth watching. Validation that reaches a database — a uniqueness rule, a state-dependent check — is easy to write and easy to forget, and it shows up here as time spent before the handler ever ran.

cratis.arc.identity.resolve is the other common surprise: an identity-details provider runs per request, and one that queries a store puts that query on the critical path of everything.

The MongoDB integration records client metrics. Arc’s command and query pipelines emit tracing rather than counters, so if you want request rates or error rates by command, derive them from the spans or record them in a command filter.

The Kotlin and Java backend observes the same pipeline stages but through Micrometer rather than ActivitySource, with its own names and an explicit correlation attribute. See Observability for that side. The two are not wire-compatible with each other and are not meant to be — each uses what its ecosystem already collects.