.NET-distribuerade spårningsbegrepp

Distribuerad spårning är en diagnostikteknik som hjälper tekniker att lokalisera fel och prestandaproblem i program, särskilt de som kan distribueras över flera datorer eller processer. I översikten över distribuerad spårning finns allmän information om var distribuerad spårning är användbar.

Spårningar och aktiviteter

Varje gång en ny begäran tas emot av ett program kan den associeras med en spårning. I programkomponenter som skrivits i .NET representeras arbetsenheter i en spårning av instanser av System.Diagnostics.Activity och spårningen som helhet utgör ett träd i dessa aktiviteter, som potentiellt sträcker sig över många olika processer. Den första aktiviteten som skapas för en ny begäran utgör roten i spårningsträdet och spårar den totala varaktigheten och hanteringen av lyckade/misslyckade begäranden. Underordnade aktiviteter kan skapas om du vill dela upp arbetet i olika steg som kan spåras individuellt. Med tanke på en aktivitet som spårade en specifik inkommande HTTP-begäran på en webbserver kan till exempel underordnade aktiviteter skapas för att spåra var och en av de databasfrågor som var nödvändiga för att slutföra begäran. På så sätt kan varaktigheten och framgången för varje fråga registreras oberoende av varandra. Aktiviteter kan registrera annan information för varje arbetsenhet, till exempel OperationNamenamn/värde-par med namnet Tags, och Events. Namnet identifierar vilken typ av arbete som utförs, taggar kan registrera beskrivande parametrar för arbetet och händelser är en enkel loggningsmekanism för att registrera tidsstämplade diagnostikmeddelanden.

Kommentar

Ett annat vanligt branschnamn för arbetsenheter i en distribuerad spårning är "Spans". .NET antog termen "Aktivitet" för många år sedan, innan namnet "Span" var väletablerat för det här konceptet.

Aktivitets-ID:t

Relationer mellan överordnade och underordnade mellan aktiviteter i det distribuerade spårningsträdet upprättas med hjälp av unika ID:er. . NET:s implementering av distribuerad spårning stöder två ID-scheman: W3C-standarden TraceContext, som är standard i .NET 5+, och en äldre .NET-konvention med namnet "Hierarkisk" som är tillgänglig för bakåtkompatibilitet. Activity.DefaultIdFormat kontrollerar vilket ID-schema som används. I W3C TraceContext-standarden tilldelas varje spårning ett globalt unikt spårnings-ID på 16 byte (Activity.TraceId), och varje aktivitet i spårningen tilldelas ett unikt 8 byte span-id (Activity.SpanId). Varje aktivitet registrerar spårnings-ID, dess eget span-id och span-id för dess överordnade (Activity.ParentSpanId). Eftersom distribuerade spårningar kan spåra arbete över processgränser kanske överordnade och underordnade aktiviteter inte ingår i samma process. Kombinationen av ett spårnings-ID och ett överordnat span-ID kan unikt identifiera den överordnade aktiviteten globalt, oavsett vilken process den finns i.

Activity.DefaultIdFormat styr vilket ID-format som används för att starta nya spårningar, men som standard används det format som den överordnade aktiviteten använder när en ny aktivitet läggs till i en befintlig spårning. Inställningen Activity.ForceDefaultIdFormat true åsidosätter det här beteendet och skapar alla nya aktiviteter med DefaultIdFormat, även när den överordnade användaren använder ett annat ID-format.

Starta och stoppa aktiviteter

Varje tråd i en process kan ha ett motsvarande aktivitetsobjekt som spårar det arbete som sker på tråden, som är tillgängligt via Activity.Current. Den aktuella aktiviteten flödar automatiskt längs alla synkrona anrop i en tråd och följer asynkrona anrop som bearbetas i olika trådar. Om Aktivitet A är den aktuella aktiviteten i en tråd och koden startar en ny aktivitet B blir B den nya aktuella aktiviteten i tråden. Som standard behandlar aktivitet B även aktivitet A som överordnad. När aktivitet B stoppas senare återställs aktivitet A som den aktuella aktiviteten i tråden. När en aktivitet startas avbildas den aktuella tiden som Activity.StartTimeUtc. När den stoppas Activity.Duration beräknas som skillnaden mellan den aktuella tiden och starttiden.

Samordna över processgränser

För att spåra arbete över processgränser måste överordnade aktivitets-ID:n överföras över nätverket så att den mottagande processen kan skapa aktiviteter som refererar till dem. När du använder W3C TraceContext ID-formatet använder .NET även DE HTTP-huvuden som rekommenderas av standarden för att överföra den här informationen. När du använder Hierarchical ID-formatet använder .NET ett anpassat HTTP-sidhuvud för begäran-id för att överföra ID:t. Till skillnad från många andra språkkörningar förstår .NET in-box-bibliotek som ASP.NET webbservern och System.Net.Http internt hur du avkodar och kodar aktivitets-ID:n på HTTP-meddelanden. Körningen förstår också hur du flödar ID:t via synkrona och asynkrona anrop. Det innebär att .NET-program som tar emot och sänder HTTP-meddelanden deltar i flödande distribuerade spårnings-ID:n automatiskt, utan någon särskild kodning av apputvecklaren eller biblioteksberoenden från tredje part. Bibliotek från tredje part kan lägga till stöd för överföring av ID:er via icke-HTTP-meddelandeprotokoll eller stöd för anpassade kodningskonventioner för HTTP.

Samla in spårningar

Instrumenterad kod kan skapa Activity objekt som en del av en distribuerad spårning, men informationen i dessa objekt måste överföras och serialiseras i ett centraliserat beständigt arkiv så att hela spårningen kan granskas senare. Det finns flera bibliotek för telemetrisamlingar som kan utföra den här uppgiften, till exempel Application Insights, OpenTelemetry eller ett bibliotek som tillhandahålls av en telemetri från tredje part eller APM-leverantör. Alternativt kan utvecklare skapa en egen anpassad aktivitetstelemetrisamling med hjälp System.Diagnostics.ActivityListener av eller System.Diagnostics.DiagnosticListener. ActivityListener har stöd för att observera aktiviteter oavsett om utvecklaren har någon förkunskap om det. Detta gör ActivityListener till en enkel och flexibel lösning för generell användning. Att använda DiagnosticListener är däremot ett mer komplext scenario som kräver att den instrumenterade koden anmäler sig genom att DiagnosticSource.StartActivity anropa och samlingsbiblioteket måste känna till den exakta namngivningsinformation som den instrumenterade koden använde när den startades. Med DiagnosticSource och DiagnosticListener kan skaparen och lyssnaren utbyta godtyckliga .NET-objekt och upprätta anpassade konventioner för informationsöverföring.

Sampling

För bättre prestanda i program med högt dataflöde stöder distribuerad spårning på .NET endast sampling av en delmängd av spårningar i stället för att registrera alla. För aktiviteter som skapats med det rekommenderade ActivitySource.StartActivity API:et kan telemetrisamlingsbibliotek styra samplingen med återanropet ActivityListener.Sample . Loggningsbiblioteket kan välja att inte skapa aktiviteten alls, att skapa den med minimal information som krävs för att sprida distribution av spårnings-ID:t eller fylla i den med fullständig diagnostikinformation. De här alternativen kompromissar med att öka prestandakostnaderna för att öka diagnostikverktyget. Aktiviteter som startas med det äldre mönstret för att Activity.Activity anropa och DiagnosticSource.StartActivity kan också stödja DiagnosticListener-sampling genom att först anropa DiagnosticSource.IsEnabled. Även när du samlar in fullständig diagnostikinformation är .NET-implementeringen utformad för att vara snabb – tillsammans med en effektiv insamlare kan en aktivitet skapas, fyllas i och överföras i ungefär en mikrosekunder på modern maskinvara. Sampling kan minska instrumentationskostnaden till mindre än 100 nanosekunder för varje aktivitet som inte registreras.

Nästa steg

Exempel på kod för att komma igång med distribuerad spårning i .NET-program finns i Instrumentation för distribuerad spårning.