Gedistribueerde tracering van OpenTelemetry inschakelen met Durable Task Scheduler

Gedistribueerde tracering biedt end-to-end inzicht in het uitvoeringsproces van orkestratie. Wanneer u OpenTelemetry inschakelt met Durable Task Scheduler, produceert elke orkestratie, activiteit en sub-orkestratie gekoppelde spans die timing, volgorde en fouten in het hele werkproces weergeven. U kunt deze traceringen exporteren naar een back-end die compatibel is met OpenTelemetry, zoals Azure Monitor Application Insights, Jaeger of Zipkin.

Durable Functions en de zelfstandige Durable Taak-SDK's bieden ondersteuning voor gedistribueerde tracing met OpenTelemetry bij gebruik van Durable Task Scheduler als backend.

Hoe werkt het?

De Durable Task SDK's instrumenteren automatisch orkestraties en activiteiten met OpenTelemetry spans. Het SDK maakt een bovengeplaatste span voor elke orkestratie en onderliggende spans voor elke activiteit-aanroep, suborkestratie en timer. Traceringscontext wordt automatisch doorgegeven aan al deze bewerkingen, zodat u één gecorreleerde tracering krijgt voor de hele werkstroom.

De resulterende traceringsstructuur ziet er als volgt uit:

create_orchestration (client)
  └─ orchestration (server)
       ├─ activity:Step1
       ├─ activity:Step2
       └─ activity:Step3

U hoeft geen aangepaste instrumentatie toe te voegen aan uw orchestrator- of activiteitscode. Registreer de Microsoft.DurableTask activiteitsbron bij uw OpenTelemetry-configuratie en de SDK verwerkt de rest.

Vereiste voorwaarden

  • Een Azure Functions project met de extensie Durable Functions versie 2.13.0 of hoger.
  • Durable Task Scheduler geconfigureerd als de back-end van de opslag voor uw functie-app.
  • Een met OpenTelemetry compatibele back-end voor het weergeven van traceringen (Application Insights, Jaeger of een andere OTLP-collector).
  • .NET 8 SDK of hoger.
  • De Microsoft.DurableTask.Worker.AzureManaged en Microsoft.DurableTask.Client.AzureManaged NuGet-pakketten.
  • De OpenTelemetry, OpenTelemetry.Extensions.Hostingen OpenTelemetry.Exporter.OpenTelemetryProtocol NuGet-pakketten.
  • Een met OpenTelemetry compatibele back-end voor het weergeven van traceringen, zoals Application Insights voor productie of Jaeger voor lokale ontwikkeling.

Gedistribueerde tracering inschakelen

Als u gedistribueerde tracering in Durable Functions wilt inschakelen, werkt u uw host.json bij en configureert u een back-end met OpenTelemetry-compatibele telemetrie.

Host.json bijwerken

Voeg de tracing sectie toe onder durableTask in uw host.json bestand:

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "tracing": {
        "DistributedTracingEnabled": true,
        "Version": "V2"
      }
    }
  }
}

Application Insights configureren

Stel de APPLICATIONINSIGHTS_CONNECTION_STRING omgevingsvariabele in uw functie-app in.

Voor lokale ontwikkeling voegt u deze toe aan local.settings.json:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "APPLICATIONINSIGHTS_CONNECTION_STRING": "<your-connection-string>"
  }
}

Voor Azure gehoste apps voegt u deze toe als toepassingsinstelling onder Configuratie in de Azure-portal.

Opmerking

Als u APPINSIGHTS_INSTRUMENTATIONKEY eerder hebt gebruikt, schakelt u over naar APPLICATIONINSIGHTS_CONNECTION_STRING voor de nieuwste mogelijkheden.

Telemetrieruis verminderen

Om te voorkomen dat Application Insights traceringsgegevens uitsampelt, moet Request worden uitgesloten van de steekproefregels in host.json.

{
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  }
}

Registreer de Microsoft.DurableTask activiteitsbron bij uw OpenTelemetry-configuratie. De Durable Task SDK maakt automatisch spans voor orkestraties en activiteiten aan wanneer u deze bron registreert.

Voeg in uw Program.cs van de worker OpenTelemetry-tracering toe met de activiteitsbron Durable Task:

using Microsoft.DurableTask;
using Microsoft.DurableTask.Worker;
using Microsoft.DurableTask.Worker.AzureManaged;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

var builder = Host.CreateApplicationBuilder(args);

// Configure OpenTelemetry tracing
builder.Services.AddOpenTelemetry()
    .ConfigureResource(resource => resource.AddService("durable-worker"))
    .WithTracing(tracing =>
    {
        tracing
            .AddSource("Microsoft.DurableTask")
            .AddOtlpExporter(opts =>
            {
                opts.Endpoint = new Uri(
                    Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")
                    ?? "http://localhost:4317");
            });
    });

// Build connection string from environment variables
string endpoint = Environment.GetEnvironmentVariable("ENDPOINT") ?? "http://localhost:8080";
string taskHub = Environment.GetEnvironmentVariable("TASKHUB") ?? "default";
string connectionString = endpoint.Contains("localhost")
    ? $"Endpoint={endpoint};TaskHub={taskHub};Authentication=None"
    : $"Endpoint={endpoint};TaskHub={taskHub};Authentication=DefaultAzure";

// Configure Durable Task worker
builder.Services.AddDurableTaskWorker()
    .AddTasks(tasks =>
    {
        tasks.AddOrchestratorFunc<string, string>(
            "OrderProcessingOrchestration", async (ctx, input) =>
        {
            var validated = await ctx.CallActivityAsync<string>("ValidateOrder", input);
            var payment = await ctx.CallActivityAsync<string>("ProcessPayment", validated);
            var shipment = await ctx.CallActivityAsync<string>("ShipOrder", payment);
            var result = await ctx.CallActivityAsync<string>("SendNotification", shipment);
            return result;
        });

        tasks.AddActivityFunc<string, string>("ValidateOrder", (ctx, input) =>
            Task.FromResult($"Validated({input})"));
        tasks.AddActivityFunc<string, string>("ProcessPayment", (ctx, input) =>
            Task.FromResult($"Paid({input})"));
        tasks.AddActivityFunc<string, string>("ShipOrder", (ctx, input) =>
            Task.FromResult($"Shipped({input})"));
        tasks.AddActivityFunc<string, string>("SendNotification", (ctx, input) =>
            Task.FromResult($"Notified({input})"));
    })
    .UseDurableTaskScheduler(connectionString);

var host = builder.Build();
await host.RunAsync();

De sleutelregel is .AddSource("Microsoft.DurableTask"), waarmee OpenTelemetry wordt geïnstrueerd om spans vast te leggen die door de Durable Task SDK worden uitgezonden.

Het OTLP-eindpunt configureren

De bovenstaande codefragmenten verwijzen naar de OTEL_EXPORTER_OTLP_ENDPOINT omgevingsvariabele om het doel voor traceringsgegevens in te stellen. Stel deze variabele in op basis van uw back-end:

Backend Eindpuntwaarde Protocol
Jaeger (lokaal) http://localhost:4317 gRPC
Jaeger (lokaal, HTTP) http://localhost:4318 HTTP/protobuf
OpenTelemetry Collector http://<collector-host>:4317 gRPC
Azure Monitor (via OTLP) Gebruik in plaats daarvan de Azure Monitor exporteur N/A

Voor lokale ontwikkeling met Jaeger werkt de standaardinstelling http://localhost:4317 wanneer Jaeger wordt uitgevoerd met OTLP gRPC ingeschakeld (poort 4317). De JavaScript-SDK maakt standaard gebruik van HTTP/protobuf, dus deze is gericht op de poort 4318 met het /v1/traces pad.

Traceringen lokaal weergeven met de Gebruikersinterface van Jaeger

Gebruik voor lokale ontwikkeling de Durable Task Scheduler-emulator met Jaeger om traceringen weer te geven. Gebruik een docker-compose.yml om beide services te starten:

services:
  dts-emulator:
    image: mcr.microsoft.com/dts/dts-emulator:latest
    ports:
      - "8080:8080"  # gRPC
      - "8082:8082"  # Dashboard
  jaeger:
    image: jaegertracing/jaeger:latest
    ports:
      - "16686:16686"  # Jaeger UI
      - "4317:4317"    # OTLP gRPC
      - "4318:4318"    # OTLP HTTP

Start de infrastructuur:

docker compose up -d

Nadat u de toepassing hebt uitgevoerd, opent u de Gebruikersinterface van Jaeger op http://localhost:16686 en zoekt u naar uw servicenaam (bijvoorbeeld durable-worker) om traceringen weer te geven.

Voor lokale ontwikkeling met Durable Functions worden gedistribueerde traceringsgegevens standaard verzonden naar Application Insights. Als u traceringen lokaal wilt weergeven zonder uit te rollen, kunt u een OTLP-exporteur toevoegen naast Application Insights in uw functie-app met gebruik van Program.cs.

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        tracing
            .AddSource("Microsoft.DurableTask")
            .AddOtlpExporter(opts =>
            {
                opts.Endpoint = new Uri("http://localhost:4317");
            });
    });

Voer Vervolgens Jaeger lokaal uit met docker run -d -p 16686:16686 -p 4317:4317 jaegertracing/jaeger:latest en open de Jaeger-gebruikersinterface op http://localhost:16686.

Traceringen weergeven in Application Insights

Voor productieworkloads is Application Insights de aanbevolen telemetrieachtergrond.

Zodra DistributedTracingEnabled is ingesteld op true met Version ingesteld op V2 in host.json, verzendt uw Durable Functions-app gecorreleerde spanten naar Application Insights. De volledige tracering voor orkestratie bekijken in de Azure-portal:

  1. Ga naar uw Application Insights-resource in de Azure-portal.
  2. Open Transactie zoeken en zoek naar uw orkestratie op naam of instance-ID.
  3. Selecteer een tracering om de einde-tot-einde transactie weer te geven met alle gecorreleerde spanwijdtes.

De tracering toont de orkestratie als een ouderspan met kindspannen voor elke activiteitsaanroep, suborkestratie en wachten op de timer. De volgende patronen leveren afzonderlijke traceervormen op.

Patroon Vorm traceren
Functiekoppeling Sequentiële activiteiten zijn genest onder de orchestrator-span.
Fan-out/fan-in Parallelle activiteiten die elkaar in tijd overlappen.
Menselijke tussenkomst Een orchestrator heeft een lange wachttijd voor een externe gebeurtenis.
Monitor Herhaalde activiteit spreidt zich uit over timerwachttijden tussen iteraties.

Configureer de OTLP-exporteur voor het verzenden van traceringen naar Application Insights met behulp van de Azure Monitor OpenTelemetry-exporteur of exporteer via OTLP naar een OpenTelemetry Collector die doorstuurt naar Application Insights.

Installeer het Azure.Monitor.OpenTelemetry.Exporter NuGet-pakket en vervang de OTLP-exporteur door:

builder.Services.AddOpenTelemetry()
    .ConfigureResource(resource => resource.AddService("durable-worker"))
    .WithTracing(tracing =>
    {
        tracing
            .AddSource("Microsoft.DurableTask")
            .AddAzureMonitorTraceExporter(opts =>
            {
                opts.ConnectionString = Environment.GetEnvironmentVariable(
                    "APPLICATIONINSIGHTS_CONNECTION_STRING");
            });
    });

Welke traceringsgegevens worden weergegeven

De traceringsgegevens die worden geproduceerd door de Durable Task SDK's omvatten:

Spantype Beschrijving
create_orchestration De client-side span die wordt verzonden bij het plannen van een nieuwe orchestratie
orchestration De orkestratie op de serverzijde bestrijkt de volledige uitvoeringslevenscyclus.
activity:<name> Een periode voor elke aanroep van activiteit, met timing en resultaat
sub_orchestration:<name> Een spanwijdte voor elke sub-orkestratieoproep
timer Een periode voor duurzame timerwachttijden

Elk bereik bevat kenmerken zoals durabletask.type, durabletask.task.name, durabletask.task.instance_iden durabletask.task.task_id. Mislukte activiteiten en orchestrationen bevatten foutdetails in de status en gebeurtenissen van de span.

Troubleshooting

Issue Resolutie / Besluit
Er worden geen sporen weergegeven Controleer of de Microsoft.DurableTask activiteitsbron is geregistreerd en of het eindpunt van de exporteur bereikbaar is.
Traceringen zijn onvolledig Controleer of de OpenTelemetry SDK wordt geïnitieerd vóór de Durable Task SDK, vooral in JavaScript/TypeScript.
Ontbrekende spanten in Application Insights Schakel steekproeven uit of pas deze aan om te voorkomen dat traceringsgegevens worden verwijderd.
Traceringen correleren niet Controleer of u Durable Task Scheduler als back-end gebruikt. Voor traceringscontextdoorgifte is de scheduler vereist.

Voorbeeldcode