Diagnosticar exceções em aplicativos Web com o Application Insights

Exceções em aplicativos Web podem ser relatadas com o Application Insights. Você pode correlacionar solicitações com falha com exceções e outros eventos no cliente e no servidor, para poder diagnosticar as causas rapidamente. Neste artigo, você aprenderá a configurar relatórios de exceção, relatar exceções explicitamente, diagnosticar falhas e muito mais.

Configurar os relatórios de exceção

Você pode configurar o Application Insights para relatar exceções que ocorrem no servidor ou no cliente. Dependendo da plataforma de que seu aplicativo depende, você precisará da extensão apropriada ou do SDK.

Lado do Servidor

Para ter exceções relatadas do seu aplicativo do lado do servidor, considere os seguintes cenários:

Lado do cliente

O SDK do JavaScript fornece a capacidade de relatórios do lado do cliente de exceções que ocorrem em navegadores da Web. Para configurar relatórios de exceção no cliente, consulte Application Insights para páginas da Web.

Estruturas do aplicativo

Algumas estruturas do aplicativo exigem mais configuração. Considere as seguintes tecnologias:

Importante

Este artigo se concentra especificamente em aplicativos .NET Framework a partir de uma perspectiva de exemplo de código. Alguns dos métodos que funcionam para .NET Framework estão obsoletos no SDK do .NET Core. Para obter mais informações, consulte SDK do .NET Core ao criar aplicativos com o .NET Core.

Diagnosticar exceções usando o Visual Studio

Abra a solução do aplicativo no Visual Studio. Execute o aplicativo, em seu servidor ou na máquina de desenvolvimento, usando F5. Recrie a exceção.

Abra a janela de telemetria de Application Insights Search no Visual Studio. Durante a depuração, selecione a caixa suspensa Application Insights.

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

Selecione um relatório de exceções para mostrar o rastreamento de pilha. Selecione uma referência de linha no rastreamento de pilha para abrir o arquivo de código relevante.

Se o CodeLens estiver habilitado, você verá dados sobre as exceções:

Screenshot that shows CodeLens notification of exceptions.

Diagnosticar falhas usando o portal do Azure

O Application Insights vem com uma experiência de Gerenciamento de desempenho de aplicativos coletada para lhe ajudar a diagnosticar falhas nos aplicativos monitorados. Para iniciar, no menu de recursos do Application Insights à esquerda, em Investigar, selecione a opção Falhas.

Você verá as tendências de taxa de falha para suas solicitações, quantas delas estão falhando e quantos usuários são afetados. A exibição Geral mostra algumas das distribuições mais úteis específicas para a operação de falha selecionada. Você verá os três principais códigos de resposta, os três principais tipos de exceção e os três principais tipos de dependência com falha.

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

Para examinar as amostras representativas de cada um desses subconjuntos de operações, selecione o link correspondente. Por exemplo, para diagnosticar exceções, você pode selecionar a contagem de uma determinada exceção a ser apresentada com a guia de detalhes da Transação de ponta a ponta.

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

Como alternativa, em vez de examinar as exceções de uma operação com falha específica, você pode iniciar da exibição Visão geral de exceções mudando para a guia Exceções na parte superior. Aqui você pode ver todas as exceções coletadas para o aplicativo monitorado.

Dados personalizados de rastreamento e log

Para obter dados de diagnóstico específicos do aplicativo, você pode inserir código para enviar seus próprios dados de telemetria. Sua telemetria personalizada ou os dados de log são exibidos na pesquisa de diagnóstico junto com a solicitação, exibição de página e outros dados coletados automaticamente.

Usando o Microsoft.VisualStudio.ApplicationInsights.TelemetryClient, você tem várias APIs disponíveis:

Para ver esses eventos, abra Pesquisar no menu à esquerda. Selecione o menu suspenso Tipos de evento e escolha Evento personalizado, Rastreamento ou Exceção.

Screenshot that shows the Search screen.

Observação

Se o seu aplicativo gerar muita telemetria, o módulo de amostragem adaptável reduzirá automaticamente o volume enviado ao portal, enviando apenas uma fração representativa de eventos. Os eventos que fazem parte da mesma operação serão selecionados ou desmarcados como um grupo, para que você possa navegar entre os eventos relacionados. Para obter mais informações, consulte Amostragem no Application Insights.

Consultar dados POST de solicitação

Os detalhes da solicitação não incluem os dados enviados ao seu aplicativo em uma chamada POST. Para que esses dados sejam relatados:

  • Instale o SDK no projeto do seu aplicativo.
  • Insira o código no seu aplicativo para chamar Microsoft.ApplicationInsights.TrackTrace(). Envie os dados de POST no parâmetro de mensagem. Há um limite para o tamanho permitido, portanto você deve tentar enviar somente os dados essenciais.
  • Quando você investiga uma solicitação com falha, localize os rastreamentos associados.

Capturar exceções e dados de diagnóstico relacionados

No início você não verá no portal todas as exceções que causam falhas em seu aplicativo. Você verá quaisquer exceções do navegador, se você estiver usando o SDK do JavaScript nas páginas da Web. Mas a maioria das exceções de servidor são capturados pelo IIS e é preciso escrever um pouco de código para vê-los.

Você pode:

  • Registrar as exceções explicitamente inserindo código em manipuladores de exceção para relatar as exceções.
  • Capturar exceções automaticamente configurando sua estrutura do ASP.NET. As inclusões necessárias são diferentes para diferentes tipos de estrutura.

Relatar exceções explicitamente

A maneira mais simples de relatar é inserir uma chamada a trackException() em um manipulador de exceção.

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

Os parâmetros de medidas e propriedades são opcionais, mas são úteis para filtrar e adicionar informações extras. Por exemplo, se você tiver um aplicativo que pode executar vários jogos, será possível localizar todos os relatórios de exceção relacionados a um jogo específico. Você pode adicionar quantos itens desejar a cada dicionário.

Exceções de navegador

A maioria das exceções de navegador são relatados.

Se sua página da web inclui arquivos de script de redes de distribuição de conteúdo ou de outros domínios, certifique-se de sua marca de script com o atributo crossorigin="anonymous" e que o servidor envia cabeçalhos CORS. Esse comportamento permitirá que você obtenha um rastreamento de pilha e detalhes de exceções sem tratamento JavaScript desses recursos.

Reutilizar o cliente de telemetria

Observação

Recomendamos que você instancie TelemetryClient uma vez e reutilize-o durante toda a vida útil de um aplicativo.

Com Injeção de dependência (DI) no .NET, o SDK do .NET apropriado e configurando corretamente o Application insights para DI, você pode exigir o TelemetryClient como um parâmetro de construtor.

public class ExampleController : ApiController
{
    private readonly TelemetryClient _telemetryClient;

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

No exemplo anterior, o TelemetryClient é injetado na classe ExampleController.

Formulários da Web

Para formulários da web, o módulo HTTP poderá coletar as exceções quando não houver nenhum redirecionamento configurado com CustomErrors. Contudo, quando você tiver redirecionamentos ativos, adicione as seguintes linhas à função Application_Error em Global.asax.cs.

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

No exemplo anterior, _telemetryClient é uma variável de escopo de classe do tipo TelemetryClient.

MVC

Começar com o SDK do Application Insights Web versão 2.6 (beta 3 e posterior), exceções de coleta sem tratamento do Application Insights lançadas automaticamente nos métodos de controladores MVC 5+. Se você já tiver adicionado um manipulador personalizado para acompanhar essas exceções, você poderá removê-lo para evitar o acompanhamento duplo de exceções.

Há vários cenários em que um filtro de exceção não pode lidar corretamente com erros quando as exceções são geradas:

  • De construtores do controlador
  • De manipuladores de mensagens
  • Durante o roteamento
  • Durante a serialização do conteúdo da resposta
  • Durante a inicialização do aplicativo
  • Em tarefas em segundo plano

Todas as exceções tratadas pelo aplicativo ainda precisam ser controladas manualmente. Exceções sem tratamento provenientes de controladores geralmente resultam em resposta de "Erro interno do servidor" 500. Se a resposta for criada manualmente como resultado de uma exceção tratada ou nenhuma exceção, ele é rastreado em telemetria de solicitação correspondente com ResultCode 500. Porém, o SDK do Application Insights não poderá controlar a exceção correspondente.

Suporte de versões anteriores

Se você usa o MVC 4 (e versões anteriores) do Application Insights Web SDK 2.5 (e versões anteriores), consulte os exemplos a seguir para rastrear exceções.

Se a configuração do CustomErrors é Off, as exceções estarão disponíveis para o módulo HTTP coletar. No entanto, se for RemoteOnly (padrão), ou On, a exceção será desmarcada e não está disponível para o Application Insights coletar automaticamente. Você pode corrigir esse comportamento substituindo a classe System.Web.Mvc.HandleErrorAttribute e aplicando a classe substituída conforme mostrado para as diferentes versões do MVC aqui (consulte fonte do 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

Substitua o atributo HandleError pelo novo atributo em seus controladores:

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

Amostra

MVC 3

Registrar AiHandleErrorAttribute como um filtro global em Global.asax.cs:

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

Amostra

MVC 4, MVC 5

Registrar AiHandleErrorAttribute como um filtro global em FilterConfig.cs:

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

Amostra

API Web

Começar com o SDK do Application Insights Web versão 2.6 (beta 3 e posterior), exceções de coleta sem tratamento do Application Insights lançadas automaticamente nos métodos de controladores para Web API 2+. Se você já adicionou um manipulador personalizado para controlar essas exceções, conforme descrito nos exemplos a seguir, você pode remover para evitar o controle duplo de exceções.

Os filtros de exceção não podem lidar com vários casos. Por exemplo:

  • Exceções geradas por construtores de controlador.
  • Exceções geradas por manipuladores de mensagens.
  • Exceções geradas durante o roteamento.
  • Exceções geradas durante a serialização de conteúdo da resposta.
  • Exceção lançada durante a inicialização do aplicativo.
  • Exceção lançada em tarefas em segundo plano.

Todas as exceções tratadas pelo aplicativo ainda precisam ser controladas manualmente. Exceções sem tratamento provenientes de controladores geralmente resultam em resposta de "Erro interno do servidor" 500. Se uma resposta for criada manualmente como resultado de uma exceção tratada ou nenhuma exceção, ele é rastreado em uma telemetria de solicitação correspondente com ResultCode 500. Porém, o SDK do Application Insights não poderá controlar a exceção correspondente.

Suporte de versões anteriores

Se você usa o Web API 1 (e versões anteriores) do Application Insights Web SDK 2.5 (e versões anteriores), consulte os exemplos a seguir para rastrear exceções.

Web API 1.x

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

Você pode adicionar esse atributo substituído para controladores específicos ou adicioná-lo à configuração de filtros globais na 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());
        }
    }
}

Amostra

Web API 2.x

Adicionar uma implementação de 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);
        }
    }
}

Adicione este snippet aos serviços em 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());
        }
    }
}

Amostra

Como alternativas, você pode:

  • Substitua a única instância ExceptionHandler por uma implementação personalizada de IExceptionHandler. O manipulador de exceção é chamado apenas quando a estrutura ainda é capaz de escolher a mensagem de resposta para enviar, não quando a conexão é anulada, por exemplo.
  • Use os filtros de exceção, como descrito na seção controladores acima da API Web 1.x, que não são chamados em todos os casos.

WCF

Adicione uma classe que estenda Attribute e implemente 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)
        {
        }
      }
    }

Adicione o atributo para as implementações de serviço:

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

Amostra

Contadores de desempenho de exceção

Se você já instalou o Agente do Application Insights do Azure Monitor no seu servidor, poderá obter um gráfico da taxa de exceções, medida pelo .NET. As exceções .NET tradas e sem tratamento estão incluídas.

Abra uma guia do gerenciador de métricas e adicione um novo gráfico. Em Contadores de Desempenho, selecione Taxa de exceção.

O .NET Framework calcula a taxa contando o número de exceções em um intervalo e dividindo pelo comprimento do intervalo.

Isso é diferente da contagem 'Exceções' calculada pelo portal do Application Insights contando relatórios TrackException. Os intervalos de amostragem são diferentes, e o SDK não envia relatórios TrackException a todas as exceções tratadas e sem tratamento.

Próximas etapas