Monitoring and debugging distributed workflows is critical for production systems. The Durable Task Scheduler ecosystem provides multiple layers of observability: a built-in dashboard for business-level monitoring and OpenTelemetry support for infrastructure-level tracing.
- Built-in Dashboard
- Distributed Tracing with OpenTelemetry
- Durable Functions Distributed Tracing
- Durable Task SDKs Tracing
- Exporter Options
- Next Steps
Every Durable Task Scheduler instance (including the local emulator) comes with a monitoring dashboard out of the box.
- View all orchestrations — filter by status, name, time range
- Drill into execution history — see each activity, sub-orchestration, and event
- Monitor timing — identify slow activities and bottlenecks
- Manage instances — pause, terminate, restart, or purge orchestration instances
- Multi-agent visualization — trace complex AI agent workflows across multiple orchestrations
Local (Emulator):
http://localhost:8082
Azure: Navigate to your Durable Task Scheduler resource → Task Hub → Dashboard URL, or go to dashboard.durabletask.io and register your endpoint.
For infrastructure-level observability — latency analysis, cross-service correlation, and performance profiling — you can use OpenTelemetry (OTel) distributed tracing.
| Aspect | Built-in Dashboard | OpenTelemetry Tracing |
|---|---|---|
| Focus | Business logic (orchestration state) | Infrastructure (latency, errors, dependencies) |
| Granularity | Orchestration/activity level | Span-level (including HTTP, DB calls) |
| Cross-service | Within task hub | Across all services (end-to-end) |
| Storage | Managed by DTS | Your choice (App Insights, Jaeger, etc.) |
| Best for | "What happened in this orchestration?" | "Where is the bottleneck across my system?" |
Durable Functions supports Distributed Tracing V2, which correlates orchestrations, entities, and activities into unified traces.
- Update host.json:
{
"extensions": {
"durableTask": {
"tracing": {
"distributedTracingEnabled": true,
"version": "V2"
}
}
}
}-
Requirements:
- .NET Isolated:
Microsoft.Azure.Functions.Worker.Extensions.DurableTask>= v1.4.0 - Non-.NET:
Microsoft.Azure.WebJobs.Extensions.DurableTask>= v3.2.0
- .NET Isolated:
-
Configure Application Insights — If your Function app has Application Insights enabled, traces will appear automatically.
- Navigate to your Application Insights resource
- Go to Transaction Search
- Filter for
RequestandDependencyevents with Durable Functions prefixes (orchestration:,activity:) - Click on an event to see the end-to-end Gantt chart
The Gantt chart shows the full orchestration flow — when each activity started, how long it took, and the data flow between them.
📖 Durable Functions diagnostics →
The Durable Task SDKs integrate with OpenTelemetry. Some spans come from your app and some come from DTS, depending on the SDK. Configure the tracer provider and exporter for your language.
Add OpenTelemetry packages to your project:
<PackageReference Include="OpenTelemetry" Version="1.*" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.*" />
<PackageReference Include="OpenTelemetry.Exporter.OtlpProtocol" Version="1.*" />Configure tracing in your worker:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.DurableTask")
.AddOtlpExporter(opts =>
{
opts.Endpoint = new Uri("http://localhost:4317");
});
});Install OpenTelemetry packages:
pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlpConfigure tracing:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://localhost:4317"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)The Go SDK (github.com/microsoft/durabletask-go v1.0.0-beta3, Go 1.25.0+) passes W3C trace context from the caller through DTS to activities. Set up an OpenTelemetry tracer provider and exporter in your app, start a caller span, and pass its context when you schedule an orchestration. Activities can create their own spans from that context.
DTS creates the orchestration, activity, and timer spans. The Go worker does not export these spans locally. Matching trace IDs show that context was passed; they do not show the full DTS trace.
Start with the Go OpenTelemetry sample. With the emulator running:
cd samples/durable-task-sdks/go
go mod download
go run ./opentelemetry-tracingTo send application spans to an OTLP/HTTP collector or Jaeger, set the endpoint:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 go run ./opentelemetry-tracingUse port 4318 (OTLP/HTTP), not 4317 (OTLP/gRPC). If the collector is not available, the sample fails. This setting does not export DTS spans.
See the SDK tracing example and the OpenTelemetry Go documentation for exporter setup.
For local development, you can use Jaeger to visualize traces alongside the DTS emulator.
version: '3.8'
services:
dts-emulator:
image: mcr.microsoft.com/dts/dts-emulator:latest
ports:
- "8080:8080"
- "8082:8082"
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # Jaeger UI
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
environment:
- COLLECTOR_OTLP_ENABLED=trueAfter starting both services:
- DTS Dashboard: http://localhost:8082
- Jaeger UI: http://localhost:16686
| Exporter | Best For | Setup Complexity |
|---|---|---|
| Application Insights | Azure production workloads | Low (built-in for Azure Functions) |
| Jaeger | Local development, self-hosted | Low (Docker) |
| Zipkin | Lightweight tracing | Low (Docker) |
| Grafana Tempo | Grafana ecosystem users | Medium |
| OTLP (generic) | Any OTel-compatible backend | Varies |
For Azure production workloads, use Application Insights with the Azure Monitor OpenTelemetry Distro in supported languages. The distro is not a Go integration. For Go, use an OpenTelemetry Go exporter and a collector.