Aangepaste bewerkingen bijhouden met Application Insights .NET SDK
Application Insights SDK's volgen automatisch binnenkomende HTTP-aanvragen en aanroepen naar afhankelijke services, zoals HTTP-aanvragen en SQL-query's. Bijhouden en correlatie van aanvragen en afhankelijkheden geven u inzicht in de reactiesnelheid en betrouwbaarheid van de hele toepassing voor alle microservices die deze toepassing combineren.
Er is een klasse toepassingspatronen die algemeen niet kunnen worden ondersteund. Voor een goede bewaking van dergelijke patronen is handmatige code-instrumentatie vereist. Dit artikel bevat een aantal patronen waarvoor handmatige instrumentatie is vereist, zoals het verwerken van aangepaste wachtrijen en het uitvoeren van langlopende achtergrondtaken.
Dit artikel bevat richtlijnen voor het bijhouden van aangepaste bewerkingen met de Application Insights SDK. Deze documentatie is relevant voor:
- Application Insights voor .NET (ook wel bekend als Base SDK) versie 2.4+.
- Application Insights voor webtoepassingen (met ASP.NET) versie 2.4+.
- Application Insights voor ASP.NET Core versie 2.1+.
Notitie
De volgende documentatie is afhankelijk van de klassieke Application Insights-API. Het langetermijnplan voor Application Insights is het verzamelen van gegevens met behulp van OpenTelemetry. Zie Azure Monitor OpenTelemetry inschakelen voor .NET-, Node.js-, Python- en Java-toepassingen en onze OpenTelemetry Roadmap voor meer informatie. Migratierichtlijnen zijn beschikbaar voor .NET, Node.js en Python.
Overzicht
Een bewerking is een logisch werk dat door een toepassing wordt uitgevoerd. Het heeft een naam, begintijd, duur, resultaat en een context van uitvoering, zoals gebruikersnaam, eigenschappen en resultaat. Als bewerking A is gestart door bewerking B, wordt bewerking B ingesteld als een bovenliggend item voor A. Een bewerking kan slechts één bovenliggende bewerking hebben, maar kan veel onderliggende bewerkingen hebben. Zie Application Insights-telemetriecorrelatie voor meer informatie over bewerkingen en telemetriecorrelatie.
In de .NET SDK van Application Insights wordt de bewerking beschreven door de abstracte klasse OperationTelemetry en de onderliggende RequestTelemetry en DependencyTelemetry.
Bijhouden van binnenkomende bewerkingen
De Application Insights-web-SDK verzamelt automatisch HTTP-aanvragen voor ASP.NET toepassingen die worden uitgevoerd in een IIS-pijplijn en alle ASP.NET Core-toepassingen. Er zijn door de community ondersteunde oplossingen voor andere platforms en frameworks. Als de toepassing niet wordt ondersteund door een van de standaard- of door de community ondersteunde oplossingen, kunt u deze handmatig instrumenteren.
Een ander voorbeeld waarvoor aangepaste tracering is vereist, is de werkrol die items uit de wachtrij ontvangt. Voor sommige wachtrijen wordt de aanroep om een bericht aan deze wachtrij toe te voegen, bijgehouden als een afhankelijkheid. De bewerking op hoog niveau waarin berichtverwerking wordt beschreven, wordt niet automatisch verzameld.
Laten we eens kijken hoe dergelijke bewerkingen kunnen worden bijgehouden.
Op hoog niveau is de taak het maken RequestTelemetry
en instellen van bekende eigenschappen. Nadat de bewerking is voltooid, houdt u de telemetrie bij. In het volgende voorbeeld ziet u deze taak.
HTTP-aanvraag in zelf-hostende Owin-app
In dit voorbeeld wordt traceringscontext doorgegeven volgens het HTTP-protocol voor correlatie. U kunt verwachten dat er headers worden weergegeven die daar worden beschreven.
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);
}
}
Het HTTP-protocol voor correlatie declareert ook de Correlation-Context
header. Het wordt hier weggelaten om het eenvoudig te maken.
Wachtrij-instrumentatie
Het W3C-traceringscontext en HTTP-protocol voor correlatiegegevens doorgeven aan HTTP-aanvragen, maar elk wachtrijprotocol moet definiëren hoe dezelfde details worden doorgegeven aan het wachtrijbericht. Sommige wachtrijprotocollen, zoals AMQP, staan het doorgeven van meer metagegevens toe. Voor andere protocollen, zoals Azure Storage Queue, moet de context worden gecodeerd in de nettolading van het bericht.
Notitie
Tracering tussen onderdelen wordt nog niet ondersteund voor wachtrijen.
Als uw producent en consument telemetrie verzenden naar verschillende Application Insights-resources, worden transacties weergegeven en end-to-end toegewezen met BEHULP van HTTP. In het geval van wachtrijen wordt deze mogelijkheid nog niet ondersteund.
Service Bus-wachtrij
Zie gedistribueerde tracering en correlatie via Azure Service Bus-berichten voor traceringsinformatie.
Azure Storage-wachtrij
In het volgende voorbeeld ziet u hoe u de bewerkingen in de Azure Storage-wachtrij kunt bijhouden en telemetrie kunt correleren tussen de producent, de consument en Azure Storage.
De Storage-wachtrij heeft een HTTP-API. Alle aanroepen naar de wachtrij worden bijgehouden door de Application Insights Dependency Collector voor HTTP-aanvragen. Deze is standaard geconfigureerd voor ASP.NET- en ASP.NET Core-toepassingen. Zie de documentatie voor Console-toepassingen voor andere soorten toepassingen.
Mogelijk wilt u ook de Application Insights-bewerkings-id correleren met de opslagaanvraag-id. Zie Azure Storage controleren, diagnosticeren en problemen oplossen voor informatie over het instellen en ophalen van een opslagaanvraagclient en een serveraanvraag-id.
Enqueue
Omdat Storage-wachtrijen ondersteuning bieden voor de HTTP-API, worden alle bewerkingen met de wachtrij automatisch bijgehouden door Application Insights. In veel gevallen moet deze instrumentatie voldoende zijn. Als u traceringen aan de consumentenzijde wilt correleren met producertraceringen, moet u een bepaalde correlatiecontext doorgeven op dezelfde manier als in het HTTP-protocol voor correlatie.
In dit voorbeeld ziet u hoe u de Enqueue
bewerking kunt bijhouden. U kunt:
- Retries correleren (indien aanwezig): ze hebben allemaal één veelvoorkomend bovenliggend element dat de
Enqueue
bewerking is. Anders worden ze bijgehouden als onderliggende items van de binnenkomende aanvraag. Als er meerdere logische aanvragen naar de wachtrij zijn, kan het lastig zijn om te vinden welke aanroep heeft geresulteerd in nieuwe pogingen. - Opslaglogboeken correleren (indien en indien nodig): ze zijn gecorreleerd met Application Insights-telemetrie.
De Enqueue
bewerking is het onderliggende element van een bovenliggende bewerking. Een voorbeeld hiervan is een binnenkomende HTTP-aanvraag. De HTTP-afhankelijkheidsaanroep is het onderliggende element van de Enqueue
bewerking en het kleinkind van de binnenkomende aanvraag.
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);
}
}
Als u de hoeveelheid telemetrie van uw toepassingsrapporten wilt verminderen of als u de Enqueue
bewerking om andere redenen niet wilt bijhouden, gebruikt u de Activity
API rechtstreeks:
- Maak (en start) een nieuwe
Activity
in plaats van de Application Insights-bewerking te starten. U hoeft er geen eigenschappen aan toe te wijzen, behalve de naam van de bewerking. - Serialiseer
yourActivity.Id
in de nettolading van het bericht in plaats vanoperation.Telemetry.Id
. U kunt ook .Activity.Current.Id
Uit wachtrij verwijderen
Op dezelfde manier Enqueue
wordt een werkelijke HTTP-aanvraag voor de opslagwachtrij automatisch bijgehouden door Application Insights. De Enqueue
bewerking vindt waarschijnlijk plaats in de bovenliggende context, zoals een context voor binnenkomende aanvragen. Application Insights SDK's correleren automatisch een dergelijke bewerking en het BIJBEHORENDE HTTP-onderdeel, met de bovenliggende aanvraag en andere telemetrie die in hetzelfde bereik worden gerapporteerd.
De Dequeue
operatie is lastig. De Application Insights SDK houdt automatisch HTTP-aanvragen bij. Maar de correlatiecontext is pas bekend als het bericht is geparseerd. Het is niet mogelijk om de HTTP-aanvraag te correleren om het bericht op te halen met de rest van de telemetrie, met name wanneer er meer dan één bericht wordt ontvangen.
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;
}
Proces
In het volgende voorbeeld wordt een binnenkomend bericht bijgehouden op een manier die vergelijkbaar is met een binnenkomende HTTP-aanvraag:
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);
}
}
Op dezelfde manier kunnen andere wachtrijbewerkingen worden geïnstrueerd. Een peek-bewerking moet op een vergelijkbare manier worden geïnstrueerd als een dequeue-bewerking. Het instrumenteren van wachtrijbeheerbewerkingen is niet nodig. Application Insights houdt bewerkingen zoals HTTP bij en in de meeste gevallen is dit voldoende.
Wanneer u berichtverwijdering instrumenteert, moet u de bewerkings-id's (correlatie- id's) instellen. U kunt ook de Activity
API gebruiken. Vervolgens hoeft u geen bewerkings-id's in te stellen voor de telemetrie-items, omdat de Application Insights SDK dit voor u doet:
- Maak een nieuw
Activity
item nadat u een item uit de wachtrij hebt. - Gebruik
Activity.SetParentId(message.ParentId)
dit om consumenten- en producentlogboeken te correleren. - Start de
Activity
. - Volg dequeue-, proces- en verwijderbewerkingen met behulp van
Start/StopOperation
helpers. Doe dit vanuit dezelfde asynchrone controlestroom (uitvoeringscontext). Op deze manier worden ze correct gecorreleerd. - Stop de
Activity
. - Telemetrie handmatig gebruiken
Start/StopOperation
of aanroepenTrack
.
Afhankelijkheidstypen
Application Insights maakt gebruik van het afhankelijkheidstype om gebruikersinterface-ervaringen aan te passen. Voor wachtrijen worden de volgende typen DependencyTelemetry
herkend die de diagnostische ervaring voor transacties verbeteren:
Azure queue
voor Azure Storage-wachtrijenAzure Event Hubs
voor Azure Event HubsAzure Service Bus
voor Azure Service Bus
Batchverwerking
Met sommige wachtrijen kunt u meerdere berichten uit de wachtrij verwijderen met één aanvraag. Het verwerken van dergelijke berichten is vermoedelijk onafhankelijk en behoort tot de verschillende logische bewerkingen. Het is niet mogelijk om de Dequeue
bewerking te correleren met een bepaald bericht dat wordt verwerkt.
Elk bericht moet worden verwerkt in een eigen asynchrone controlestroom. Zie de sectie Voor het bijhouden van uitgaande afhankelijkheden voor meer informatie.
Langlopende achtergrondtaken
Sommige toepassingen starten langdurige bewerkingen die mogelijk worden veroorzaakt door gebruikersaanvragen. Vanuit het perspectief van tracering/instrumentatie is dit niet anders dan aanvraag- of afhankelijkheidsinstrumentatie:
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);
}
}
In dit voorbeeld telemetryClient.StartOperation
wordt de correlatiecontext gemaakt DependencyTelemetry
en ingevuld. Stel dat u een bovenliggende bewerking hebt die is gemaakt door binnenkomende aanvragen die de bewerking hebben gepland. Zolang BackgroundTask
het begint in dezelfde asynchrone controlestroom als een binnenkomende aanvraag, wordt deze gecorreleerd met die bovenliggende bewerking. BackgroundTask
en alle geneste telemetrie-items worden automatisch gecorreleerd met de aanvraag die dit heeft veroorzaakt, zelfs nadat de aanvraag is beëindigd.
Wanneer de taak begint vanaf de achtergrondthread waaraan geen bewerking (Activity
) is gekoppeld, BackgroundTask
is er geen bovenliggend item. Het kan echter geneste bewerkingen hebben. Alle telemetrie-items die van de taak worden gerapporteerd, worden gecorreleerd aan de DependencyTelemetry
gemaakte in BackgroundTask
.
Bijhouden van uitgaande afhankelijkheden
U kunt uw eigen soort afhankelijkheid bijhouden of een bewerking die niet wordt ondersteund door Application Insights.
De Enqueue
methode in de Service Bus-wachtrij of de opslagwachtrij kan fungeren als voorbeelden voor dergelijke aangepaste tracering.
De algemene benadering voor het bijhouden van aangepaste afhankelijkheid is het volgende:
- Roep de
TelemetryClient.StartOperation
methode (extensie) aan die deDependencyTelemetry
eigenschappen vult die nodig zijn voor correlatie en een aantal andere eigenschappen, zoals begin, tijdstempel en duur. - Stel andere aangepaste eigenschappen in op de
DependencyTelemetry
naam, zoals de naam en eventuele andere context die u nodig hebt. - Maak een afhankelijkheidsaanroep en wacht erop.
- Stop de bewerking met
StopOperation
wanneer deze is voltooid. - Uitzonderingen verwerken.
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.
}
}
}
Als u een bewerking opstelt, wordt de bewerking gestopt, dus u kunt dit doen in plaats van aanroepen StopOperation
.
Waarschuwing
In sommige gevallen kan een niet-verwerkte uitzondering voorkomen dat finally
deze wordt aangeroepen, zodat bewerkingen mogelijk niet worden bijgehouden.
Parallelle bewerkingen verwerken en bijhouden
Het aanroepen StopOperation
stopt alleen de bewerking die is gestart. Als de huidige actieve bewerking niet overeenkomt met de bewerking die u wilt stoppen, StopOperation
doet u niets. Deze situatie kan optreden als u meerdere bewerkingen parallel start in dezelfde uitvoeringscontext.
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;
Zorg ervoor dat u de bewerking altijd aanroept StartOperation
en verwerkt in dezelfde asynchrone methode om bewerkingen die parallel worden uitgevoerd, te isoleren. Als de bewerking synchroon (of niet asynchroon) is, verpakt u het proces en houdt u het bij met 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);
}
ApplicationInsights-bewerkingen versus System.Diagnostics.Activity
System.Diagnostics.Activity
vertegenwoordigt de context voor gedistribueerde tracering en wordt gebruikt door frameworks en bibliotheken om context binnen en buiten het proces te maken en door te geven en telemetrie-items te correleren. Activity
werkt samen met System.Diagnostics.DiagnosticSource
het meldingsmechanisme tussen het framework/de bibliotheek om te informeren over interessante gebeurtenissen, zoals binnenkomende of uitgaande aanvragen en uitzonderingen.
Activiteiten zijn eersteklas burgers in Application Insights. Automatische afhankelijkheid en aanvraagverzameling zijn sterk afhankelijk van deze, samen met DiagnosticSource
gebeurtenissen. Als u in uw toepassing hebt gemaakt Activity
, zou dit er niet toe leiden dat application Insights-telemetrie wordt gemaakt. Application Insights moet gebeurtenissen ontvangen DiagnosticSource
en weten welke namen en nettoladingen van gebeurtenissen moeten worden omgezet Activity
in telemetrie.
Elke Application Insights-bewerking (aanvraag of afhankelijkheid) omvat Activity
. Wanneer StartOperation
deze wordt aangeroepen, wordt deze eronder gemaakt Activity
. StartOperation
is de aanbevolen manier om aanvraag- of afhankelijkheidstelemetrieën handmatig bij te houden en ervoor te zorgen dat alles is gecorreleerd.
Volgende stappen
- Meer informatie over de basisbeginselen van telemetriecorrelatie in Application Insights.
- Bekijk hoe gecorreleerde gegevens de ervaring voor transactiediagnose en application map mogelijk maken.
- Bekijk het gegevensmodel voor Application Insights-typen en -gegevensmodellen.
- Aangepaste gebeurtenissen en metrische gegevens rapporteren aan Application Insights.
- Bekijk de standaardconfiguratie voor verzameling contexteigenschappen.
- Raadpleeg de gebruikershandleiding System.Diagnostics.Activity om te zien hoe telemetrie wordt gecorreleerd.