Distributed Tracing
Release-backed guide to tracing Elsa 3.8.0 workflows with Elsa.Workflows instrumentation and the OpenTelemetry diagnostics collector.
In release/3.8.0, Elsa has two distinct OpenTelemetry stories:
Elsa.Workflowsemits workflow and activity spans plus workflow metrics.Elsa.Diagnostics.OpenTelemetryingests OTLP data so Elsa Studio can query and stream traces, metrics, and logs.
Treat those as complementary parts of one tracing setup:
your Elsa host emits telemetry;
your OTLP backend stores and correlates it;
Elsa's diagnostics collector can optionally receive the same OTLP traffic for Studio diagnostics.
What Elsa emits directly
The release-backed instrumentation surface is Elsa.Workflows.
ActivitySource:Elsa.WorkflowsMeter:Elsa.Workflows
WorkflowInstrumentation in elsa-core emits:
workflow spans with operation name
workflow.execute;activity spans with operation name
activity.execute;counters for
elsa.workflow.started,elsa.workflow.completed, andelsa.workflow.faulted;a histogram for
elsa.activity.duration.
Key workflow span tags include:
workflow.instance.idworkflow.definition.idworkflow.definition.versionworkflow.definition.version.idworkflow.statusworkflow.substatusworkflow.nameworkflow.parent.instance.idworkflow.correlation.idelsa.tenant.id
Key activity span tags include:
workflow.activity.idworkflow.activity.nameworkflow.activity.typeworkflow.activity.versionworkflow.activity.execution.idworkflow.activity.statusworkflow.activity.parent.execution.idworkflow.activity.scheduled.by.execution.idworkflow.activity.outcome
When execution faults, the instrumentation marks the span as error and adds a standard exception.type tag.
Basic exporter setup
To export Elsa workflow spans and metrics from your host, subscribe to the Elsa.Workflows source and meter:
Use this path when you want traces in systems such as Jaeger, Grafana Tempo, Honeycomb, Datadog, or any other OTLP-compatible backend.
What to expect in traces
For the built-in Elsa.Workflows instrumentation:
one workflow execution cycle creates one workflow span;
each executed activity creates an activity span;
faulted executions set the span status to error;
cancellations are treated separately from faults;
parent workflow instance IDs and correlation IDs flow into span tags when present.
This makes CorrelationId, parent-child workflow dispatch, and activity timings directly queryable in your tracing backend.
Elsa Studio collector and trace viewer
Elsa.Diagnostics.OpenTelemetry does not replace the Elsa.Workflows instrumentation. It adds a diagnostics collector and Studio-facing query surface.
In release/3.8.0, the collector maps these HTTP/protobuf ingestion routes by default:
POST /elsa/otlp/v1/tracesPOST /elsa/otlp/v1/metricsPOST /elsa/otlp/v1/logs
It also exposes Studio-facing read endpoints:
POST /diagnostics/opentelemetry/resources/searchPOST /diagnostics/opentelemetry/traces/searchGET /diagnostics/opentelemetry/traces/{traceId}POST /diagnostics/opentelemetry/metrics/searchPOST /diagnostics/opentelemetry/logs/searchGET /diagnostics/opentelemetry/storageGET /diagnostics/opentelemetry/collector-configuration
For live updates, the diagnostics module also maps the SignalR hub route:
/elsa/hubs/diagnostics/opentelemetry
Read access is protected by read:diagnostics:opentelemetry.
Securing OTLP ingestion
The diagnostics collector has a separate ingestion permission concept.
Read endpoints use
read:diagnostics:opentelemetry.OTLP ingestion uses
ingest:diagnostics:opentelemetryinternally.
For HTTP/protobuf ingestion, OpenTelemetryDiagnosticsOptions supports API key protection. Configure it through standard options binding:
If you configure an API key, callers send it in the x-otlp-api-key header by default. The collector configuration endpoint intentionally returns <configured> instead of the secret value.
Collector configuration and endpoint options
OpenTelemetryDiagnosticsOptions lets you tune collector behavior, including:
HttpEndpointPath, default/elsa/otlp/v1HubRoute, default/elsa/hubs/diagnostics/opentelemetryTraceCapacitySpanCapacityMetricPointCapacityLogRecordCapacityResourceCapacitySubscriberChannelCapacityMaxQuerySizeMaxHttpRequestBodySizeEnableGrpcGrpcEndpointPath
When you enable the diagnostics shell feature through UseOpenTelemetryDiagnostics, the feature itself exposes the in-memory capacity and max-request-body settings. For endpoint paths, hub route, API key, and related collector behavior, configure OpenTelemetryDiagnosticsOptions directly.
The GET /diagnostics/opentelemetry/collector-configuration endpoint reports the active HTTP and gRPC collector metadata plus the expected OTEL environment variables:
OTEL_SERVICE_NAMEOTEL_EXPORTER_OTLP_ENDPOINTOTEL_EXPORTER_OTLP_PROTOCOL
About gRPC ingestion in 3.8.0
This release exposes shared gRPC collector metadata, but the shared Elsa.Diagnostics.OpenTelemetry module does not itself bind a concrete gRPC collector service.
What the code does in release/3.8.0:
if
EnableGrpcisfalse, no gRPC collector path is exposed;if
EnableGrpcistruebutGrpcEndpointPathis empty, Elsa throws during endpoint mapping;the shared module documents that actual gRPC service binding is host-specific.
So for a portable setup across Elsa hosts, use the HTTP/protobuf OTLP routes unless your host explicitly adds the gRPC binding.
Older Elsa.OpenTelemetry extension package
The elsa-extensions repository still contains an Elsa.OpenTelemetry module that adds workflow and activity execution middleware with its own ActivitySource.
That middleware:
creates workflow spans named
execute workflow {name};creates activity spans named
execute activity {type};records incident details and correlation IDs on spans;
supports
UseNewRootActivityForRemoteParentandUseDummyParentActivityAsRootSpan.
You will still see it used in the Elsa.Server.Web workbench host in elsa-extensions, but for general release/3.8.0 guidance the stable baseline is still Elsa.Workflows instrumentation plus, optionally, the diagnostics collector.
Use the extension middleware only when you are intentionally adopting that host-specific tracing behavior and understand its trace-root options.
Recommended deployment patterns
Use one of these patterns:
Backend-only tracing
Use this when operators work primarily in your external observability stack.
Export
Elsa.Workflowsspans and metrics directly to your OTLP backend.Use Elsa incidents and activity records for workflow-local diagnosis.
Keep Studio diagnostics focused on structured logs and runtime inspection.
Backend plus Studio trace diagnostics
Use this when Elsa Studio users also need an in-product trace view.
Export
Elsa.Workflowstelemetry to your OTLP backend.Send OTLP telemetry to Elsa's diagnostics collector as well.
Grant operators
read:diagnostics:opentelemetry.Tune in-memory capacities so Studio diagnostics stay bounded.
Troubleshooting
If traces do not appear where you expect, check these points in order:
Confirm your OpenTelemetry pipeline subscribes to
WorkflowInstrumentation.ActivitySourceName.Confirm your metrics pipeline subscribes to
WorkflowInstrumentation.MeterName.Verify the OTLP exporter endpoint from the host process, not only from your workstation.
If Studio diagnostics are empty, verify the collector routes under
/elsa/otlp/v1and thex-otlp-api-keyheader when enabled.If SignalR trace streaming fails, verify the user has
read:diagnostics:opentelemetry.If you enabled gRPC ingestion, confirm your host actually bound the gRPC collector service instead of only setting collector metadata.
Related guides
Last updated