Verifica delle operazioni personalizzate con Application Insights .NET SDKTrack custom operations with Application Insights .NET SDK

Gli SDK di Application Insights di Azure verificano automaticamente le richieste HTTP in ingresso e le chiamate ai servizi dipendenti, ovvero richieste HTTP, query SQL e così via.Azure Application Insights SDKs automatically track incoming HTTP requests and calls to dependent services, such as HTTP requests and SQL queries. La verifica e la correlazione di richieste e dipendenze offre visibilità sui tempi di risposta e sull'affidabilità dell'intera applicazione in tutti i microservizi che combinano questa applicazione.Tracking and correlation of requests and dependencies give you visibility into the whole application's responsiveness and reliability across all microservices that combine this application.

Esiste una classe di modelli di applicazione che non può essere supportata in modo generico.There is a class of application patterns that can't be supported generically. Per il corretto monitoraggio di tali modelli, è necessaria la strumentazione manuale del codice.Proper monitoring of such patterns requires manual code instrumentation. Questo articolo descrive alcuni criteri che potrebbero richiedere una strumentazione manuale, ad esempio per l’elaborazione di code personalizzate e l'esecuzione prolungata di attività in background.This article covers a few patterns that might require manual instrumentation, such as custom queue processing and running long-running background tasks.

Questo documento offre indicazioni su come tenere traccia delle operazioni personalizzate con Application Insights SDK.This document provides guidance on how to track custom operations with the Application Insights SDK. Questa documentazione è relativa a:This documentation is relevant for:

  • Application Insights per .NET (noto anche come Base SDK) versione 2.4+.Application Insights for .NET (also known as Base SDK) version 2.4+.
  • Application Insights per applicazioni Web (che esegue ASP.NET) versione 2.4+.Application Insights for web applications (running ASP.NET) version 2.4+.
  • Application Insights per ASP.NET Core versione 2.1+.Application Insights for ASP.NET Core version 2.1+.

PanoramicaOverview

Un'operazione è un lavoro logico eseguito da un'applicazione.An operation is a logical piece of work run by an application. Sono indicati nome, ora di avvio, durata, risultato e contesto dell'esecuzione, ad esempio nome utente, proprietà e risultato.It has a name, start time, duration, result, and a context of execution like user name, properties, and result. Se l'operazione A è stata avviata dall'operazione B, l'operazione B è impostata come elemento padre per A. Un'operazione può avere un solo padre, ma può avere molte operazioni figlio.If operation A was initiated by operation B, then operation B is set as a parent for A. An operation can have only one parent, but it can have many child operations. Per ulteriori informazioni sulle operazioni e la correlazione dei dati di telemetria, vedere Correlazione dei dati di telemetria di Azure Application Insights.For more information on operations and telemetry correlation, see Azure Application Insights telemetry correlation.

Nell’SDK di Application Insights .NET l'operazione viene descritta dalla classe astratta OperationTelemetry e dai discendenti RequestTelemetry e DependencyTelemetry.In the Application Insights .NET SDK, the operation is described by the abstract class OperationTelemetry and its descendants RequestTelemetry and DependencyTelemetry.

Verifica delle operazioni in ingressoIncoming operations tracking

Application Insights Web SDK raccoglie automaticamente le richieste HTTP per le applicazioni ASP.NET eseguite nella pipeline di IIS e per tutte le applicazioni ASP.NET Core.The Application Insights web SDK automatically collects HTTP requests for ASP.NET applications that run in an IIS pipeline and all ASP.NET Core applications. Sono disponibili soluzioni supportate dalla community per altre piattaforme e altri framework.There are community-supported solutions for other platforms and frameworks. Se tuttavia l'applicazione non è supportata dalle soluzioni standard o supportate dalla community, è possibile instrumentarla manualmente.However, if the application isn't supported by any of the standard or community-supported solutions, you can instrument it manually.

Un altro esempio che richiede la verifica personalizzata è offerto dal ruolo di lavoro che riceve gli elementi dalla coda.Another example that requires custom tracking is the worker that receives items from the queue. Per alcune code, la chiamata per aggiungere un messaggio a questa coda viene registrata come dipendenza.For some queues, the call to add a message to this queue is tracked as a dependency. L'operazione di alto livello che descrive l'elaborazione del messaggio tuttavia non viene raccolta automaticamente.However, the high-level operation that describes message processing is not automatically collected.

Di seguito viene illustrato come è possibile tenere traccia di tali operazioni.Let's see how we can track such operations.

A un livello elevato, l'attività consiste nel creare RequestTelemetry e impostare le proprietà note.On a high level, the task is to create RequestTelemetry and set known properties. Al termine dell'operazione, tenere traccia dei dati di telemetria.After the operation is finished, you track the telemetry. L'esempio seguente illustra questa attività.The following example demonstrates this task.

Richiesta HTTP nell'app con self-hosting OwinHTTP request in Owin self-hosted app

In questo esempio, si seguirà il protocollo HTTP per la correlazione.In this example, we follow the HTTP Protocol for Correlation. Si deve prevedere di ricevere le intestazioni descritte qui.You should expect to receive headers that are described there.

public class ApplicationInsightsMiddleware : OwinMiddleware
{
    private readonly TelemetryClient telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);

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

Il protocollo HTTP per la correlazione dichiara inoltre l’intestazione Correlation-Context.The HTTP Protocol for Correlation also declares the Correlation-Context header. Tuttavia, è omesso qui per motivi di semplicità.However, it's omitted here for simplicity.

Strumentazione della codaQueue instrumentation

Per la comunicazione HTTP, è stato creato un protocollo per il passaggio dei dettagli della correlazione.For HTTP communication, we've created a protocol to pass correlation details. Con alcuni protocolli delle code è possibile passare metadati aggiuntivi con il messaggio, con altri invece non è consentito.With some queues' protocols, you can pass additional metadata along with the message, and with others you can't.

Coda del bus di servizioService Bus queue

Con la coda del bus di servizio di Microsoft Azure è possibile passare un contenitore di proprietà insieme al messaggio.With the Azure Service Bus queue, you can pass a property bag along with the message. Viene usato per passare l'ID di correlazione.We use it to pass the correlation ID.

La coda del bus di servizio usa protocolli basati su TCP.The Service Bus queue uses TCP-based protocols. Application Insights non tiene traccia automaticamente delle operazioni della coda, quindi ne viene tenuta traccia manualmente.Application Insights doesn't automatically track queue operations, so we track them manually. L'operazione di rimozione dalla coda è un'API di tipo push e non è possibile tenerne traccia.The dequeue operation is a push-style API, and we're unable to track it.

AccodareEnqueue

public async Task Enqueue(string payload)
{
    // StartOperation is a helper method that initializes the telemetry item
    // and allows correlation of this operation with its parent and children.
    var operation = telemetryClient.StartOperation<DependencyTelemetry>("enqueue " + queueName);
    operation.Telemetry.Type = "Queue";
    operation.Telemetry.Data = "Enqueue " + queueName;

    var message = new BrokeredMessage(payload);
    // Service Bus queue allows the property bag to pass along with the message.
    // We will use them to pass our correlation identifiers (and other context)
    // to the consumer.
    message.Properties.Add("ParentId", operation.Telemetry.Id);
    message.Properties.Add("RootId", operation.Telemetry.Context.Operation.Id);

    try
    {
        await queue.SendAsync(message);

        // Set operation.Telemetry Success and ResponseCode here.
        operation.Telemetry.Success = true;
    }
    catch (Exception e)
    {
        telemetryClient.TrackException(e);
        // Set operation.Telemetry Success and ResponseCode here.
        operation.Telemetry.Success = false;
        throw;
    }
    finally
    {
        telemetryClient.StopOperation(operation);
    }
}

ProcessProcess

public async Task Process(BrokeredMessage message)
{
    // After the message is taken from the queue, create RequestTelemetry to track its processing.
    // It might also make sense to get the name from the message.
    RequestTelemetry requestTelemetry = new RequestTelemetry { Name = "Dequeue " + queueName };

    var rootId = message.Properties["RootId"].ToString();
    var parentId = message.Properties["ParentId"].ToString();
    // Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
    requestTelemetry.Context.Operation.Id = rootId;
    requestTelemetry.Context.Operation.ParentId = 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);
    }
}

Coda di archiviazione di AzureAzure Storage queue

L'esempio seguente illustra come tenere traccia delle operazioni della coda di archiviazione di Azure e correlare i dati di telemetria tra producer, consumer e Archiviazione di Azure.The following example shows how to track the Azure Storage queue operations and correlate telemetry between the producer, the consumer, and Azure Storage.

La coda di archiviazione ha un'API HTTP.The Storage queue has an HTTP API. Tutte le chiamate alla coda vengono tracciate dall'agente di raccolta di dipendenze Application Insights per le richieste HTTP.All calls to the queue are tracked by the Application Insights Dependency Collector for HTTP requests. Assicurarsi di avere Microsoft.ApplicationInsights.DependencyCollector.HttpDependenciesParsingTelemetryInitializer in applicationInsights.config.Make sure you have Microsoft.ApplicationInsights.DependencyCollector.HttpDependenciesParsingTelemetryInitializer in applicationInsights.config. Se non è disponibile, aggiungerlo a livello di programmazione come descritto in Filtraggio e pre-elaborazione nell’SDK Azure Application Insights.If you don't have it, add it programmatically as described in Filtering and Preprocessing in the Azure Application Insights SDK.

Se si configura Application Insights manualmente, creare e inizializzare Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule in modo simile a:If you configure Application Insights manually, make sure you create and initialize Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule similarly to:

DependencyTrackingTelemetryModule module = new DependencyTrackingTelemetryModule();

// You can prevent correlation header injection to some domains by adding it to the excluded list.
// Make sure you add a Storage endpoint. Otherwise, you might experience request signature validation issues on the Storage service side.
module.ExcludeComponentCorrelationHttpHeadersOnDomains.Add("core.windows.net");
module.Initialize(TelemetryConfiguration.Active);

// Do not forget to dispose of the module during application shutdown.

Inoltre è possibile correlare l'ID operazione di Application Insights con l'ID di richiesta di Archiviazione.You also might want to correlate the Application Insights operation ID with the Storage request ID. Per informazioni su come impostare e ottenere un client di richiesta di Archivazione e un ID di richiesta del server, vedere Monitoraggio, diagnosi e risoluzione dei problemi dell'archiviazione di Azure.For information on how to set and get a Storage request client and a server request ID, see Monitor, diagnose, and troubleshoot Azure Storage.

AccodareEnqueue

Poiché le code di archiviazione di Azure supportano l'API HTTP, tutte le operazioni con la coda vengono automaticamente registrate da Application Insights.Because Storage queues support the HTTP API, all operations with the queue are automatically tracked by Application Insights. In molti casi, questa strumentazione dovrebbe essere sufficiente.In many cases, this instrumentation should be enough. Per correlare le tracce sul lato consumer con le tracce del producer, è necessario passare parte del contesto di correlazione in modo simile a quanto avviene nel protocollo HTTP per la correlazione.However, to correlate traces on the consumer side with producer traces, you must pass some correlation context similarly to how we do it in the HTTP Protocol for Correlation.

In questo esempio, si traccia l’operazione facoltativa Enqueue.In this example, we track the optional Enqueue operation. È possibile:You can:

  • Correlare gli eventuali tentativi, che hanno tutti un'operazione padre comune, ovvero Enqueue.Correlate retries (if any): They all have one common parent that's the Enqueue operation. In caso contrario, vengono registrati come elementi figlio della richiesta in ingresso.Otherwise, they're tracked as children of the incoming request. Se sono presenti più richieste logiche per la coda, potrebbe risultare difficile trovare la chiamata che ha restituito i tentativi.If there are multiple logical requests to the queue, it might be difficult to find which call resulted in retries.
  • Correlare i log di archiviazione (se e quando necessario) con i dati di telemetria di Application Insights.Correlate Storage logs (if and when needed): They're correlated with Application Insights telemetry.

L'operazione Enqueue è l’elemento figlio di un'operazione padre (ad esempio, una richiesta HTTP in ingresso).The Enqueue operation is the child of a parent operation (for example, an incoming HTTP request). La chiamata di dipendenza HTTP è l'elemento figlio dell'operazione Enqueue e nipote della richiesta in ingresso:The HTTP dependency call is the child of the Enqueue operation and the grandchild of the incoming request:

public async Task Enqueue(CloudQueue queue, string message)
{
    var operation = telemetryClient.StartOperation<DependencyTelemetry>("enqueue " + queue.Name);
    operation.Telemetry.Type = "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);
    }
}  

Per ridurre la quantità di dati di telemetria segnalati dall'applicazione o per non tenere traccia dell'operazione Enqueue per altri motivi, è possibile usare direttamente l'API Activity:To reduce the amount of telemetry your application reports or if you don't want to track the Enqueue operation for other reasons, use the Activity API directly:

  • Creare (e avviare) un nuovo Activity anziché avviare l'operazione Application Insights.Create (and start) a new Activity instead of starting the Application Insights operation. Non è necessario assegnare proprietà ad essa, tranne il nome dell'operazione.You do not need to assign any properties on it except the operation name.
  • Serializzare yourActivity.Id nel payload dei messaggi invece di operation.Telemetry.Id.Serialize yourActivity.Id into the message payload instead of operation.Telemetry.Id. È anche possibile usare Activity.Current.Id.You can also use Activity.Current.Id.

Rimuovere dalla codaDequeue

In modo simile a Enqueue, la richiesta HTTP effettiva per la coda di archiviazione viene automaticamente registrata da Application Insights.Similarly to Enqueue, an actual HTTP request to the Storage queue is automatically tracked by Application Insights. L'operazione Enqueue tuttavia viene probabilmente eseguita nel contesto padre, ad esempio il contesto della richiesta in ingresso.However, the Enqueue operation presumably happens in the parent context, such as an incoming request context. Gli SDK di Application Insights correlano automaticamente tale operazione (e la parte HTTP) con la richiesta padre e gli altri dati di telemetria segnalati nello stesso ambito.Application Insights SDKs automatically correlate such an operation (and its HTTP part) with the parent request and other telemetry reported in the same scope.

L'operazione Dequeue è un'operazione complessa.The Dequeue operation is tricky. L’SDK Application Insights tiene automaticamente traccia delle richieste HTTP.The Application Insights SDK automatically tracks HTTP requests. Tuttavia, non conosce il contesto di correlazione fino a quando non viene analizzato il messaggio.However, it doesn't know the correlation context until the message is parsed. Non è possibile correlare la richiesta HTTP per ottenere il messaggio con gli altri dati di telemetria.It's not possible to correlate the HTTP request to get the message with the rest of the telemetry.

In molti casi, può essere utile correlare la richiesta di coda HTTP anche con le altre tracce.In many cases, it might be useful to correlate the HTTP request to the queue with other traces as well. L'esempio seguente illustra come fare:The following example demonstrates how to do it:

public async Task<MessagePayload> Dequeue(CloudQueue queue)
{
    var telemetry = new DependencyTelemetry
    {
        Type = "Queue",
        Name = "Dequeue " + queue.Name
    };

    telemetry.Start();

    try
    {
        var message = await queue.GetMessageAsync();

        if (message != null)
        {
            var payload = JsonConvert.DeserializeObject<MessagePayload>(message.AsString);

            // If there is a message, we want to correlate the Dequeue operation with processing.
            // However, we will only know what correlation ID to use after we get it from the message,
            // so we will report telemetry after we know the IDs.
            telemetry.Context.Operation.Id = payload.RootId;
            telemetry.Context.Operation.ParentId = payload.ParentId;

            // Delete the message.
            return payload;
        }
    }
    catch (StorageException e)
    {
        telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
        telemetry.Success = false;
        telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
        telemetryClient.TrackException(e);
    }
    finally
    {
        // Update status code and success as appropriate.
        telemetry.Stop();
        telemetryClient.Track(telemetry);
    }

    return null;
}

ProcessProcess

Nell'esempio seguente viene tracciato il messaggio in arrivo in modo simile a quanto avviene per la richiesta HTTP in ingresso:In the following example, we trace an incoming message in a manner similarly to how we trace an incoming HTTP request:

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 = "Dequeue " + 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);
    }
}

Analogamente, è possibile instrumentare le altre operazioni della coda.Similarly, other queue operations can be instrumented. L'operazione di visualizzazione deve essere instrumentata in modo simile a quella di rimozione dalla coda.A peek operation should be instrumented in a similar way as a dequeue operation. Non è necessario instrumentare operazioni di gestione della coda.Instrumenting queue management operations isn't necessary. Application Insights tiene traccia di operazioni come HTTP e nella maggior parte dei casi è sufficiente.Application Insights tracks operations such as HTTP, and in most cases, it's enough.

Quando si instrumenta l'eliminazione di un messaggio, assicurarsi di impostare gli identificatori delle operazioni (correlazione).When you instrument message deletion, make sure you set the operation (correlation) identifiers. In alternativa, è possibile usare l'API Activity.Alternatively, you can use the Activity API. Non è quindi necessario impostare gli identificatori delle operazioni negli elementi di telemetria perché Application Insights esegue questa operazione automaticamente:Then you don't need to set operation identifiers on the telemetry items because Application Insights does it for you:

  • Creare un nuovo oggetto Activity dopo avere ottenuto un elemento dalla coda.Create a new Activity after you've got an item from the queue.
  • Usare Activity.SetParentId(message.ParentId) per correlare i log del consumer e del producer.Use Activity.SetParentId(message.ParentId) to correlate consumer and producer logs.
  • Avviare il Activity.Start the Activity.
  • Tenere traccia delle operazioni di rimozione dalla coda, elaborazione ed eliminazione usando gli helper Start/StopOperation.Track dequeue, process, and delete operations by using Start/StopOperation helpers. dallo stesso flusso di controllo asincrono (contesto di esecuzione).Do it from the same asynchronous control flow (execution context). In questo modo la correlazione sarà corretta.In this way, they're correlated properly.
  • Arrestare il Activity.Stop the Activity.
  • Usare Start/StopOperation o chiamare Track telemetry manualmente.Use Start/StopOperation, or call Track telemetry manually.

Elaborazione batchBatch processing

Per alcune code, è possibile una rimozione dalla coda di più messaggi con una singola richiesta.With some queues, you can dequeue multiple messages with one request. L'elaborazione di tali messaggi è presumibilmente indipendente e appartiene a diverse operazioni logiche.Processing such messages is presumably independent and belongs to the different logical operations. In questo caso, non è possibile correlare l'operazione Dequeue a una determinata elaborazione dei messaggi.In this case, it's not possible to correlate the Dequeue operation to particular message processing.

Ogni elaborazione dei messaggi deve essere eseguita nel proprio flusso di controllo asincrono.Each message should be processed in its own asynchronous control flow. Per ulteriori informazioni, vedere la sezione Verifica delle dipendenze in uscita.For more information, see the Outgoing dependencies tracking section.

Attività in background a esecuzione prolungataLong-running background tasks

Alcune applicazioni avviano operazioni a esecuzione prolungata che possono essere causate dalle richieste degli utenti.Some applications start long-running operations that might be caused by user requests. Dal punto di vista della verifica/strumentazione, non c'è differenza dalla strumentazione delle richieste o delle dipendenze:From the tracing/instrumentation perspective, it's not different from request or dependency instrumentation:

async Task BackgroundTask()
{
    var operation = telemetryClient.StartOperation<RequestTelemetry>(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 questo esempio, si usa telemetryClient.StartOperation per creare RequestTelemetry e riempire il contesto di correlazione.In this example, we use telemetryClient.StartOperation to create RequestTelemetry and fill the correlation context. Si supponga di avere un'operazione padre creata dalle richieste in ingresso che hanno pianificato l'operazione.Let's say you have a parent operation that was created by incoming requests that scheduled the operation. BackgroundTask, purché venga avviato nello stesso flusso di controllo asincrono di una richiesta in ingresso, viene correlato con tale operazione padre.As long as BackgroundTask starts in the same asynchronous control flow as an incoming request, it's correlated with that parent operation. BackgroundTask e tutti gli elementi di telemetria annidati vengono automaticamente correlati alla richiesta che l'ha generato anche dopo la fine della richiesta.BackgroundTask and all nested telemetry items are automatically correlated with the request that caused it, even after the request ends.

Quando l'attività viene avviata dal thread in background a cui non sono associate operazioni (Activity), BackgroundTask non ha elementi padre.When the task starts from the background thread that doesn't have any operation (Activity) associated with it, BackgroundTask doesn't have any parent. Tuttavia, può avere operazioni annidate.However, it can have nested operations. Tutti gli elementi di telemetria segnalati dall'attività sono correlati a RequestTelemetry creato in BackgroundTask.All telemetry items reported from the task are correlated to the RequestTelemetry created in BackgroundTask.

Verifica delle dipendenze in uscitaOutgoing dependencies tracking

È possibile tenere traccia della propria tipologia di dipendenza o di operazioni non supportate da Application Insights.You can track your own dependency kind or an operation that's not supported by Application Insights.

Il metodo Enqueue nella coda del bus di servizio o nella coda di archiviazione è un esempio di tale verifica personalizzata.The Enqueue method in the Service Bus queue or the Storage queue can serve as examples for such custom tracking.

L'approccio generale per la verifica personalizzata delle dipendenze è:The general approach for custom dependency tracking is to:

  • Chiamare il metodo TelemetryClient.StartOperation (estensione) che riempie le proprietà DependencyTelemetry necessarie per la correlazione e altre proprietà (timestamp di avvio, durata).Call the TelemetryClient.StartOperation (extension) method that fills the DependencyTelemetry properties that are needed for correlation and some other properties (start time stamp, duration).
  • Impostare le altre proprietà personalizzate in DependencyTelemetry, ad esempio nome e altri contesti necessari.Set other custom properties on the DependencyTelemetry, such as the name and any other context you need.
  • Effettuare una chiamata di dipendenza e attendere.Make a dependency call and wait for it.
  • Al termine, arrestare l'operazione con StopOperation.Stop the operation with StopOperation when it's finished.
  • Gestire le eccezioni.Handle exceptions.

StopOperation arresta solo l'operazione che è stata avviata.StopOperation only stops the operation that was started. Se l'operazione corrente in esecuzione non corrisponde all'operazione che si desidera arrestare, StopOperation non esegue alcuna operazione.If the current running operation doesn't match the one you want to stop, StopOperation does nothing. Questa situazione può verificarsi se si avviano più operazioni in parallelo nello stesso contesto di esecuzione:This situation might happen if you start multiple operations in parallel in the same execution context:

var firstOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 1");
var firstOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 1");
var firstTask = RunMyTaskAsync();

var secondOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 2");
var secondTask = RunMyTaskAsync();

await firstTask;

// This will do nothing and will not report telemetry for the first operation
// as currently secondOperation is active.
telemetryClient.StopOperation(firstOperation); 

await secondTask;

È quindi necessario assicurarsi di chiamare sempre StartOperation e di eseguire l'attività nel contesto corretto:Make sure you always call StartOperation and run your task in its own context:

public async Task RunMyTaskAsync()
{
    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.
    }
    finally 
    {
        telemetryClient.StopOperation(operation);
    }
}

Passaggi successiviNext steps