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:
- App Web di Azure: aggiungere l'estensione di Application Insights.
- Aggiungere l'estensione di monitoraggio delle applicazioni per macchine virtuali di Azure e le app ospitate in IIS per set di scalabilità di macchine virtuali di Azure.
- 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 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:
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.
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.
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:
- TelemetryClient.TrackEvent viene usato in genere 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 includere proprietà di stringa e metriche numeriche, in base alle quali è possibile filtrare le ricerche diagnostiche.
- TelemetryClient.TrackTrace permette di inviare dati più lunghi, ad esempio 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.
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
}
}
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());
}
}
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());
}
}
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());
}
}
}
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());
}
}
}
In alternativa, è possibile:
- Sostituire l'unica istanza
ExceptionHandler
con un'implementazione personalizzata diIExceptionHandler
. 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
}
}
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.