X Tutup
Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

OpenTelemetry Distributed Tracing Sample

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.

Prerequisites

  • Java 17+
  • Docker (for DTS emulator and Jaeger)

Running the Sample

1. Start the infrastructure

# 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

2. Run the tracing sample

./gradlew :samples:runTracingPattern -PskipSigning -x downloadProtoFiles

3. View traces

What the Sample Does

The TracingPattern sample demonstrates the Fan-Out/Fan-In pattern with distributed tracing:

  1. Configures OpenTelemetry with an OTLP exporter pointing to Jaeger
  2. Connects a worker and client to the DTS emulator using a connection string
  3. Creates a parent span (create_orchestration:FanOutFanIn) and schedules an orchestration
  4. The orchestration waits on a 1-second durable timer, then fans out 5 parallel GetWeather activities (Seattle, Tokyo, London, Paris, Sydney), fans in the results, then calls CreateSummary to aggregate
  5. The SDK automatically propagates trace context through the full execution chain

Screenshots

Jaeger — Trace Search Results

Shows the trace from durabletask-java-tracing-sample service with spans covering the full fan-out/fan-in orchestration lifecycle.

Jaeger trace search results

Jaeger — Trace Detail

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 under create_orchestration rather than nested under the orchestration span. All spans have meaningful durations.

Jaeger trace detail

Jaeger — Span Attributes

Activity span showing attributes aligned with the .NET SDK schema:

  • durabletask.type=activity
  • durabletask.task.name=GetWeather
  • durabletask.task.instance_id=<orchestrationId>
  • durabletask.task.task_id=1
  • otel.scope.name=Microsoft.DurableTask
  • span.kind=server

Jaeger span detail

DTS Dashboard — Completed Orchestrations

The FanOutFanIn orchestration completed successfully with all activities.

DTS Dashboard

Cleanup

docker stop jaeger dts-emulator && docker rm jaeger dts-emulator

Azure Functions Sample

The 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× GetWeatherCreateSummary) but runs as an HTTP-triggered Azure Function.

Running

cd samples-azure-functions
../gradlew azureFunctionsPackage -PskipSigning -x downloadProtoFiles
cd build/azure-functions/<app-name>
func start

Then 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.

X Tutup