Sledování vlastních operací pomocí sady Application Přehledy .NET SDK

Sady SDK Přehledy aplikací automaticky sledují příchozí požadavky HTTP a volání závislých služeb, jako jsou požadavky HTTP a dotazy SQL. Sledování a korelace požadavků a závislostí poskytuje přehled o odezvě a spolehlivosti celé aplikace napříč všemi mikroslužbami, které tuto aplikaci kombinují.

Existuje třída vzorů aplikací, které není možné obecně podporovat. Správné monitorování takových vzorů vyžaduje ruční instrumentaci kódu. Tento článek popisuje několik vzorů, které můžou vyžadovat ruční instrumentaci, jako je vlastní zpracování fronty a spouštění dlouhotrvajících úloh na pozadí.

Tento článek obsahuje pokyny ke sledování vlastních operací pomocí sady Application Přehledy SDK. Tato dokumentace je relevantní pro:

  • Aplikační Přehledy pro .NET (označované také jako základní sada SDK) verze 2.4 nebo novější.
  • Přehledy aplikace pro webové aplikace (spuštěné ASP.NET) verze 2.4 nebo novější.
  • Přehledy aplikace pro ASP.NET Core verze 2.1 nebo novější.

Poznámka:

Následující dokumentace se spoléhá na rozhraní API Přehledy Application Přehledy Classic. Dlouhodobým plánem pro application Přehledy je shromažďovat data pomocí OpenTelemetry. Další informace najdete v tématu Povolení OpenTelemetry služby Azure Monitor pro aplikace .NET, Node.js, Python a Java.

Přehled

Operace je logická část práce spuštěná aplikací. Má název, počáteční čas, dobu trvání, výsledek a kontext spuštění, jako je uživatelské jméno, vlastnosti a výsledek. Pokud byla operace A inicializována operací B, operace B je nastavena jako nadřazená pro A. Operace může mít pouze jednu nadřazenou položku, ale může mít mnoho podřízených operací. Další informace o operacích a korelaci telemetrie najdete v tématu Přehledy korelace telemetrie aplikace.

V sadě Application Přehledy .NET SDK je operace popsaná abstraktní třídou OperationTelemetry a jejími potomky RequestTelemetry a DependencyTelemetry.

Sledování příchozích operací

Sada Application Přehledy Web SDK automaticky shromažďuje požadavky HTTP pro ASP.NET aplikace, které běží v kanálu služby IIS, a všechny aplikace ASP.NET Core. Existují komunitní řešení pro jiné platformy a architektury. Pokud aplikace není podporována žádným ze standardních nebo komunitních řešení, můžete ji instrumentovat ručně.

Dalším příkladem, který vyžaduje vlastní sledování, je pracovní proces, který přijímá položky z fronty. U některých front se volání pro přidání zprávy do této fronty sleduje jako závislost. Operace vysoké úrovně, která popisuje zpracování zpráv, se neshromažďuje automaticky.

Pojďme se podívat, jak by mohly být tyto operace sledovány.

Na vysoké úrovni je úkolem vytvořit RequestTelemetry a nastavit známé vlastnosti. Po dokončení operace budete sledovat telemetrii. Následující příklad ukazuje tento úkol.

Požadavek HTTP v aplikaci V místním prostředí Owinu

V tomto příkladu se kontext trasování rozšíří podle protokolu HTTP pro korelaci. Měli byste očekávat, že dostanete hlavičky, které jsou tam popsané.

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);
    }
}

Protokol HTTP pro korelaci také deklaruje hlavičku Correlation-Context . Kvůli jednoduchosti je tu vynechán.

Instrumentace front

Kontext trasování W3C a protokol HTTP pro předávání korelačních podrobností s požadavky HTTP, ale každý protokol fronty musí definovat, jak se stejné podrobnosti předávají ve zprávě fronty. Některé protokoly front, jako je AMQP, umožňují předávání dalších metadat. Jiné protokoly, jako je fronta služby Azure Storage, vyžadují, aby byl kontext zakódován do datové části zprávy.

Poznámka:

Trasování mezi komponentami se zatím pro fronty nepodporuje.

Pokud váš producent a příjemce posílají telemetrii do různých prostředků aplikace Přehledy, prostředí diagnostiky transakcí a mapa aplikací zobrazují transakce a kompletní mapování. V případě front se tato funkce zatím nepodporuje.

Fronta služby Service Bus

Informace o trasování najdete v tématu Distribuované trasování a korelace prostřednictvím zasílání zpráv služby Azure Service Bus.

Fronta služby Azure Storage

Následující příklad ukazuje, jak sledovat operace fronty Azure Storage a korelovat telemetrii mezi producentem, příjemcem a Azure Storage.

Fronta úložiště má rozhraní HTTP API. Všechna volání do fronty jsou sledována kolektorem závislostí aplikace Přehledy pro požadavky HTTP. Ve výchozím nastavení je nakonfigurovaná pro aplikace ASP.NET a ASP.NET Core. Další typy aplikací najdete v dokumentaci ke konzolovým aplikacím.

Můžete také chtít korelovat ID operace Přehledy aplikace s ID požadavku úložiště. Informace o tom, jak nastavit a získat klienta žádosti o úložiště a ID požadavku serveru, najdete v tématu Monitorování, diagnostika a řešení potíží se službou Azure Storage.

Enqueue

Vzhledem k tomu, že fronty služby Storage podporují rozhraní HTTP API, všechny operace s frontou se automaticky sledují Přehledy aplikací. V mnoha případech by tato instrumentace měla stačit. Pokud chcete korelovat trasování na straně příjemce s trasováními producenta, musíte předat kontext korelace podobně jako v protokolu HTTP pro korelaci.

Tento příklad ukazuje, jak sledovat Enqueue operaci. Můžete provádět následující akce:

  • Korelace opakovaných pokusů (pokud existuje):Všichni mají jeden společný nadřazený objekt, který je operací Enqueue . Jinak se sledují jako podřízené příchozí žádosti. Pokud fronta obsahuje více logických požadavků, může být obtížné zjistit, které volání vedlo k opakovaným pokusům.
  • Korelace protokolů úložiště (pokud a v případě potřeby): Korelují se telemetrií Přehledy aplikací.

Operace Enqueue je podřízenou nadřazenou operací. Příkladem je příchozí požadavek HTTP. Volání závislostí HTTP je podřízeným objektem Enqueue operace a vnukem příchozího požadavku.

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);
    }
}  

Pokud chcete snížit množství telemetrických dat, které vaše aplikace hlásí, nebo pokud nechcete sledovat Enqueue operaci z jiných důvodů, použijte Activity rozhraní API přímo:

  • Místo spuštění operace Přehledy aplikace vytvořte (a spusťte) novýActivity. Není nutné přiřazovat žádné vlastnosti s výjimkou názvu operace.
  • Serializace yourActivity.Id do datové části zprávy místo operation.Telemetry.Id. Můžete také použít Activity.Current.Id.

Odstranění z fronty

EnqueuePodobně jako skutečný požadavek HTTP do fronty služby Storage se automaticky sleduje Přehledy aplikace. Operace Enqueue se pravděpodobně provede v nadřazeného kontextu, například v kontextu příchozího požadavku. Sady Application Přehledy SDK automaticky korelují takovou operaci a její část HTTP s nadřazeným požadavkem a další telemetrií hlášenou ve stejném oboru.

Operace Dequeue je složitá. Sada Application Přehledy SDK automaticky sleduje požadavky HTTP. Ale nezná kontext korelace, dokud se zpráva neanalyzuje. Požadavek HTTP není možné korelovat, aby se zpráva dostala se zbytkem telemetrie, zejména pokud se přijme více než jedna zpráva.

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;
}

Zpracovat

V následujícím příkladu se příchozí zpráva sleduje podobným způsobem jako příchozí požadavek 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);
    }
}

Podobně lze instrumentovat i jiné operace fronty. Operace náhledu by měla být instrumentována podobným způsobem jako operace odstranění fronty. Instrumentace operací správy front není nutná. Aplikace Přehledy sleduje operace, jako je HTTP, a ve většině případů stačí.

Při instrumentaci odstranění zprávy se ujistěte, že jste nastavili identifikátory operace (korelace). Alternativně můžete použít Activity rozhraní API. Pak nemusíte nastavovat identifikátory operací u položek telemetrie, protože sada Application Přehledy SDK to udělá za vás:

  • Po vytvoření položky z fronty vytvořte novou Activity položku.
  • Slouží Activity.SetParentId(message.ParentId) ke korelaci protokolů příjemců a producentů.
  • Spusťte tlačítko Activity.
  • Sledujte operace vyřazení, zpracování a odstranění pomocí Start/StopOperation pomocných rutin. Proveďte to ze stejného asynchronního toku řízení (kontext spouštění). Tímto způsobem korelují správně.
  • ActivityZastavte .
  • Použijte Start/StopOperation nebo volejte Track telemetrii ručně.

Typy závislostí

Aplikace Přehledy používá typ závislosti k přizpůsobení uživatelského rozhraní. Pro fronty rozpozná následující typy DependencyTelemetry , které zlepšují prostředí pro diagnostiku transakcí:

  • Azure queue pro fronty Azure Storage
  • Azure Event Hubs pro Azure Event Hubs
  • Azure Service Bus pro Azure Service Bus

Dávkové zpracování

U některých front můžete s jedním požadavkem vyřadit z fronty více zpráv. Zpracování takových zpráv je pravděpodobně nezávislé a patří do různých logických operací. Operaci není možné korelovat Dequeue s konkrétní zpracovávanou zprávou.

Každá zpráva by měla být zpracována ve vlastním asynchronním toku řízení. Další informace najdete v části Sledování odchozích závislostí.

Dlouhotrvající úlohy na pozadí

Některé aplikace spouštějí dlouhotrvající operace, které můžou být způsobené požadavky uživatelů. Z hlediska trasování/instrumentace se neliší od instrumentace požadavků nebo závislostí:

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);
    }
}

V tomto příkladu telemetryClient.StartOperation vytvoří DependencyTelemetry a vyplní kontext korelace. Řekněme, že máte nadřazenou operaci vytvořenou příchozími požadavky, které operaci naplánovaly. BackgroundTask Pokud se spustí ve stejném asynchronním toku řízení jako příchozí požadavek, koreluje se s danou nadřazenou operací. BackgroundTask a všechny vnořené položky telemetrie se automaticky korelují s požadavkem, který ji způsobil, a to i po skončení požadavku.

Když úloha začíná z vlákna na pozadí, které nemá přidruženou BackgroundTask žádnou operaci (Activity) nemá žádnou nadřazenou položku. Může však obsahovat vnořené operace. Všechny položky telemetrie hlášené z úkolu jsou korelovány s vytvořeným DependencyTelemetry v BackgroundTask.

Sledování odchozích závislostí

Můžete sledovat vlastní druh závislosti nebo operaci, která není podporována Přehledy aplikací.

Metoda Enqueue ve frontě služby Service Bus nebo frontě služby Storage může sloužit jako příklady pro takové vlastní sledování.

Obecným přístupem ke sledování vlastních závislostí je:

  • Zavolejte metodu TelemetryClient.StartOperation (extension), která vyplní DependencyTelemetry vlastnosti potřebné pro korelaci a některé další vlastnosti, jako je začátek, časové razítko a doba trvání.
  • Nastavte další vlastní vlastnosti v objektu DependencyTelemetry, například název a jakýkoli jiný kontext, který potřebujete.
  • Proveďte volání závislostí a počkejte na něj.
  • Po dokončení operace StopOperation zastavte.
  • Zpracování výjimek
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.
        }
    }
}

Zrušení operace způsobí zastavení operace, takže ji můžete udělat místo volání StopOperation.

Upozorňující

V některých případech může neošetřená výjimka bránitfinally v volání, takže operace nemusí být sledovány.

Paralelní zpracování a sledování operací

Volání StopOperation zastaví pouze spuštěnou operaci. Pokud aktuální spuštěná operace neodpovídá té, kterou chcete zastavit, StopOperation nic nedělá. K této situaci může dojít, pokud paralelně spustíte více operací ve stejném kontextu provádění.

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;

Ujistěte se, že vždy voláte StartOperation a zpracováváte operaci ve stejné asynchronní metodě, abyste izolovali operace spuštěné paralelně. Pokud je operace synchronní (nebo nesync), zabalte proces a sledujte pomocí 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);
}

Operace aplikace Přehledy vs. System.Diagnostics.Activity

System.Diagnostics.Activity představuje distribuovaný kontext trasování a je používán architekturami a knihovnami k vytvoření a šíření kontextu uvnitř procesu a mimo proces a korelaci položek telemetrie. Activity spolupracuje s mechanismem System.Diagnostics.DiagnosticSource oznámení mezi architekturou nebo knihovnou, aby upozorňovat na zajímavé události, jako jsou příchozí nebo odchozí požadavky a výjimky.

Aktivity jsou prvotřídními občany v aplikaci Přehledy. Automatické závislosti a shromažďování požadavků se na ně spoléhají společně s událostmi DiagnosticSource . Pokud jste vytvořili Activity ve své aplikaci, nemělo by to za následek vytvoření telemetrie Přehledy aplikace. Aplikace Přehledy potřebuje přijímat DiagnosticSource události a znát názvy událostí a datové části pro překlad Activity do telemetrie.

Každá operace Přehledy aplikace (požadavek nebo závislost) zahrnuje Activity. Když StartOperation je volána, vytvoří Activity se pod ní. StartOperation je doporučený způsob ručního sledování telemetrie požadavků nebo závislostí a zajištění korelace všeho.

Další kroky

  • Seznamte se se základy korelace telemetrie v Přehledy aplikace.
  • Podívejte se, jak korelovaná data řídí prostředí pro diagnostiku transakcí a mapu aplikací.
  • Podívejte se na datový model pro typy Přehledy aplikací a datový model.
  • Nahlašujte vlastní události a metriky do Přehledy aplikace.
  • Podívejte se na standardní konfiguraci kolekce kontextových vlastností.
  • Projděte si uživatelskou příručku system.Diagnostics.Activity a zjistěte, jak korelujeme telemetrii.