Distribuerad spårning och korrelation genom Service Bus meddelanden

Ett av de vanliga problemen vid Micro Services-utveckling är möjligheten att spåra åtgärder från en klient genom alla tjänster som ingår i bearbetningen. Det är användbart för fel sökning, prestanda analys, A/B-testning och andra typiska diagnos scenarier. En del av det här problemet spårar logiska arbets delar. Det omfattar meddelande behandlings resultat och svars tider och externa beroende anrop. En annan del är en korrelation av dessa diagnostiska händelser utöver process gränser.

När en producent skickar ett meddelande via en kö, sker det vanligt vis i omfånget för en annan logisk åtgärd som initieras av en annan klient eller tjänst. Samma åtgärd fortsätter av konsumenten när den får ett meddelande. Både producent och konsument (och andra tjänster som bearbetar åtgärden) genererar sedan telemetri-händelser för att spåra åtgärds flödet och resultatet. För att kunna korrelera sådana händelser och spåra åtgärder från slut punkt till slut punkt måste varje tjänst som rapporterar telemetri stämpla varje händelse med en spårnings kontext.

Microsoft Azure Service Bus Messaging har definierat nytto Last egenskaper som producenter och konsumenter bör använda för att skicka sådan spårnings kontext. Protokollet baseras på http-korrelations protokollet.

Egenskapens namn Beskrivning
Diagnostic-Id Unikt ID för ett externt anrop från producent till kön. Se begärande-ID i HTTP-protokollet för att få rationella, överväganden och format

Service Bus .NET-klient spårning

ServiceBusProcessorKlassen för Azure Messaging Service Bus-klienten för .net innehåller spårnings instrument som kan kopplas till spårnings system eller del av klient kod. Med instrumentering kan du spåra alla anrop till tjänsten för Service Bus meddelande tjänsten från klient sidan. Om meddelande bearbetningen görs med hjälp ProcessMessageAsync av ServiceBusProcessor (meddelande hanterarens mönster) instrumenteras även meddelande bearbetningen.

Spåra med Azure Application insikter

Microsoft Application Insights ger omfattande prestanda övervaknings funktioner, inklusive automagic-begäran och beroende spårning.

Installera Application Insights SDK, beroende på din projekt typ:

  • ASP.net -installation version 2,5-beta2 eller högre
  • ASP.net Core -installera version 2.2.0-beta2 eller högre. Dessa länkar innehåller information om hur du installerar SDK, skapar resurser och konfigurerar SDK (om det behövs). Information om non-ASP.NET-program finns i artikeln Azure Application Insights för konsol program .

Om du använder ProcessMessageAsync ServiceBusProcessor (mönster för meddelande hanterare) för att bearbeta meddelanden, instrumenteras även meddelande bearbetningen. Alla Service Bus-anrop som utförs av tjänsten spåras automatiskt och korreleras med andra telemetri objekt. I annat fall refererar vi till följande exempel för manuell meddelande bearbetnings spårning.

Behandling av spåra meddelanden

async Task ProcessAsync(ProcessMessageEventArgs args)
{
    ServiceBusReceivedMessage message = args.Message;
    if (message.ApplicationProperties.TryGetValue("Diagnostic-Id", out var objectId) && objectId is string diagnosticId)
    {
        var activity = new Activity("ServiceBusProcessor.ProcessMessage");
        activity.SetParentId(diagnosticId);
        // If you're using Microsoft.ApplicationInsights package version 2.6-beta or higher, you should call StartOperation<RequestTelemetry>(activity) instead
        using (var operation = telemetryClient.StartOperation<RequestTelemetry>("Process", activity.RootId, activity.ParentId))
        {
            telemetryClient.TrackTrace("Received message");
            try 
            {
            // process message
            }
            catch (Exception ex)
            {
                telemetryClient.TrackException(ex);
                operation.Telemetry.Success = false;
                throw;
            }

            telemetryClient.TrackTrace("Done");
        }
    }
}

I det här exemplet rapporteras begäran om telemetri för varje bearbetat meddelande, med en tidsstämpel, varaktighet och resultat (lyckades). Telemetri har också en uppsättning korrelations egenskaper. Kapslade spår och undantag som rapporteras vid meddelande bearbetning stämplas också med korrelations egenskaper som representerar dem som underordnade till RequestTelemetry .

Om du gör anrop till stödda externa komponenter under meddelande bearbetningen spåras de också automatiskt och korreleras. Se spåra anpassade åtgärder med Application Insights .NET SDK för manuell spårning och korrelation.

Om du kör någon extern kod utöver Application Insights SDK, förväntar du dig att se längre tid när du visar Application Insights loggar.

Längre varaktighet i Application Insights loggen

Det innebär inte att det tog lång tid att ta emot meddelandet. I det här scenariot har meddelandet redan mottagits sedan meddelandet skickades som en parameter till SDK-koden. Och namn -taggen i App Insights-loggarna (processen) anger att meddelandet nu bearbetas av den externa händelse bearbetnings koden. Det här problemet är inte Azure-relaterat. De här måtten avser i stället effektiviteten hos din externa kod, under förutsättning att meddelandet redan har tagits emot från Service Bus.

Spåra utan spårnings system

Om spårnings systemet inte stöder automatisk Service Bus samtals spårning kan du behöva lägga till sådant stöd i ett spårnings system eller i ditt program. I det här avsnittet beskrivs diagnostiska händelser som skickas av Service Bus .NET-klienten.

Service Bus .NET-klienten instrumenteras med hjälp av .NET tracing primitiver system. Diagnostics. Activity och system. Diagnostics. DiagnosticSource.

Activity fungerar som en spårnings kontext medan DiagnosticSource är en meddelande funktion.

Om det inte finns någon lyssnare för DiagnosticSource-händelserna, är instrumentering inaktiverat, och behåller inga instrument kostnader. DiagnosticSource ger all kontroll till lyssnaren:

  • lyssnare styr vilka källor och händelser som ska bevakas
  • lyssnare kontrollerar händelse frekvens och sampling
  • händelser skickas med en nytto last som ger fullständig kontext så att du kan komma åt och ändra meddelande objekt under händelsen

Bekanta dig med användar handboken för DiagnosticSource innan du fortsätter med implementeringen.

Nu ska vi skapa en lyssnare för Service Bus händelser i ASP.NET Core app som skriver loggar med Microsoft. extension. Logga. Den använder system. Reactive. Core -biblioteket för att prenumerera på DiagnosticSource (det är också enkelt att prenumerera på DiagnosticSource utan IT)

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory, IApplicationLifetime applicationLifetime)
{
    // configuration...

    var serviceBusLogger = factory.CreateLogger("Azure.Messaging.ServiceBus");

    IDisposable innerSubscription = null;
    IDisposable outerSubscription = DiagnosticListener.AllListeners.Subscribe(delegate (DiagnosticListener listener)
    {
        // subscribe to the Service Bus DiagnosticSource
        if (listener.Name == "Azure.Messaging.ServiceBus")
        {
            // receive event from Service Bus DiagnosticSource
            innerSubscription = listener.Subscribe(delegate (KeyValuePair<string, object> evnt)
            {
                // Log operation details once it's done
                if (evnt.Key.EndsWith("Stop"))
                {
                    Activity currentActivity = Activity.Current;
                    serviceBusLogger.LogInformation($"Operation {currentActivity.OperationName} is finished, Duration={currentActivity.Duration}, Id={currentActivity.Id}, StartTime={currentActivity.StartTimeUtc}");
                }
            });
        }
    });

    applicationLifetime.ApplicationStopping.Register(() =>
    {
        outerSubscription?.Dispose();
        innerSubscription?.Dispose();
    });
}

I det här exemplet loggar Listener varaktighet, resultat, unik identifierare och start tid för varje Service Bus åtgärd.

Händelser

Alla händelser har följande egenskaper som stämmer med den öppna telemetri-specifikationen: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md .

  • message_bus.destination – kö/ämne/prenumerations Sök väg
  • peer.address – fullständigt kvalificerat namn område
  • kind – antingen producent, konsument eller klient. Producer används vid sändning av meddelanden, konsument vid mottagning och klient vid kvittning.
  • componentservicebus

Alla händelser har även egenskaperna "entity" och "slut punkt", de utelämnas i tabellen nedan

  • string Entity --Namn på entiteten (kö, ämne osv.)
  • Uri Endpoint -Service Bus slut punkts-URL

Instrumenterade åtgärder

Här är en fullständig lista över instrumenterade åtgärder:

Åtgärds namn Spårat API
ServiceBusSender. send ServiceBusSender.SendMessageAsync
ServiceBusSender.SendMessagesAsync
ServiceBusSender. Schedule ServiceBusSender.ScheduleMessageAsync
ServiceBusSender.ScheduleMessagesAsync
ServiceBusSender. Cancel ServiceBusSender.CancelScheduledMessageAsync
ServiceBusSender.CancelScheduledMessagesAsync
ServiceBusReceiver. Receive ServiceBusReceiver.ReceiveMessageAsync
ServiceBusReceiver.ReceiveMessagesAsync
ServiceBusReceiver.ReceiveDeferred ServiceBusReceiver.ReceiveDeferredMessagesAsync
ServiceBusReceiver. Peek ServiceBusReceiver.PeekMessageAsync
ServiceBusReceiver.PeekMessagesAsync
ServiceBusReceiver. överge ServiceBusReceiver.AbandonMessagesAsync
ServiceBusReceiver. Complete ServiceBusReceiver.CompleteMessagesAsync
ServiceBusReceiver. obeställbara meddelanden kön ServiceBusReceiver.DeadLetterMessagesAsync
ServiceBusReceiver. Överlåt ServiceBusReceiver.DeferMessagesAsync
ServiceBusReceiver.RenewMessageLock ServiceBusReceiver.RenewMessageLockAsync
ServiceBusSessionReceiver.RenewSessionLock ServiceBusSessionReceiver.RenewSessionLockAsync
ServiceBusSessionReceiver.GetSessionState ServiceBusSessionReceiver.GetSessionStateAsync
ServiceBusSessionReceiver.SetSessionState ServiceBusSessionReceiver.SetSessionStateAsync
ServiceBusProcessor.ProcessMessage Återanrop för processor angavs på ServiceBusProcessor. ProcessMessageAsync-egenskap
ServiceBusSessionProcessor.ProcessSessionMessage Återanrop för processor angavs på ServiceBusSessionProcessor. ProcessMessageAsync-egenskap

Filtrering och sampling

I vissa fall är det önskvärt att endast logga en del av händelserna för att minska prestanda och lagrings förbrukning. Du kan endast logga "stoppa"-händelser (som i föregående exempel) eller en procentuell sampling av händelserna. DiagnosticSource Ange ett sätt att åstadkomma det med IsEnabled predikatet. Mer information finns i Sammanhangs beroende filtrering i DiagnosticSource.

IsEnabled kan anropas flera gånger för en enskild åtgärd för att minimera prestanda påverkan.

IsEnabled anropas i följande ordning:

  1. IsEnabled(<OperationName>, string entity, null) till exempel IsEnabled("ServiceBusSender.Send", "MyQueue1") . Observera att det inte finns någon start eller stopp i slutet. Använd den för att filtrera bort specifika åtgärder eller köer. Om callback-metoden returnerar false skickas inte händelser för åtgärden.

    • För åtgärderna "process" och "ProcessSession" får du också IsEnabled(<OperationName>, string entity, Activity activity) motringning. Använd den för att filtrera händelser baserat på activity.Id eller Taggar egenskaper.
  2. IsEnabled(<OperationName>.Start) till exempel IsEnabled("ServiceBusSender.Send.Start") . Kontrollerar om start händelsen ska utlösas. Resultatet påverkar endast händelsen "starta", men ytterligare Instrumentation är inte beroende av det.

Det finns ingen IsEnabled "stopp"-händelse.

Om åtgärds resultatet är ett undantag IsEnabled("ServiceBusSender.Send.Exception") kallas det. Du kan bara prenumerera på "undantags händelser" och förhindra resten av Instrumentation. I så fall måste du fortfarande hantera sådana undantag. Eftersom annan Instrumentation är inaktive rad bör du inte förvänta spårnings kontexten för att flöda med meddelanden från konsument till producent.

Du kan IsEnabled även implementera provtagnings strategier. Sampling som baseras på Activity.Id eller Activity.RootId säkerställer konsekvent provtagning över alla däck (så länge som det sprids av spårnings systemet eller av din egen kod).

I närvaro av flera DiagnosticSource lyssnare för samma källa räcker det bara för en lyssnare att acceptera händelsen, så det finns ingen garanti som IsEnabled kallas.

Nästa steg