Śledzenie operacji niestandardowych za pomocą zestawu SDK platformy .NET usługi Application Insights
Zestawy SDK usługi Application Insights automatycznie śledzą przychodzące żądania HTTP i wywołania usług zależnych, takie jak żądania HTTP i zapytania SQL. Śledzenie i korelacja żądań i zależności zapewnia wgląd w czas odpowiedzi i niezawodność całej aplikacji we wszystkich mikrousługach łączących tę aplikację.
Istnieje klasa wzorców aplikacji, których nie można ogólnie obsługiwać. Odpowiednie monitorowanie takich wzorców wymaga instrumentacji kodu ręcznego. W tym artykule opisano kilka wzorców, które mogą wymagać instrumentacji ręcznej, takich jak niestandardowe przetwarzanie kolejek i długotrwałe zadania w tle.
Ten artykuł zawiera wskazówki dotyczące śledzenia operacji niestandardowych za pomocą zestawu SDK usługi Application Insights. Ta dokumentacja jest odpowiednia dla:
- Usługa Application Insights dla platformy .NET (znana również jako podstawowy zestaw SDK) w wersji 2.4 lub nowszej.
- Usługa Application Insights dla aplikacji internetowych (z systemem ASP.NET) w wersji 2.4 lub nowszej.
- Usługa Application Insights dla ASP.NET Core w wersji 2.1 lub nowszej.
Uwaga
Zalecamy dystrybucję OpenTelemetry usługi Azure Monitor dla nowych aplikacji lub klientów, aby umożliwić usłudze Azure Monitor Application Insights. Dystrybucja OpenTelemetry usługi Azure Monitor zapewnia podobną funkcjonalność i środowisko jako zestaw SDK usługi Application Insights. Migracja z zestawu SDK usługi Application Insights jest możliwa przy użyciu przewodników migracji dla platformy .NET, Node.js i języka Python, ale nadal pracujemy nad dodaniem kilku dodatkowych funkcji w celu zapewnienia zgodności z poprzednimi wersjami.
Omówienie
Operacja jest logicznym elementem pracy uruchamianym przez aplikację. Ma on nazwę, czas rozpoczęcia, czas trwania, wynik i kontekst wykonywania, taki jak nazwa użytkownika, właściwości i wynik. Jeśli operacja A została zainicjowana przez operację B, operacja B jest ustawiona jako element nadrzędny dla A. Operacja może mieć tylko jeden element nadrzędny, ale może mieć wiele operacji podrzędnych. Aby uzyskać więcej informacji na temat operacji i korelacji telemetrii, zobacz Korelacja telemetrii usługi Application Insights.
W zestawie SDK platformy .NET usługi Application Insights operacja jest opisana przez abstrakcyjną klasę OperationTelemetry i jej elementy potomne RequestTelemetry i DependencyTelemetry.
Śledzenie operacji przychodzących
Zestaw SDK sieci Web usługi Application Insights automatycznie zbiera żądania HTTP dla aplikacji ASP.NET uruchamianych w potoku usług IIS i wszystkich aplikacji ASP.NET Core. Istnieją rozwiązania obsługiwane przez społeczność dla innych platform i struktur. Jeśli aplikacja nie jest obsługiwana przez żadne ze standardowych lub obsługiwanych przez społeczność rozwiązań, możesz przeprowadzić instrumentację ręcznie.
Innym przykładem, który wymaga śledzenia niestandardowego, jest proces roboczy, który odbiera elementy z kolejki. W przypadku niektórych kolejek wywołanie dodawania komunikatu do tej kolejki jest śledzone jako zależność. Operacja wysokiego poziomu, która opisuje przetwarzanie komunikatów, nie jest automatycznie zbierana.
Zobaczmy, jak można śledzić takie operacje.
Na wysokim poziomie zadaniem jest utworzenie RequestTelemetry
i ustawienie znanych właściwości. Po zakończeniu operacji można śledzić dane telemetryczne. W poniższym przykładzie pokazano to zadanie.
Żądanie HTTP w aplikacji hostowanej samodzielnie przez firmę Owin
W tym przykładzie kontekst śledzenia jest propagowany zgodnie z protokołem HTTP dla korelacji. Należy spodziewać się otrzymania nagłówków, które zostały tam opisane.
public class ApplicationInsightsMiddleware : OwinMiddleware
{
// You may create a new TelemetryConfiguration instance, reuse one you already have,
// or fetch the instance created by Application Insights SDK.
private readonly TelemetryConfiguration telemetryConfiguration = TelemetryConfiguration.CreateDefault();
private readonly TelemetryClient telemetryClient = new TelemetryClient(telemetryConfiguration);
public ApplicationInsightsMiddleware(OwinMiddleware next) : base(next) {}
public override async Task Invoke(IOwinContext context)
{
// Let's create and start RequestTelemetry.
var requestTelemetry = new RequestTelemetry
{
Name = $"{context.Request.Method} {context.Request.Uri.GetLeftPart(UriPartial.Path)}"
};
// If there is a Request-Id received from the upstream service, set the telemetry context accordingly.
if (context.Request.Headers.ContainsKey("Request-Id"))
{
var requestId = context.Request.Headers.Get("Request-Id");
// Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
requestTelemetry.Context.Operation.Id = GetOperationId(requestId);
requestTelemetry.Context.Operation.ParentId = requestId;
}
// StartOperation is a helper method that allows correlation of
// current operations with nested operations/telemetry
// and initializes start time and duration on telemetry items.
var operation = telemetryClient.StartOperation(requestTelemetry);
// Process the request.
try
{
await Next.Invoke(context);
}
catch (Exception e)
{
requestTelemetry.Success = false;
requestTelemetry.ResponseCode;
telemetryClient.TrackException(e);
throw;
}
finally
{
// Update status code and success as appropriate.
if (context.Response != null)
{
requestTelemetry.ResponseCode = context.Response.StatusCode.ToString();
requestTelemetry.Success = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
}
else
{
requestTelemetry.Success = false;
}
// Now it's time to stop the operation (and track telemetry).
telemetryClient.StopOperation(operation);
}
}
public static string GetOperationId(string id)
{
// Returns the root ID from the '|' to the first '.' if any.
int rootEnd = id.IndexOf('.');
if (rootEnd < 0)
rootEnd = id.Length;
int rootStart = id[0] == '|' ? 1 : 0;
return id.Substring(rootStart, rootEnd - rootStart);
}
}
Protokół HTTP dla korelacji deklaruje Correlation-Context
również nagłówek . Pominięto go tutaj dla uproszczenia.
Instrumentacja kolejki
Kontekst śledzenia W3C i protokół HTTP dla szczegółów korelacji przekazywania korelacji z żądaniami HTTP, ale każdy protokół kolejki musi określić, jak te same szczegóły są przekazywane wzdłuż komunikatu kolejki. Niektóre protokoły kolejki, takie jak AMQP, umożliwiają przekazywanie większej liczby metadanych. Inne protokoły, takie jak kolejka usługi Azure Storage, wymagają kodowania kontekstu w ładunku komunikatu.
Uwaga
Śledzenie między składnikami nie jest jeszcze obsługiwane w przypadku kolejek.
W przypadku protokołu HTTP, jeśli producent i odbiorca wysyłają dane telemetryczne do różnych zasobów usługi Application Insights, środowisko diagnostyki transakcji i mapa aplikacji pokazują transakcje i mapuj na koniec. W przypadku kolejek ta funkcja nie jest jeszcze obsługiwana.
Kolejka usługi Service Bus
Aby uzyskać informacje o śledzeniu, zobacz Śledzenie rozproszone i korelacja za pośrednictwem komunikatów usługi Azure Service Bus.
Kolejka usługi Azure Storage
W poniższym przykładzie pokazano, jak śledzić operacje kolejki usługi Azure Storage i korelować dane telemetryczne między producentem, konsumentem i usługą Azure Storage.
Kolejka usługi Storage ma interfejs API HTTP. Wszystkie wywołania kolejki są śledzone przez moduł zbierający zależności usługi Application Insights dla żądań HTTP. Jest ona domyślnie konfigurowana w aplikacjach ASP.NET i ASP.NET Core. W przypadku innych rodzajów aplikacji zapoznaj się z dokumentacją aplikacji konsolowych.
Możesz również skorelować identyfikator operacji usługi Application Insights z identyfikatorem żądania magazynu. Aby uzyskać informacje na temat ustawiania i pobierania klienta żądania magazynu oraz identyfikatora żądania serwera, zobacz Monitorowanie, diagnozowanie i rozwiązywanie problemów z usługą Azure Storage.
Kolejka
Ponieważ kolejki usługi Storage obsługują interfejs API HTTP, wszystkie operacje z kolejką są automatycznie śledzone przez usługę Application Insights. W wielu przypadkach instrumentacja ta powinna wystarczyć. Aby skorelować ślady po stronie konsumenta ze śladami producenta, należy przekazać jakiś kontekst korelacji podobnie do tego, jak robimy to w protokole HTTP dla korelacji.
W tym przykładzie pokazano, jak śledzić operację Enqueue
. Masz następujące możliwości:
- Koreluj ponawianie prób (jeśli istnieje): wszystkie mają jeden wspólny element nadrzędny, który jest operacją
Enqueue
. W przeciwnym razie są one śledzone jako elementy podrzędne żądania przychodzącego. Jeśli istnieje wiele logicznych żądań do kolejki, może być trudno znaleźć wywołanie, które spowodowało ponowne próby. - Skoreluj dzienniki magazynu (w razie potrzeby): są one skorelowane z telemetrią usługi Application Insights.
Operacja Enqueue
jest elementem podrzędnym operacji nadrzędnej. Przykładem jest przychodzące żądanie HTTP. Wywołanie zależności HTTP jest elementem podrzędnym Enqueue
operacji i wnukiem żądania przychodzącego.
public async Task Enqueue(CloudQueue queue, string message)
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>("enqueue " + queue.Name);
operation.Telemetry.Type = "Azure queue";
operation.Telemetry.Data = "Enqueue " + queue.Name;
// MessagePayload represents your custom message and also serializes correlation identifiers into payload.
// For example, if you choose to pass payload serialized to JSON, it might look like
// {'RootId' : 'some-id', 'ParentId' : '|some-id.1.2.3.', 'message' : 'your message to process'}
var jsonPayload = JsonConvert.SerializeObject(new MessagePayload
{
RootId = operation.Telemetry.Context.Operation.Id,
ParentId = operation.Telemetry.Id,
Payload = message
});
CloudQueueMessage queueMessage = new CloudQueueMessage(jsonPayload);
// Add operation.Telemetry.Id to the OperationContext to correlate Storage logs and Application Insights telemetry.
OperationContext context = new OperationContext { ClientRequestID = operation.Telemetry.Id};
try
{
await queue.AddMessageAsync(queueMessage, null, null, new QueueRequestOptions(), context);
}
catch (StorageException e)
{
operation.Telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
operation.Telemetry.Success = false;
operation.Telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
telemetryClient.TrackException(e);
}
finally
{
// Update status code and success as appropriate.
telemetryClient.StopOperation(operation);
}
}
Aby zmniejszyć ilość danych telemetrycznych raportów aplikacji lub jeśli nie chcesz śledzić Enqueue
operacji z innych powodów, użyj interfejsu Activity
API bezpośrednio:
- Utwórz (i uruchom) nową
Activity
zamiast rozpoczynać operację usługi Application Insights. Nie trzeba przypisywać żadnych właściwości z wyjątkiem nazwy operacji. - Serializuj
yourActivity.Id
w ładunku komunikatu zamiastoperation.Telemetry.Id
. Możesz również użyć poleceniaActivity.Current.Id
.
Usuwanie z kolejki
Podobnie jak Enqueue
w przypadku usługi Application Insights, rzeczywiste żądanie HTTP do kolejki usługi Storage jest automatycznie śledzone przez usługę Application Insights. Prawdopodobnie Enqueue
operacja odbywa się w kontekście nadrzędnym, takim jak kontekst żądania przychodzącego. Zestawy SDK usługi Application Insights automatycznie skorelują taką operację i jej część HTTP z żądaniem nadrzędnym i innymi danymi telemetrycznymi zgłoszonymi w tym samym zakresie.
Operacja Dequeue
jest trudna. Zestaw SDK usługi Application Insights automatycznie śledzi żądania HTTP. Nie wie jednak kontekstu korelacji, dopóki komunikat nie zostanie przeanalizowany. Nie można skorelować żądania HTTP w celu pobrania komunikatu z pozostałą częścią telemetrii, zwłaszcza w przypadku odebrania więcej niż jednego komunikatu.
public async Task<MessagePayload> Dequeue(CloudQueue queue)
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>("dequeue " + queue.Name);
operation.Telemetry.Type = "Azure queue";
operation.Telemetry.Data = "Dequeue " + queue.Name;
try
{
var message = await queue.GetMessageAsync();
}
catch (StorageException e)
{
operation.telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
operation.telemetry.Success = false;
operation.telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
telemetryClient.TrackException(e);
}
finally
{
// Update status code and success as appropriate.
telemetryClient.StopOperation(operation);
}
return null;
}
Przetwarzaj
W poniższym przykładzie komunikat przychodzący jest śledzony w sposób podobny do przychodzącego żądania HTTP:
public async Task Process(MessagePayload message)
{
// After the message is dequeued from the queue, create RequestTelemetry to track its processing.
RequestTelemetry requestTelemetry = new RequestTelemetry { Name = "process " + queueName };
// It might also make sense to get the name from the message.
requestTelemetry.Context.Operation.Id = message.RootId;
requestTelemetry.Context.Operation.ParentId = message.ParentId;
var operation = telemetryClient.StartOperation(requestTelemetry);
try
{
await ProcessMessage();
}
catch (Exception e)
{
telemetryClient.TrackException(e);
throw;
}
finally
{
// Update status code and success as appropriate.
telemetryClient.StopOperation(operation);
}
}
Podobnie można instrumentować inne operacje kolejki. Operację wglądu należy instrumentować w podobny sposób jak operacja dequeue. Instrumentacja operacji zarządzania kolejkami nie jest konieczna. Usługa Application Insights śledzi operacje, takie jak HTTP, a w większości przypadków wystarczy.
Podczas instrumentowania usuwania komunikatów upewnij się, że ustawiono identyfikatory operacji (korelacji). Alternatywnie możesz użyć interfejsu Activity
API. Następnie nie musisz ustawiać identyfikatorów operacji na elementach telemetrii, ponieważ zestaw SDK usługi Application Insights wykonuje następujące czynności:
- Utwórz nowy
Activity
element po utworzeniu elementu z kolejki. - Służy
Activity.SetParentId(message.ParentId)
do korelowania dzienników konsumentów i producentów. - Uruchom plik
Activity
. - Śledzenie operacji usuwania z kolejki, przetwarzania i usuwania przy użyciu
Start/StopOperation
pomocników. Zrób to z tego samego przepływu sterowania asynchronicznego (kontekstu wykonywania). W ten sposób są one prawidłowo skorelowane. - Zatrzymaj element
Activity
. - Ręczne używanie
Start/StopOperation
danych telemetrycznych lub wywoływanieTrack
ich.
Typy zależności
Usługa Application Insights używa typu zależności do dostosowywania środowisk interfejsu użytkownika. W przypadku kolejek rozpoznaje następujące typy DependencyTelemetry
, które zwiększają środowisko diagnostyki transakcji:
Azure queue
dla kolejek usługi Azure StorageAzure Event Hubs
dla usługi Azure Event HubsAzure Service Bus
dla usługi Azure Service Bus
Przetwarzanie wsadowe
W przypadku niektórych kolejek można usunąć kolejkę wielu komunikatów z jednym żądaniem. Przetwarzanie takich komunikatów jest prawdopodobnie niezależne i należy do różnych operacji logicznych. Nie można skorelować Dequeue
operacji z przetwarzanym konkretnym komunikatem.
Każdy komunikat powinien być przetwarzany we własnym asynchronicznym przepływie sterowania. Aby uzyskać więcej informacji, zobacz sekcję Śledzenie zależności wychodzących.
Długotrwałe zadania w tle
Niektóre aplikacje uruchamiają długotrwałe operacje, które mogą być spowodowane żądaniami użytkowników. Z perspektywy śledzenia/instrumentacji nie różni się ona od instrumentacji żądań lub zależności:
async Task BackgroundTask()
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>(taskName);
operation.Telemetry.Type = "Background";
try
{
int progress = 0;
while (progress < 100)
{
// Process the task.
telemetryClient.TrackTrace($"done {progress++}%");
}
// Update status code and success as appropriate.
}
catch (Exception e)
{
telemetryClient.TrackException(e);
// Update status code and success as appropriate.
throw;
}
finally
{
telemetryClient.StopOperation(operation);
}
}
W tym przykładzie telemetryClient.StartOperation
tworzy DependencyTelemetry
i wypełnia kontekst korelacji. Załóżmy, że masz operację nadrzędną, która została utworzona przez przychodzące żądania, które planowały operację. Tak długo, jak BackgroundTask
rozpoczyna się w tym samym przepływie sterowania asynchronicznym co żądanie przychodzące, jest skorelowany z tą operacją nadrzędną. BackgroundTask
i wszystkie zagnieżdżone elementy telemetrii są automatycznie skorelowane z żądaniem, które je spowodowało, nawet po zakończeniu żądania.
Gdy zadanie rozpoczyna się od wątku w tle, który nie ma żadnej operacji (Activity
) skojarzonej z nim, BackgroundTask
nie ma żadnego elementu nadrzędnego. Może jednak mieć zagnieżdżone operacje. Wszystkie elementy telemetrii zgłoszone z zadania są skorelowane z utworzonym elementem DependencyTelemetry
w programie BackgroundTask
.
Śledzenie zależności wychodzących
Możesz śledzić własny rodzaj zależności lub operację, która nie jest obsługiwana przez usługę Application Insights.
Enqueue
Metoda w kolejce usługi Service Bus lub w kolejce usługi Storage może służyć jako przykłady takiego śledzenia niestandardowego.
Ogólne podejście do niestandardowego śledzenia zależności polega na następujących celach:
- Wywołaj metodę
TelemetryClient.StartOperation
(extension), która wypełniaDependencyTelemetry
właściwości wymagane do korelacji i innych właściwości, takich jak start, sygnatura czasowa i czas trwania. - Ustaw inne właściwości niestandardowe na
DependencyTelemetry
obiekcie , takie jak nazwa i dowolny inny kontekst, którego potrzebujesz. - Utwórz wywołanie zależności i poczekaj na to.
- Zatrzymaj operację
StopOperation
po zakończeniu. - Obsługa wyjątków.
public async Task RunMyTaskAsync()
{
using (var operation = telemetryClient.StartOperation<DependencyTelemetry>("task 1"))
{
try
{
var myTask = await StartMyTaskAsync();
// Update status code and success as appropriate.
}
catch(...)
{
// Update status code and success as appropriate.
}
}
}
Usuwanie operacji powoduje zatrzymanie operacji, więc można to zrobić zamiast wywoływać StopOperation
.
Ostrzeżenie
W niektórych przypadkach nieobsługiwany wyjątek może uniemożliwić finally
wywoływanie, więc operacje mogą nie być śledzone.
Przetwarzanie i śledzenie operacji równoległych
Wywołanie StopOperation
zatrzymuje tylko uruchomioną operację. Jeśli bieżąca uruchomiona operacja jest niezgodna z bieżącą operacją, którą chcesz zatrzymać, StopOperation
nic nie robi. Taka sytuacja może wystąpić, jeśli równolegle uruchomisz wiele operacji w tym samym kontekście wykonywania.
var firstOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 1");
var firstTask = RunMyTaskAsync();
var secondOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 2");
var secondTask = RunMyTaskAsync();
await firstTask;
// FAILURE!!! This will do nothing and will not report telemetry for the first operation
// as currently secondOperation is active.
telemetryClient.StopOperation(firstOperation);
await secondTask;
Upewnij się, że zawsze wywołujesz StartOperation
operację i przetwarzasz operację w tej samej metodzie asynchronicznej , aby odizolować operacje uruchomione równolegle. Jeśli operacja jest synchroniczna (lub nie asynchroniczna), opakuj proces i śledź za pomocą polecenia Task.Run
.
public void RunMyTask(string name)
{
using (var operation = telemetryClient.StartOperation<DependencyTelemetry>(name))
{
Process();
// Update status code and success as appropriate.
}
}
public async Task RunAllTasks()
{
var task1 = Task.Run(() => RunMyTask("task 1"));
var task2 = Task.Run(() => RunMyTask("task 2"));
await Task.WhenAll(task1, task2);
}
Operacje usługi ApplicationInsights a System.Diagnostics.Activity
System.Diagnostics.Activity
reprezentuje kontekst śledzenia rozproszonego i jest używany przez struktury i biblioteki do tworzenia i propagowania kontekstu wewnątrz i poza procesem oraz korelowania elementów telemetrii. Activity
współpracuje ze sobą jako mechanizm powiadamiania między strukturą System.Diagnostics.DiagnosticSource
/biblioteką w celu powiadamiania o interesujących zdarzeniach, takich jak przychodzące lub wychodzące żądania i wyjątki.
Działania są obywatelami pierwszej klasy w usłudze Application Insights. Automatyczne zależności i zbieranie żądań polegają na nich w dużym stopniu wraz ze zdarzeniami DiagnosticSource
. Jeśli utworzono Activity
aplikację, nie spowoduje to utworzenia telemetrii usługi Application Insights. Usługa Application Insights musi odbierać DiagnosticSource
zdarzenia i znać nazwy zdarzeń i ładunki, aby przetłumaczyć je Activity
na dane telemetryczne.
Każda operacja usługi Application Insights (żądanie lub zależność) obejmuje .Activity
Gdy StartOperation
jest wywoływany, tworzy Activity
pod spodem. StartOperation
to zalecany sposób ręcznego śledzenia telemetrii żądań lub zależności i upewnienia się, że wszystko jest skorelowane.
Następne kroki
- Poznaj podstawy korelacji telemetrii w usłudze Application Insights.
- Sprawdź, jak skorelowane dane zasilają środowisko diagnostyki transakcji i mapę aplikacji.
- Zobacz model danych dla typów usługi Application Insights i modelu danych.
- Zgłaszanie zdarzeń niestandardowych i metryk do usługi Application Insights.
- Zapoznaj się ze standardową konfiguracją kolekcji właściwości kontekstu.
- Zapoznaj się z podręcznikiem użytkownika System.Diagnostics.Activity, aby zobaczyć, jak korelujemy dane telemetryczne.