Diagnosticare 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 prevede la raccolta di dati con OpenTelemetry. Per altre informazioni, vedere Abilitare OpenTelemetry di Monitoraggio di Azure per le applicazioni .NET, Node.js, Python e Java oltre che la Roadmap OpenTelemetry. Le indicazioni sulla migrazione sono disponibili per .NET, Node.js e Python.

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, saranno necessari l'estensione o l'SDK appropriati.

Lato server

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

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 Application Insights Search in Visual Studio. Durante il debug selezionare la casella di riepilogo a discesa Application Insights .

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

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

Screenshot che mostra la notifica CodeLens delle eccezioni.

Diagnosticare gli errori con 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 Analisi, 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 che mostra una visualizzazione di valutazione degli errori nella scheda Operazioni.

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 che mostra la scheda dei dettagli delle transazioni end-to-end.

In alternativa, invece di esaminare le eccezioni di un'operazione non riuscita specifica, è possibile iniziare dalla visualizzazione complessiva delle eccezioni, passando alla scheda Eccezioni in alto. 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 di pagina e ad altri dati raccolti automaticamente.

Usando Microsoft.VisualStudio.ApplicationInsights.TelemetryClient, sono disponibili diverse API:

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 che mostra la schermata Cerca.

Nota

Se l'app genera molti dati di telemetria, il modulo di campionamento adattivo riduce automaticamente il volume che viene inviato al portale inviando solo una frazione rappresentativa di eventi. Gli eventi che fanno parte della stessa operazione verranno selezionati o deselezionati come gruppo, per rendere possibile lo spostamento tra eventi correlati. Per altre informazioni, vedere Campionamento in Application Insights.

Vedere i dati POST di una richiesta

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 per le dimensioni consentite, quindi è consigliabile provare a inviare solo i dati essenziali.
  • Quando si esamina una richiesta non riuscita, trovare le tracce associate.

Acquisizione delle eccezioni e dei relativi dati di diagnostica

Inizialmente, nel portale non verranno visualizzate tutte le eccezioni che causano errori nell'app. Verranno visualizzate tutte le 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 altre informazioni. 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 il numero desiderato di elementi a ogni dizionario.

Eccezioni del browser

Viene segnalata la maggior parte delle eccezioni del browser.

Se la pagina Web include file di script provenienti da reti per la distribuzione di contenuti o da altri domini, verificare che il tag dello script contenga l'attributo crossorigin="anonymous" e che il server invii intestazioni CORS. Questo comportamento consentirà di ottenere un'analisi dello stack e i 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, il .NET SDK appropriato e la corretta configurazione di Application Insights per l'inserimento delle dipendenze, è possibile richiedere TelemetryClient come parametro del costruttore.

public class ExampleController : ApiController
{
    private readonly TelemetryClient _telemetryClient;

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

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

Web Form

Per Web Form, il modulo HTTP potrà raccogliere le eccezioni quando non sono configurati reindirizzamenti con CustomErrors. Tuttavia, quando sono presenti reindirizzamenti attivi, aggiungere le righe seguenti alla funzione Application_Error 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 versioni successive), Application Insights raccoglie le eccezioni non gestite generate automaticamente nei metodi dei controller MVC 5+. Se in precedenza è stato aggiunto un gestore personalizzato per tenere traccia di tali eccezioni, è possibile rimuoverlo per evitare 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 da controller restituiscono in genere una risposta 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 di CustomErrors è Off, le eccezioni potranno essere raccolte dal modulo HTTP. Se tuttavia si tratta di RemoteOnly (impostazione predefinita) o On, l'eccezione verrà cancellata e non potrà essere raccolta automaticamente da Application Insights. È possibile risolvere questo comportamento eseguendo l'override della classe System.Web.Mvc.HandleErrorAttribute e applicando la classe di cui è stato eseguito l'override, come illustrato per le diverse versioni MVC riportate di seguito (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

Registrare 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 versioni successive), Application Insights raccoglie le eccezioni non gestite generate automaticamente nei metodi dei controller per API Web 2+. Se in precedenza è stato aggiunto un gestore personalizzato per tenere traccia di tali eccezioni (come descritto nell'esempio seguente), è possibile rimuoverlo per evitare 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 da controller restituiscono in genere una risposta 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 API Web 1 (e versioni precedenti) di Application Insights Web SDK 2.5 (e versioni precedenti), vedere gli esempi seguenti per tenere traccia delle eccezioni.

API Web 1.x

Override System.Web.Http.Filters.ExceptionFilterAttribute:

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

Sarà possibile aggiungere questo attributo di cui è stato eseguito l'override ai controller specifici o alla configurazione del filtro globale nella classe WebApiConfig:

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 istanza ExceptionHandler con un'implementazione personalizzata di IExceptionHandler. Questo gestore di eccezione viene chiamato solo quando il framework può ancora scegliere il messaggio di risposta da inviare, non quando la connessione viene interrotta.
  • 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

L'installazione dell'agente di Application Insights di Monitoraggio di Azure nel server permette di ottenere un grafico della frequenza delle eccezioni, misurata da .NET. Le eccezioni .NET gestite e non gestite sono incluse.

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

.NET framework calcola la frequenza contando il numero delle eccezioni in un intervallo e dividendolo per la lunghezza dell'intervallo.

Questo conteggio è diverso dal conteggio delle eccezioni calcolato dal portale di Application Insights, che conteggia i report TrackException. Gli intervalli di campionamento sono diversi e il SDK non invia report di TrackException per tutte le eccezioni gestite e non gestite.

Passaggi successivi