Diagnosticare le eccezioni nelle app Web con Application Insights

Nota

La documentazione seguente si basa sull'API classica di Application Insights. Il piano a lungo termine per Application Insights consiste nel raccogliere dati usando OpenTelemetry. Per altre informazioni, vedere Abilitare OpenTelemetry di Monitoraggio di Azure per le applicazioni .NET, Node.js, Python e Java.

Le eccezioni nelle applicazioni Web possono essere segnalate con Application Insights. È possibile correlare le richieste non riuscite con le eccezioni e altri eventi sia nel client che nel server, in modo da poter diagnosticare rapidamente le cause. Questo articolo illustra come configurare la segnalazione delle eccezioni, segnalare le eccezioni in modo esplicito, diagnosticare gli errori e altro ancora.

Configurare la creazione di report sulle eccezioni

È possibile configurare Application Insights per segnalare le eccezioni che si verificano nel server o nel client. A seconda della piattaforma da cui dipende l'applicazione, sarà necessaria l'estensione o l'SDK appropriato.

Lato server

Per fare in modo che le eccezioni vengano segnalate dall'applicazione sul lato server, considerare gli scenari seguenti:

  • Aggiungere l'estensione Application Insights per le app Web di Azure.
  • Aggiungere l'estensione di monitoraggio delle applicazioni per Azure Macchine virtuali e azure set di scalabilità di macchine virtuali app ospitate in IIS.
  • Installare Application Insights SDK nel codice dell'app, eseguire Application Insights Agent per server Web IIS o abilitare l'agente Java per le app Web Java.

Lato client

JavaScript SDK offre la possibilità di creare report sul lato client di eccezioni che si verificano nei Web browser. Per configurare la segnalazione delle eccezioni nel client, vedere Application Insights per le pagine Web.

Framework applicazioni

Con alcuni framework dell'applicazione, è necessaria una maggiore configurazione. Si considerino le tecnologie seguenti:

Importante

Questo articolo è incentrato in modo specifico sulle app .NET Framework dal punto di vista di un esempio di codice. Alcuni dei metodi che funzionano per .NET Framework sono obsoleti in .NET Core SDK. Per altre informazioni, vedere la documentazione di .NET Core SDK quando si compilano app con .NET Core.

Diagnosticare le eccezioni con Visual Studio

Apri la soluzione dell'app in Visual Studio. Eseguire l'app nel server o nel computer di sviluppo usando F5. Ricreare l'eccezione.

Aprire la finestra di telemetria di ricerca di Application Insights in Visual Studio. Durante il debug selezionare la casella di riepilogo a discesa Application Insights .

Screenshot that shows right-clicking the project and choosing Application Insights.

Selezionare un report eccezioni per visualizzarne l'analisi dello stack. Per aprire il file di codice pertinente, selezionare un riferimento a riga nell'analisi dello stack.

Se CodeLens è abilitato, verranno visualizzati i dati sulle eccezioni:

Screenshot that shows CodeLens notification of exceptions.

Diagnosticare gli errori usando il portale di Azure

Application Insights offre un'esperienza di gestione delle prestazioni delle applicazioni curata che consente di diagnosticare gli errori nelle applicazioni monitorate. Per iniziare, nel menu delle risorse di Application Insights a sinistra, in Ricerca, selezionare l'opzione Errori .

Verranno visualizzate le tendenze del tasso di errore per le richieste, il numero di errori e il numero di utenti interessati. La visualizzazione Complessiva mostra alcune delle distribuzioni più utili specifiche per l'operazione di errore selezionata. Verranno visualizzati i primi tre codici di risposta, i primi tre tipi di eccezione e i primi tre tipi di dipendenza con errori.

Screenshot that shows a failures triage view on the Operations tab.

Per esaminare esempi rappresentativi per ognuno di questi subset di operazioni, selezionare il collegamento corrispondente. Ad esempio, per diagnosticare le eccezioni, è possibile selezionare il conteggio di una particolare eccezione da visualizzare con la scheda Dettagli transazione end-to-end.

Screenshot that shows the End-to-end transaction details tab.

In alternativa, invece di esaminare le eccezioni di un'operazione di errore specifica, è possibile iniziare dalla visualizzazione Complessiva delle eccezioni passando alla scheda Eccezioni nella parte superiore. Qui è possibile visualizzare tutte le eccezioni raccolte per l'app monitorata.

Dati di traccia e di log personalizzati

Per ottenere dati di diagnostica specifici per l'app, è possibile inserire codice per l'invio di dati di telemetria personalizzati. I dati di telemetria o di log personalizzati vengono visualizzati nella ricerca diagnostica insieme alla richiesta, alla visualizzazione pagina e ad altri dati raccolti automaticamente.

Microsoft.VisualStudio.ApplicationInsights.TelemetryClientUsando , sono disponibili diverse API:

  • TelemetryClient.TrackEvent viene in genere usato per il monitoraggio dei modelli di utilizzo, ma i dati inviati vengono visualizzati anche in Eventi personalizzati nella ricerca diagnostica. Gli eventi sono denominati e possono contenere proprietà di stringa e metriche numeriche in cui è possibile filtrare le ricerche di diagnostica.
  • TelemetryClient.TrackTrace consente di inviare dati più lunghi, ad esempio le informazioni POST.
  • TelemetryClient.TrackException invia i dettagli dell'eccezione, ad esempio le analisi dello stack ad Application Insights.

Per visualizzare questi eventi, nel menu a sinistra aprire Cerca. Selezionare il menu a discesa Tipi di evento e quindi scegliere Evento personalizzato, Traccia o Eccezione.

Screenshot that shows the Search screen.

Nota

Se l'app genera molti dati di telemetria, il modulo di campionamento adattivo ridurrà automaticamente il volume inviato al portale inviando solo una frazione rappresentativa di eventi. Gli eventi che fanno parte della stessa operazione verranno selezionati o deselezionati come gruppo in modo da poter spostarsi tra eventi correlati. Per altre informazioni, vedere Campionamento in Application Insights.

Vedere richiedere i dati POST

I dettagli della richiesta non includono i dati inviati all'app in una chiamata POST. Per poter ottenere questi dati:

  • Installare l'SDK nel progetto dell'applicazione.
  • Inserire il codice nell'applicazione per chiamare Microsoft.ApplicationInsights.TrackTrace(). Inviare i dati POST nel parametro del messaggio. Esiste un limite alle dimensioni consentite, quindi è consigliabile provare a inviare solo i dati essenziali.
  • Quando si esamina una richiesta non riuscita, trovare le tracce associate.

Acquisire eccezioni e dati di diagnostica correlati

Inizialmente, nel portale non verranno visualizzate tutte le eccezioni che causano errori nell'app. Verranno visualizzate eventuali eccezioni del browser, se si usa JavaScript SDK nelle pagine Web. La maggior parte delle eccezioni del server viene rilevata da IIS, ma è necessario scrivere qualche riga di codice per visualizzarle.

È possibile:

  • Registrare le eccezioni in modo esplicito inserendo il codice nei gestori di eccezioni per segnalare le eccezioni.
  • Acquisire automaticamente le eccezioni configurando il framework di ASP.NET. Gli elementi da aggiungere variano a seconda dei diversi tipi di framework.

Segnalare le eccezioni in modo esplicito

Il modo più semplice per segnalare consiste nell'inserire una chiamata a trackException() in un gestore eccezioni.

try
{
    // ...
}
catch (ex)
{
    appInsights.trackException(ex, "handler loc",
    {
        Game: currentGame.Name,
        State: currentGame.State.ToString()
    });
}
var telemetry = new TelemetryClient();

try
{
    // ...
}
catch (Exception ex)
{
    var properties = new Dictionary<string, string>
    {
        ["Game"] = currentGame.Name
    };

    var measurements = new Dictionary<string, double>
    {
        ["Users"] = currentGame.Users.Count
    };

    // Send the exception telemetry:
    telemetry.TrackException(ex, properties, measurements);
}
Dim telemetry = New TelemetryClient

Try
    ' ...
Catch ex as Exception
    ' Set up some properties:
    Dim properties = New Dictionary (Of String, String)
    properties.Add("Game", currentGame.Name)

    Dim measurements = New Dictionary (Of String, Double)
    measurements.Add("Users", currentGame.Users.Count)

    ' Send the exception telemetry:
    telemetry.TrackException(ex, properties, measurements)
End Try

I parametri delle proprietà e delle misurazioni sono facoltativi, ma sono utili per filtrare e aggiungere informazioni aggiuntive. Ad esempio, per un'app in grado di eseguire diversi giochi, è possibile trovare tutti i report di eccezione correlati a un gioco specifico. È possibile aggiungere tutti gli elementi desiderati a ogni dizionario.

Eccezioni del browser

Viene segnalata la maggior parte delle eccezioni del browser.

Se la pagina Web include file di script da reti per la distribuzione di contenuti o altri domini, verificare che il tag script abbia l'attributo crossorigin="anonymous" e che il server invii intestazioni CORS. Questo comportamento consente di ottenere una traccia dello stack e dettagli per le eccezioni JavaScript non gestite da queste risorse.

Riutilizzare il client di telemetria

Nota

È consigliabile creare un'istanza di TelemetryClient una volta e riutilizzarla per tutta la durata di un'applicazione.

Con l'inserimento delle dipendenze (DI) in .NET, .NET SDK appropriato e la corretta configurazione di Application Insights per l'inserimento delle dipendenze, è possibile richiedere come parametro del TelemetryClient costruttore.

public class ExampleController : ApiController
{
    private readonly TelemetryClient _telemetryClient;

    public ExampleController(TelemetryClient telemetryClient)
    {
        _telemetryClient = telemetryClient;
    }
}

Nell'esempio precedente, l'oggetto TelemetryClient viene inserito nella ExampleController classe .

Web Form

Per i web form, il modulo HTTP sarà in grado di raccogliere le eccezioni quando non sono presenti reindirizzamenti configurati con CustomErrors. Tuttavia, quando sono presenti reindirizzamenti attivi, aggiungere le righe seguenti alla Application_Error funzione in Global.asax.cs.

void Application_Error(object sender, EventArgs e)
{
    if (HttpContext.Current.IsCustomErrorEnabled &&
        Server.GetLastError () != null)
    {
        _telemetryClient.TrackException(Server.GetLastError());
    }
}

Nell'esempio precedente, è _telemetryClient una variabile con ambito classe di tipo TelemetryClient.

MVC

A partire da Application Insights Web SDK versione 2.6 (beta 3 e successive), Application Insights raccoglie automaticamente le eccezioni non gestite generate nei metodi controller MVC 5+. Se in precedenza è stato aggiunto un gestore personalizzato per tenere traccia di tali eccezioni, è possibile rimuoverlo per impedire il doppio rilevamento delle eccezioni.

Esistono diversi scenari in cui un filtro eccezioni non riesce a gestire correttamente gli errori quando vengono generate eccezioni:

  • Dai costruttori del controller
  • Dai gestori di messaggi
  • Durante il routing
  • Durante la serializzazione del contenuto della risposta
  • Durante l'avvio dell'applicazione
  • Nelle attività in background

È ancora necessario tenere traccia manualmente di tutte le eccezioni gestite dall'applicazione. Le eccezioni non gestite provenienti dai controller generano in genere una risposta di 500 "Errore interno del server". Se tale risposta viene costruita manualmente come risultato di un'eccezione gestita o nessuna eccezione, viene rilevata nei dati di telemetria delle richieste corrispondenti con ResultCode 500. Tuttavia, Application Insights SDK non è in grado di tenere traccia di un'eccezione corrispondente.

Supporto nelle versioni precedenti

Se si usa MVC 4 (e versioni precedenti) di Application Insights Web SDK 2.5 (e versioni precedenti), vedere gli esempi seguenti per tenere traccia delle eccezioni.

Se la configurazione CustomErrors è Off, le eccezioni saranno disponibili per il modulo HTTP da raccogliere. Tuttavia, se è RemoteOnly (impostazione predefinita) o On, l'eccezione verrà cancellata e non sarà disponibile per Application Insights per la raccolta automatica. È possibile correggere il comportamento eseguendo l'override della classe System.Web.Mvc.HandleErrorAttribute e applicando la classe sottoposta a override come illustrato per le diverse versioni MVC qui (vedere l'origine GitHub):

using System;
using System.Web.Mvc;
using Microsoft.ApplicationInsights;

namespace MVC2App.Controllers
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AiHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext != null && filterContext.HttpContext != null && filterContext.Exception != null)
            {
                //The attribute should track exceptions only when CustomErrors setting is On
                //if CustomErrors is Off, exceptions will be caught by AI HTTP Module
                if (filterContext.HttpContext.IsCustomErrorEnabled)
                {   //Or reuse instance (recommended!). See note above.
                    var ai = new TelemetryClient();
                    ai.TrackException(filterContext.Exception);
                }
            }
            base.OnException(filterContext);
        }
    }
}

MVC 2

Sostituire l'attributo HandleError con il nuovo attributo nei controller:

    namespace MVC2App.Controllers
    {
        [AiHandleError]
        public class HomeController : Controller
        {
            // Omitted for brevity
        }
    }

Esempio

MVC 3

Registrarsi AiHandleErrorAttribute come filtro globale in Global.asax.cs:

public class MyMvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new AiHandleErrorAttribute());
    }
}

Esempio

MVC 4, MVC 5

Registrare AiHandleErrorAttribute come filtro globale in FilterConfig.cs:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        // Default replaced with the override to track unhandled exceptions
        filters.Add(new AiHandleErrorAttribute());
    }
}

Esempio

API Web

A partire da Application Insights Web SDK versione 2.6 (beta 3 e successive), Application Insights raccoglie le eccezioni non gestite generate automaticamente nei metodi controller per l'API Web 2+. Se in precedenza è stato aggiunto un gestore personalizzato per tenere traccia di tali eccezioni, come descritto negli esempi seguenti, è possibile rimuoverlo per impedire il doppio rilevamento delle eccezioni.

Esistono diversi casi in cui i filtri delle eccezioni non possono essere gestiti. Ad esempio:

  • Eccezioni generate dai costruttori dei controller.
  • Eccezioni generate dai gestori di messaggi.
  • Eccezioni generate durante il routing.
  • Eccezioni generate durante la serializzazione del contenuto della risposta.
  • Eccezione generata durante l'avvio dell'applicazione.
  • Eccezione generata in attività in background.

È ancora necessario tenere traccia manualmente di tutte le eccezioni gestite dall'applicazione. Le eccezioni non gestite provenienti dai controller generano in genere una risposta di 500 "Errore interno del server". Se tale risposta viene costruita manualmente come risultato di un'eccezione gestita o nessuna eccezione, viene rilevata in una telemetria di richiesta corrispondente con ResultCode 500. Tuttavia, Application Insights SDK non è in grado di tenere traccia di un'eccezione corrispondente.

Supporto nelle versioni precedenti

Se si usa l'API Web 1 (e versioni precedenti) di Application Insights Web SDK 2.5 (e versioni precedenti), fare riferimento agli esempi seguenti per tenere traccia delle eccezioni.

API Web 1.x

Eseguire l'override System.Web.Http.Filters.ExceptionFilterAttributedi :

using System.Web.Http.Filters;
using Microsoft.ApplicationInsights;

namespace WebAPI.App_Start
{
    public class AiExceptionFilterAttribute : ExceptionFilterAttribute
    {
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext != null && actionExecutedContext.Exception != null)
        {  //Or reuse instance (recommended!). See note above.
            var ai = new TelemetryClient();
            ai.TrackException(actionExecutedContext.Exception);
        }
        base.OnException(actionExecutedContext);
    }
    }
}

È possibile aggiungere questo attributo sottoposto a override a controller specifici o aggiungerlo alla configurazione del filtro globale nella WebApiConfig classe :

using System.Web.Http;
using WebApi1.x.App_Start;

namespace WebApi1.x
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });
    
            // ...
            config.EnableSystemDiagnosticsTracing();
    
            // Capture exceptions for Application Insights:
            config.Filters.Add(new AiExceptionFilterAttribute());
        }
    }
}

Esempio

API Web 2.x

Aggiungere un'implementazione di IExceptionLogger:

using System.Web.Http.ExceptionHandling;
using Microsoft.ApplicationInsights;

namespace ProductsAppPureWebAPI.App_Start
{
    public class AiExceptionLogger : ExceptionLogger
    {
        public override void Log(ExceptionLoggerContext context)
        {
            if (context != null && context.Exception != null)
            {
                //or reuse instance (recommended!). see note above
                var ai = new TelemetryClient();
                ai.TrackException(context.Exception);
            }
            base.Log(context);
        }
    }
}

Aggiungere questo frammento di codice ai servizi in WebApiConfig:

using System.Web.Http;
using System.Web.Http.ExceptionHandling;
using ProductsAppPureWebAPI.App_Start;

namespace WebApi2WithMVC
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
    
            // Web API routes
            config.MapHttpAttributeRoutes();
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });

            config.Services.Add(typeof(IExceptionLogger), new AiExceptionLogger());
        }
    }
}

Esempio

In alternativa, è possibile:

  • Sostituire l'unica ExceptionHandler istanza con un'implementazione personalizzata di IExceptionHandler. Questo gestore eccezioni viene chiamato solo quando il framework è ancora in grado di scegliere il messaggio di risposta da inviare, non quando la connessione viene interrotta, ad esempio.
  • Usare i filtri eccezioni, come descritto nella sezione precedente sui controller dell'API Web 1.x, che non vengono chiamati in tutti i casi.

WCF

Aggiungere una classe che estende Attribute e implementa IErrorHandler e IServiceBehavior.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher;
    using System.Web;
    using Microsoft.ApplicationInsights;

    namespace WcfService4.ErrorHandling
    {
      public class AiLogExceptionAttribute : Attribute, IErrorHandler, IServiceBehavior
      {
        public void AddBindingParameters(ServiceDescription serviceDescription,
            System.ServiceModel.ServiceHostBase serviceHostBase,
            System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,
            System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
            System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher disp in serviceHostBase.ChannelDispatchers)
            {
                disp.ErrorHandlers.Add(this);
            }
        }

        public void Validate(ServiceDescription serviceDescription,
            System.ServiceModel.ServiceHostBase serviceHostBase)
        {
        }

        bool IErrorHandler.HandleError(Exception error)
        {//or reuse instance (recommended!). see note above
            var ai = new TelemetryClient();

            ai.TrackException(error);
            return false;
        }

        void IErrorHandler.ProvideFault(Exception error,
            System.ServiceModel.Channels.MessageVersion version,
            ref System.ServiceModel.Channels.Message fault)
        {
        }
      }
    }

Aggiungere l'attributo alle implementazioni del servizio:

namespace WcfService4
{
    [AiLogException]
    public class Service1 : IService1
    {
        // Omitted for brevity
    }
}

Esempio

Contatori delle prestazioni per le eccezioni

Se è stato installato l'agente di Application Insights di Monitoraggio di Azure nel server, è possibile ottenere un grafico della frequenza delle eccezioni, misurata da .NET. Sono incluse eccezioni .NET gestite e non gestite.

Aprire una scheda Esplora metriche, aggiungere un nuovo grafico. In Contatori delle prestazioni selezionare Frequenza eccezioni.

.NET Framework calcola la frequenza conteggiando il numero di eccezioni in un intervallo e dividendo per la lunghezza dell'intervallo.

Questo conteggio è diverso dal numero di eccezioni calcolato dal conteggio dei report del portale TrackException di Application Insights. Gli intervalli di campionamento sono diversi e l'SDK non invia TrackException report per tutte le eccezioni gestite e non gestite.

Passaggi successivi