Spåra anpassade åtgärder med Application Insights .NET SDK
Application Insights SDK:er spårar automatiskt inkommande HTTP-begäranden och anrop till beroende tjänster, till exempel HTTP-begäranden och SQL-frågor. Spårning och korrelation av begäranden och beroenden ger dig insyn i hela programmets svarstider och tillförlitlighet för alla mikrotjänster som kombinerar det här programmet.
Det finns en klass med programmönster som inte kan stödjas allmänt. Korrekt övervakning av sådana mönster kräver manuell kodinstrumentation. Den här artikeln beskriver några mönster som kan kräva manuell instrumentering, till exempel anpassad köbearbetning och tidskrävande bakgrundsuppgifter.
Den här artikeln innehåller vägledning om hur du spårar anpassade åtgärder med Application Insights SDK. Den här dokumentationen är relevant för:
- Application Insights för .NET (även kallat Base SDK) version 2.4+.
- Application Insights för webbprogram (som kör ASP.NET) version 2.4+.
- Application Insights för ASP.NET Core version 2.1+.
Varning
Vi rekommenderar Azure Monitor OpenTelemetry Distro för nya program eller kunder för att driva Azure Monitor Application Insights. Azure Monitor OpenTelemetry Distro ger en liknande funktion och upplevelse som Application Insights SDK. Det går att migrera från Application Insights SDK med hjälp av migreringsguiderna för .NET, Node.js och Python, men vi arbetar fortfarande med att lägga till ytterligare några funktioner för bakåtkompatibilitet.
Översikt
En åtgärd är ett logiskt arbete som körs av ett program. Den har ett namn, starttid, varaktighet, resultat och en kontext för körning som användarnamn, egenskaper och resultat. Om åtgärd A initierades av åtgärd B anges åtgärd B som överordnad för A. En åtgärd kan bara ha en överordnad åtgärd, men den kan ha många underordnade åtgärder. Mer information om åtgärder och telemetrikorrelation finns i Application Insights telemetrikorrelation.
I Application Insights .NET SDK beskrivs åtgärden av den abstrakta klassen OperationTelemetry och dess underordnade RequestTelemetry och DependencyTelemetry.
Spårning av inkommande åtgärder
Application Insights webb-SDK samlar automatiskt in HTTP-begäranden för ASP.NET program som körs i en IIS-pipeline och alla ASP.NET Core-program. Det finns lösningar som stöds av communityn för andra plattformar och ramverk. Om programmet inte stöds av någon av de standardlösningar eller lösningar som stöds av communityn kan du instrumentera det manuellt.
Ett annat exempel som kräver anpassad spårning är arbetaren som tar emot objekt från kön. För vissa köer spåras anropet för att lägga till ett meddelande i den här kön som ett beroende. Den övergripande åtgärd som beskriver meddelandebearbetning samlas inte in automatiskt.
Nu ska vi se hur sådana åtgärder kan spåras.
På hög nivå är uppgiften att skapa RequestTelemetry
och ange kända egenskaper. När åtgärden är klar spårar du telemetrin. I följande exempel visas den här uppgiften.
HTTP-begäran i en lokalt installerad Owin-app
I det här exemplet sprids spårningskontexten enligt HTTP-protokollet för korrelation. Du bör förvänta dig att få rubriker som beskrivs där.
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);
}
}
HTTP-protokollet för korrelation deklarerar Correlation-Context
också huvudet. Det utelämnas här för enkelhetens skull.
Köinstrumentation
W3C-spårningskontexten och HTTP-protokollet för korrelationspasskorrelationsinformation med HTTP-begäranden, men varje köprotokoll måste definiera hur samma information skickas längs kömeddelandet. Vissa köprotokoll, till exempel AMQP, tillåter överföring av fler metadata. Andra protokoll, till exempel Azure Storage Queue, kräver att kontexten kodas i meddelandets nyttolast.
Kommentar
Spårning mellan komponenter stöds inte för köer ännu.
Med HTTP, om din producent och konsument skickar telemetri till olika Application Insights-resurser, visar transaktionsdiagnostikupplevelsen och Programkarta transaktioner och mappar från slutpunkt till slutpunkt. När det gäller köer stöds inte den här funktionen ännu.
Service Bus-kö
Information om spårning finns i Distribuerad spårning och korrelation via Azure Service Bus-meddelanden.
Azure Storage-kö
I följande exempel visas hur du spårar Azure Storage-köåtgärderna och korrelerar telemetri mellan producenten, konsumenten och Azure Storage.
Lagringskön har ett HTTP-API. Alla anrop till kön spåras av Application Insights Dependency Collector för HTTP-begäranden. Den konfigureras som standard för ASP.NET- och ASP.NET Core-program. Med andra typer av program kan du läsa dokumentationen om konsolprogram.
Du kanske också vill korrelera Application Insights-åtgärds-ID:t med ID:t för lagringsbegäran. Information om hur du anger och hämtar en klient för lagringsbegäran och ett serverbegärans-ID finns i Övervaka, diagnostisera och felsöka Azure Storage.
Enqueue
Eftersom Lagringsköer stöder HTTP-API:et spåras alla åtgärder med kön automatiskt av Application Insights. I många fall bör den här instrumentationen vara tillräcklig. För att korrelera spårningar på konsumentsidan med producentspårningar måste du skicka en korrelationskontext som liknar hur vi gör det i HTTP-protokollet för korrelation.
Det här exemplet visar hur du spårar åtgärden Enqueue
. Du kan:
- Korrelera återförsök (om några): De har alla en gemensam överordnad som är åtgärden
Enqueue
. Annars spåras de som underordnade till den inkommande begäran. Om det finns flera logiska begäranden till kön kan det vara svårt att hitta vilket anrop som resulterade i återförsök. - Korrelera lagringsloggar (om och när det behövs): De korreleras med Application Insights-telemetri.
Åtgärden Enqueue
är underordnad en överordnad åtgärd. Ett exempel är en inkommande HTTP-begäran. HTTP-beroendeanropet är underordnad åtgärden Enqueue
och barnbarnet till den inkommande begäran.
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);
}
}
Om du vill minska mängden telemetri i dina programrapporter eller om du inte vill spåra Enqueue
åtgärden av andra skäl använder du API:et Activity
direkt:
- Skapa (och starta) en ny
Activity
i stället för att starta Application Insights-åtgärden. Du behöver inte tilldela några egenskaper för den förutom åtgärdsnamnet. - Serialisera
yourActivity.Id
i meddelandets nyttolast i stället föroperation.Telemetry.Id
. Du kan också användaActivity.Current.Id
.
Inaktivera kö
Enqueue
På samma sätt spåras en faktisk HTTP-begäran till lagringskö automatiskt av Application Insights. Åtgärden Enqueue
sker förmodligen i den överordnade kontexten, till exempel en kontext för inkommande begäranden. Application Insights SDK:er korrelerar automatiskt en sådan åtgärd och dess HTTP-del med den överordnade begäran och annan telemetri som rapporteras i samma omfång.
Åtgärden Dequeue
är knepig. Application Insights SDK spårar automatiskt HTTP-begäranden. Men den känner inte till korrelationskontexten förrän meddelandet parsas. Det går inte att korrelera HTTP-begäran för att få meddelandet med resten av telemetrin, särskilt när fler än ett meddelande tas emot.
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;
}
Process
I följande exempel spåras ett inkommande meddelande på ett sätt som liknar en inkommande HTTP-begäran:
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);
}
}
På samma sätt kan andra köåtgärder instrumenteras. En granskningsåtgärd bör instrumenteras på ett liknande sätt som en dequeue-åtgärd. Instrumentering av köhanteringsåtgärder är inte nödvändigt. Application Insights spårar åtgärder som HTTP, och i de flesta fall räcker det.
När du instrumentera borttagning av meddelanden kontrollerar du att du anger åtgärdsidentifierarna (korrelation). Du kan också använda API:et Activity
. Sedan behöver du inte ange åtgärdsidentifierare för telemetriobjekten eftersom Application Insights SDK gör det åt dig:
- Skapa en ny
Activity
när du har fått ett objekt från kön. - Använd
Activity.SetParentId(message.ParentId)
för att korrelera konsument- och producentloggar. Activity
Starta .- Spåra dequeue-, process- och borttagningsåtgärder med hjälp av hjälpfunktioner
Start/StopOperation
. Gör det från samma asynkrona kontrollflöde (körningskontext). På så sätt korreleras de korrekt. Activity
Stoppa .- Använd
Start/StopOperation
eller anropaTrack
telemetri manuellt.
Beroendetyper
Application Insights använder beroendetyp för att anpassa användargränssnittsupplevelser. För köer identifieras följande typer av som förbättrar upplevelsen av DependencyTelemetry
transaktionsdiagnostik:
Azure queue
för Azure Storage-köerAzure Event Hubs
för Azure Event HubsAzure Service Bus
för Azure Service Bus
Batchbearbetning
Med vissa köer kan du ta bort flera meddelanden med en begäran. Bearbetningen av sådana meddelanden är förmodligen oberoende och tillhör de olika logiska åtgärderna. Det går inte att korrelera åtgärden Dequeue
med ett visst meddelande som bearbetas.
Varje meddelande ska bearbetas i sitt eget asynkrona kontrollflöde. Mer information finns i avsnittet Spårning av utgående beroenden.
Långvariga bakgrundsaktiviteter
Vissa program startar tidskrävande åtgärder som kan orsakas av användarbegäranden. Ur spårnings-/instrumentationsperspektivet skiljer det sig inte från instrumentation för begäran eller beroende:
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);
}
}
I det här exemplet telemetryClient.StartOperation
skapar DependencyTelemetry
och fyller korrelationskontexten. Anta att du har en överordnad åtgärd som skapades av inkommande begäranden som schemalagt åtgärden. Så länge som BackgroundTask
startar i samma asynkrona kontrollflöde som en inkommande begäran korreleras den med den överordnade åtgärden. BackgroundTask
och alla kapslade telemetriobjekt korreleras automatiskt med den begäran som orsakade den, även när begäran har avslutats.
När aktiviteten startar från bakgrundstråden som inte har någon åtgärd (Activity
) associerad med den, BackgroundTask
har den ingen överordnad. Den kan dock ha kapslade åtgärder. Alla telemetriobjekt som rapporteras från aktiviteten korreleras till de som skapats DependencyTelemetry
i BackgroundTask
.
Spårning av utgående beroenden
Du kan spåra din egen beroendetyp eller en åtgärd som inte stöds av Application Insights.
Metoden Enqueue
i Service Bus-kön eller lagringskön kan fungera som exempel för sådan anpassad spårning.
Den allmänna metoden för anpassad beroendespårning är att:
- Anropa metoden
TelemetryClient.StartOperation
(tillägg) som fyller deDependencyTelemetry
egenskaper som behövs för korrelation och vissa andra egenskaper, till exempel start, tidsstämpel och varaktighet. - Ange andra anpassade egenskaper för
DependencyTelemetry
, till exempel namnet och alla andra kontexter som du behöver. - Ring ett beroendeanrop och vänta på det.
- Stoppa åtgärden med
StopOperation
när den är klar. - Hantera undantag.
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.
}
}
}
Om du tar bort en åtgärd stoppas åtgärden, så du kan göra det i stället för att anropa StopOperation
.
Varning
I vissa fall kan ett ohanterat undantag förhindra finally
att anropas, så åtgärder kanske inte spåras.
Bearbetning och spårning av parallella åtgärder
Anrop StopOperation
stoppar bara den åtgärd som startades. Om den aktuella åtgärden som körs inte matchar den som du vill stoppa, StopOperation
gör ingenting. Den här situationen kan inträffa om du startar flera åtgärder parallellt i samma körningskontext.
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;
Se till att du alltid anropar StartOperation
och bearbetar åtgärden i samma asynkron metod för att isolera åtgärder som körs parallellt. Om åtgärden är synkron (eller inte asynkron), omsluter du processen och spårar med 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-åtgärder jämfört med System.Diagnostics.Activity
System.Diagnostics.Activity
representerar den distribuerade spårningskontexten och används av ramverk och bibliotek för att skapa och sprida kontext i och utanför processen och korrelera telemetriobjekt. Activity
fungerar tillsammans med System.Diagnostics.DiagnosticSource
som meddelandemekanism mellan ramverket/biblioteket för att meddela om intressanta händelser som inkommande eller utgående begäranden och undantag.
Aktiviteter är förstklassiga medborgare i Application Insights. Automatisk beroende- och begärandeinsamling är starkt beroende av dem tillsammans med DiagnosticSource
händelser. Om du har skapat Activity
i ditt program skulle det inte leda till att Application Insights-telemetri skapas. Application Insights måste ta emot DiagnosticSource
händelser och känna till händelsernas namn och nyttolaster för att översättas Activity
till telemetri.
Varje Application Insights-åtgärd (begäran eller beroende) omfattar Activity
. När StartOperation
anropas skapas Activity
den under. StartOperation
är det rekommenderade sättet att spåra telemetrier för begäran eller beroende manuellt och se till att allt är korrelerat.
Nästa steg
- Lär dig grunderna i telemetrikorrelation i Application Insights.
- Se hur korrelerade data driver transaktionsdiagnostiken och programkartan.
- Se datamodellen för Application Insights-typer och datamodeller.
- Rapportera anpassade händelser och mått till Application Insights.
- Kolla in standardkonfigurationen för samling med kontextegenskaper.
- Kontrollera användarhandboken för System.Diagnostics.Activity för att se hur vi korrelerar telemetri.