This sample demonstrates distributed tracing with the Durable Task Java SDK using OpenTelemetry. Traces are exported to Jaeger via OTLP/gRPC for visualization.
The Java SDK automatically propagates W3C trace context (traceparent/tracestate) when scheduling orchestrations. The worker creates spans around each activity and orchestration execution, forming a correlated trace tree visible in Jaeger.
- Java 17+
- Docker (for DTS emulator and Jaeger)
# Start the DTS emulator (port 8080 for gRPC, 8082 for dashboard)
docker run -d --name dts-emulator \
-p 8080:8080 -p 8082:8082 \
mcr.microsoft.com/dts/dts-emulator:latest
# Start Jaeger (port 16686 for UI, 4317 for OTLP gRPC)
docker run -d --name jaeger \
-p 16686:16686 -p 4317:4317 -p 4318:4318 \
-e COLLECTOR_OTLP_ENABLED=true \
jaegertracing/all-in-one:latest./gradlew :samples:runTracingPattern -PskipSigning -x downloadProtoFiles- Jaeger UI: http://localhost:16686 — Search for service
durabletask-java-tracing-sample - DTS Dashboard: http://localhost:8082
The TracingPattern sample demonstrates the Fan-Out/Fan-In pattern with distributed tracing:
- Configures OpenTelemetry with an OTLP exporter pointing to Jaeger
- Connects a worker and client to the DTS emulator using a connection string
- Creates a parent span (
create_orchestration:FanOutFanIn) and schedules an orchestration - The orchestration waits on a 1-second durable timer, then fans out 5 parallel
GetWeatheractivities (Seattle, Tokyo, London, Paris, Sydney), fans in the results, then callsCreateSummaryto aggregate - The SDK automatically propagates trace context through the full execution chain
Shows the trace from durabletask-java-tracing-sample service with spans covering the full fan-out/fan-in orchestration lifecycle.
Full span hierarchy showing the fan-out/fan-in pattern with proper span durations:
create_orchestration:FanOutFanIn(root, internal)orchestration:FanOutFanIn(server — full lifecycle, ~1.2s)orchestration:FanOutFanIn:timer(internal — creation-to-fired, ~965ms)activity:GetWeather×5 (client — scheduling-to-completion, ~184ms) + ×5 (server — execution, ~25ms)activity:CreateSummary(client, ~8ms) + (server, ~0.7ms)
15 spans total, Depth 2.
Note: Java OTel doesn't support
SetSpanId()like .NET, so child spans appear as siblings undercreate_orchestrationrather than nested under the orchestration span. All spans have meaningful durations.
Activity span showing attributes aligned with the .NET SDK schema:
durabletask.type=activitydurabletask.task.name=GetWeatherdurabletask.task.instance_id=<orchestrationId>durabletask.task.task_id=1otel.scope.name=Microsoft.DurableTaskspan.kind=server
The FanOutFanIn orchestration completed successfully with all activities.
docker stop jaeger dts-emulator && docker rm jaeger dts-emulatorThe samples-azure-functions module contains a matching Fan-Out/Fan-In sample (TracingChain.java) for use with Azure Durable Functions. It uses the same pattern (1s timer → 5× GetWeather → CreateSummary) but runs as an HTTP-triggered Azure Function.
cd samples-azure-functions
../gradlew azureFunctionsPackage -PskipSigning -x downloadProtoFiles
cd build/azure-functions/<app-name>
func startThen trigger with: curl http://localhost:7071/api/StartFanOutFanIn
Distributed tracing in Durable Functions exports to Application Insights (not Jaeger/OTLP). Configure your APPLICATIONINSIGHTS_CONNECTION_STRING in local.settings.json to see traces.



