Włącz śledzenie rozproszone OpenTelemetry za pomocą planera zadań Durable Task Scheduler

Śledzenie rozproszone zapewnia całościowy wgląd w wykonywanie orkiestracji. Po włączeniu OpenTelemetry z użyciem Durable Task Scheduler, każda orkiestracja, czynność i sub-orkiestracja produkuje powiązane zakresy, które pokazują czas, kolejność i błędy w całym przepływie pracy. Te ślady można wyeksportować do dowolnego zaplecza zgodnego z technologią OpenTelemetry, takiego jak Azure Monitor Application Insights, Jaeger lub Zipkin.

Durable Functions i autonomiczne Durable Task SDK obsługują rozproszone śledzenie OpenTelemetry podczas korzystania z Harmonogramu Zadań Durable jako zaplecza.

Jak to działa

Zestawy SDK Durable Task automatycznie instrumentują orkiestracje i działania za pomocą przedziałów OpenTelemetry. Zestaw SDK tworzy zakres nadrzędny dla każdej aranżacji i zakresów podrzędnych dla każdego wywołania działania, podarancji i czasomierza. Kontekst śledzenia jest propagowany automatycznie we wszystkich tych operacjach, dzięki czemu uzyskasz jeden skorelowany ślad dla całego przepływu pracy.

Wynikowe drzewo śledzenia wygląda następująco:

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

Nie musisz dodawać instrumentacji niestandardowej do orkiestratora ani kodu działania. Zarejestruj źródło aktywności Microsoft.DurableTask w swojej konfiguracji OpenTelemetry, a zestaw SDK obsłuży resztę.

Wymagania wstępne

  • Projekt Azure Functions z rozszerzeniem Durable Functions w wersji 2.13.0 lub nowszej.
  • Trwały harmonogram zadań skonfigurowany jako zaplecze magazynowe dla aplikacji funkcji w chmurze.
  • Zaplecze zgodne z technologią OpenTelemetry do wyświetlania śladów (Application Insights, Jaeger lub innego modułu zbierającego OTLP).
  • .NET 8 SDK lub nowszy.
  • Pakiety NuGet Microsoft.DurableTask.Worker.AzureManaged i Microsoft.DurableTask.Client.AzureManaged.
  • Pakiety OpenTelemetry, OpenTelemetry.Extensions.Hosting i OpenTelemetry.Exporter.OpenTelemetryProtocol NuGet.
  • Zaplecze zgodne z technologią OpenTelemetry do wyświetlania śladów, takich jak usługa Application Insights dla środowiska produkcyjnego lub Jaeger na potrzeby programowania lokalnego.

Włączanie śledzenia rozproszonego

Aby włączyć śledzenie rozproszone w Durable Functions, zaktualizuj host.json i skonfiguruj zaplecze telemetrii zgodnej z biblioteką OpenTelemetry.

Aktualizacja host.json

Dodaj sekcję tracing pod durableTask w pliku host.json :

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

Skonfiguruj Application Insights

Ustaw zmienną APPLICATIONINSIGHTS_CONNECTION_STRING środowiskową w aplikacji funkcji.

W przypadku programowania lokalnego dodaj go do local.settings.json:

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

W przypadku aplikacji hostowanych Azure dodaj je jako ustawienie aplikacji w obszarze Configuration w portalu Azure.

Uwaga / Notatka

Jeśli wcześniej używałeś APPINSIGHTS_INSTRUMENTATIONKEY, przełącz się na APPLICATIONINSIGHTS_CONNECTION_STRING , aby uzyskać najnowsze możliwości.

Zmniejszanie szumu telemetrii

Aby zapobiec próbkowaniu danych śledzenia przez usługę Application Insights, wyklucz Request z reguł próbkowania w host.json:

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

Zarejestruj źródło aktywności Microsoft.DurableTask w swojej konfiguracji OpenTelemetry. Zestaw Durable Task SDK automatycznie tworzy zakresy aranżacji i działań podczas rejestrowania tego źródła.

W Program.cs pracownika dodaj śledzenie OpenTelemetry za pomocą źródła aktywności 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();

Kluczowa linia to .AddSource("Microsoft.DurableTask"), która informuje bibliotekę OpenTelemetry o przechwyceniu przedziałów emitowanych przez zestaw Durable Task SDK.

Konfigurowanie punktu końcowego OTLP

Powyższe fragmenty kodu odwołują się do zmiennej środowiskowej OTEL_EXPORTER_OTLP_ENDPOINT , aby ustawić miejsce docelowe dla danych śledzenia. Ustaw tę zmienną na podstawie zaplecza:

Backend Wartość punktu końcowego Protokół
Jaeger (lokalny) http://localhost:4317 gRPC
Jaeger (lokalny, HTTP) http://localhost:4318 HTTP/protobuf
OpenTelemetry Collector http://<collector-host>:4317 gRPC
Azure Monitor (za pośrednictwem OTLP) Zamiast tego należy użyć eksportera Azure Monitor N/A

W przypadku programowania lokalnego w środowisku Jaeger ustawienie domyślne http://localhost:4317 działa, gdy aplikacja Jaeger jest uruchomiona z włączoną funkcją OTLP gRPC (port 4317). Zestaw SDK języka JavaScript domyślnie używa protokołu HTTP/protobuf, więc jest przeznaczony dla portu 4318 ze ścieżką /v1/traces .

Wyświetlaj ślady lokalnie w interfejsie użytkownika Jaeger

W przypadku programowania lokalnego użyj emulatora narzędzia Durable Task Scheduler z oprogramowaniem Jaeger , aby wyświetlić ślady. Użyj elementu , docker-compose.yml aby uruchomić obie usługi:

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

Uruchom infrastrukturę:

docker compose up -d

Po uruchomieniu aplikacji otwórz interfejs użytkownika usługi Jaeger pod adresem http://localhost:16686 i wyszukaj nazwę usługi (na przykład durable-worker), aby wyświetlić ślady.

W przypadku programowania lokalnego przy użyciu Durable Functions dane śledzenia rozproszonego są domyślnie wysyłane do usługi Application Insights. Aby wyświetlić ślady lokalnie bez wdrażania, możesz dodać eksportera OTLP wraz z usługą Application Insights w aplikacji Program.csfunkcji :

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

Następnie uruchom aplikację Jaeger lokalnie za pomocą docker run -d -p 16686:16686 -p 4317:4317 jaegertracing/jaeger:latest polecenia i otwórz interfejs użytkownika jaegera pod adresem http://localhost:16686.

Wyświetlanie śladów w usłudze Application Insights

W przypadku obciążeń produkcyjnych usługa Application Insights jest zalecanym zapleczem telemetrii.

Po ustawieniu DistributedTracingEnabled na true oraz Version na V2 w host.json, aplikacja Durable Functions generuje skorelowane odcinki do usługi Application Insights. Aby wyświetlić pełny ślad aranżacji w portalu Azure:

  1. Przejdź do zasobu usługi Application Insights w portalu Azure.
  2. Otwórz wyszukiwanie transakcji i wyszukaj orkiestrację według nazwy lub identyfikatora wystąpienia.
  3. Wybierz ślad, aby wyświetlić kompleksową transakcję ze wszystkimi skorelowanych zakresami.

Ślad pokazuje aranżację jako zakres nadrzędny z zakresami podrzędnymi dla każdego wywołania działania, suborchestracji i oczekiwania czasomierza. Następujące wzorce generują różne kształty śladów:

Wzór Kształt obrysu
Łączenie funkcji w łańcuchy Sekwencyjna aktywność zagnieżdżona pod zakresem orkiestratora.
Fan-out/fan-in Aktywności równoległe nakładają się w czasie.
Interakcja z użytkownikami Rozpiętość orkiestratora z długim oczekiwaniem na zdarzenie zewnętrzne.
Monitor Powtarzające się działania obejmują oczekiwanie za pomocą czasomierza między iteracjami.

Skonfiguruj eksportera OTLP, aby wysyłał ślady do usługi Application Insights przy użyciu eksportera Azure Monitor OpenTelemetry lub eksportuj za pośrednictwem otLP do modułu zbierającego OpenTelemetry, który przekazuje dane do usługi Application Insights.

Zainstaluj pakiet Azure.Monitor.OpenTelemetry.Exporter NuGet i zastąp eksportera OTLP:

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

Jakie dane śledzenia pokazują

Dane śledzenia generowane przez zestawy SDK trwałych zadań obejmują:

Typ zakresu Opis
create_orchestration Emitowany zakres po stronie klienta podczas planowania nowej orkiestracji
orchestration Zakres zarządzania po stronie serwera obejmujący cały cykl realizacji procesu wykonywania
activity:<name> Okres dla każdego wywołania aktywności, pokazujący czas i wynik
sub_orchestration:<name> Zakres dla każdego wywołania orkiestracji podrzędnej
timer Zakres dla długich czasów oczekiwania czasomierza

Każdy zakres zawiera atrybuty, takie jak durabletask.type, , durabletask.task.namedurabletask.task.instance_idi durabletask.task.task_id. Nieudane działania i orkiestracje zawierają szczegóły błędu w stanie i zdarzeniach okresu.

Troubleshooting

Problematyka Resolution
Nie są wyświetlane żadne ślady Sprawdź, czy Microsoft.DurableTask źródło działania jest zarejestrowane, a punkt końcowy eksportera jest osiągalny.
Ślady są niekompletne Sprawdź, czy zestaw OpenTelemetry SDK został zainicjowany przed zestawem Durable Task SDK (szczególnie w języku JavaScript/TypeScript).
Brakujące zakresy w usłudze Application Insights Wyłącz lub dostosuj ustawienia próbkowania , aby zapobiec porzuceniu danych śledzenia.
Ślady nie są skorelowane Sprawdź, czy używasz narzędzia Durable Task Scheduler jako zaplecza. Propagacja kontekstu śledzenia wymaga harmonogramu.

Przykładowy kod