使用 Application Insights 診斷 Web 應用程式中的例外狀況

注意

下列文件依賴Application Insights傳統 API。 Application Insights 的長期計劃是使用 OpenTelemetry 收集數據。 如需詳細資訊,請參閱 為 .NET、Node.js、Python 和 Java 應用程式啟用 Azure 監視器 OpenTelemetry。

Web 應用程式中的例外狀況可以使用 Application Insights 報告。 失敗的要求可以與用戶端和伺服器端的例外狀況和其他事件相互關聯,加速診斷原因。 在本文中,您將了解如何設定例外狀況報告、明確報告例外狀況、診斷失敗等。

設定例外狀況報告

您可以設定 Application Insights 報告伺服器或用戶端中發生的例外狀況。 根據應用程式所在的平台,您需要適當的延伸模組或 SDK。

伺服器端

若要從伺服器端應用程式回報例外狀況,請考慮下列情節:

用戶端

JavaScript SDK 的功能提供用戶端報告網頁瀏覽器中發生的例外狀況。 若要在用戶端上設定例外狀況報告,請參閱適用於網頁的 Application Insights

應用程式架構

使用某些應用程式架構時,需要更多設定。 請考慮下列技術:

重要

本文特別著重程式碼範例觀點的 .NET Framework 應用程式。 部分適用於 .NET Framework 的方法在 .NET Core SDK 中已淘汰。 如需詳細資訊,請參閱使用 .NET Core 組建應用程式時的 .NET Core SDK 文件

使用 Visual Studio 診斷例外狀況

在 Visual Studio 中開啟應用程式方案。 使用 F5 執行伺服器或開發機器上的應用程式。 重新建立例外狀況。

在 Visual Studio 中開啟 [Application Insights 搜尋] 遙測視窗。 偵錯時,請選取 [Application Insights] 下拉式清單。

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

選取例外狀況報告,並顯示其堆疊追蹤。 若要開啟相關程式碼檔案,請選取堆疊追蹤中的行參考。

如果已啟用 CodeLens,您會看到例外狀況的資料:

Screenshot that shows CodeLens notification of exceptions.

使用 Azure 入口網站診斷失敗

Application Insights 隨附精心設計的 Application Performance Management 體驗,協助您診斷受監視應用程式中的失敗。 若要開始,請在左側的 Application Insights 資源功能表中,選取 [調查] 底下的 [失敗] 選項。

您會看到要求的失敗率趨勢,即有多少失敗的要求,以及受影響的使用者人數。 [整體] 檢視會顯示所選失敗作業特定的一些最實用散發。 您會看到前三個回應碼、前三個例外狀況類型,以及前三個失敗的相依性類型。

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

若要檢閱這些作業子集的代表範例,請選取對應的連結。 例如,若要診斷例外狀況,您可以選取要顯示在 [端對端交易詳細 資料] 索引標籤的特定例外狀況計數。

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

或者也可以不查看特定失敗作業的例外狀況,而切換到頂端的 [例外狀況] 索引標籤,從例外狀況的 [整體] 檢視開始。 您可以在此處查看為您的受監視應用程式收集的所有例外狀況。

自訂追蹤和記錄資料

若要取得您的 app 的特定診斷資料,您可以插入程式碼以傳送您自己的遙測資料。 您自訂的遙測或記錄資料會顯示在診斷搜尋,除此之外,還會顯示要求、頁面檢視和其他自動收集的資料。

使用 Microsoft.VisualStudio.ApplicationInsights.TelemetryClient 時,您可以使用下列幾個 API:

若要查看這些事件,請在左側功能表上開啟 [搜尋]。 選取下拉式功能表 [事件種類],然後選擇 [自訂事件]、[追蹤] 或 [例外狀況]

Screenshot that shows the Search screen.

注意

如果您的應用程式會產生大量遙測資料,調適型取樣模組會自動僅傳送事件代表性片段,減少傳送到入口網站的量。 會以群組形式選取或取消選取屬於相同作業的事件,讓您可以在相關事件之間瀏覽。 如需詳細資訊,請參閱在 Application Insights 中取樣

查看要求 POST 資料

要求詳細資料不包括在 POST 呼叫中傳送至您的應用程式的資料。 若要報告此資料:

  • 在您的應用程式專案中安裝 SDK
  • 在您的應用程式中插入程式碼來呼叫 Microsoft.ApplicationInsights.TrackTrace()。 在訊息參數中傳送 POST 資料。 允許的大小有所限制,所以應嘗試只傳送基本的資料。
  • 當您調查失敗的要求時,會發現相關聯的追蹤。

擷取例外狀況和相關的診斷資料

一開始,您不會在入口網站看到應用程式中造成失敗的所有例外狀況。 您會看到任何瀏覽器例外狀況 (如果您在網頁中使用 JavaScript SDK)。 但是 IIS 會攔截大部分的伺服器例外狀況,而且您必須撰寫一段程式碼才能查看它們。

您可以:

  • 明確記錄例外狀況 ,方法是將程式碼插入例外狀況處理常式中,以報告例外狀況。
  • 自動擷取例外狀況 ,方法是設定您的 ASP.NET 架構。 架構類型不同,則必要的新增項目也不同。

明確報告例外狀況

最簡單的方法是在例外處理常式中插入 trackException() 的呼叫。

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

屬性和度量參數為選用,但對於篩選和新增額外資訊來說,相當有用。 比方說,如果您有一個應用程式可以執行數個遊戲,則您可以找到與特定遊戲相關的所有例外狀況報告。 您可以將許多項目加入至每個字典,且項目數量不限。

瀏覽器例外狀況

大部分的瀏覽器例外狀況都會報告。

如果您的網頁包含來自內容傳遞網路或其他網域的指令碼檔案,請確定指令碼標籤具有屬性 crossorigin="anonymous",而且伺服器會傳送 CORS 標頭。 此行為可讓您從這些資源取得未處理 JavaScript 例外狀況的堆疊追蹤和詳細資料。

重複使用遙測用戶端

注意

建議您具現化 TelemetryClient 一次,並在應用程式生命週期中重複使用。

使用 .NET 中的相依性插入 (DI)、適當的 .NET SDK,及正確設定的 DI Application Insights,您可以要求 TelemetryClient,作為建構函式參數。

public class ExampleController : ApiController
{
    private readonly TelemetryClient _telemetryClient;

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

在上述範例中,TelemetryClient 會插入 ExampleController 類別。

Web Form

如果是 Web Forms,未使用 CustomErrors 設定重新導向時,HTTP 模組可以收集例外狀況。 但使用重新導向時,請新增下列程式碼至 Global.asax.csApplication_Error 函式。

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

在上述範例中,_telemetryClient 類型 TelemetryClient 的類別範圍變數。

MVC

從 Application Insights Web SDK 2.6 版 (beta3 和更新版本) 開始,Application Insights 會自動收集在 MVC 5+ 控制器方法中擲回的未處理例外狀況。 如果您之前已新增追蹤這類例外狀況的自訂處理常式,為避免重複追蹤例外狀況,請移除該處理常式。

例外狀況篩選無法正確處理錯誤,或擲回例外狀況時,有數種情節:

  • 從控制器建構函式
  • 從訊息處理常式
  • 路由傳送期間
  • 回應內容序列化期間
  • 應用程式啟動期間
  • 在背景工作中

由應用程式處理的所有例外狀況仍然需要手動追蹤。 源自控制器的未處理例外狀況通常會導致 500「內部伺服器錯誤」回應。 如果此類回應是因為已處理的例外狀況 (或根本沒有例外狀況) 而手動建構的,則對應的要求遙測會加以追蹤並產生 ResultCode 500。 不過,Application Insights SDK 無法追蹤對應的例外狀況。

舊版支援

如果您使用 Application Insights Web SDK 2.5 (和較早版本) 的 MVC 4 (和較早版本),請參閱以下範例以追蹤例外狀況。

如果 CustomErrors 組態是 Off,則例外狀況將可供 HTTP 模組收集。 不過如果是 RemoteOnly (預設值) 或 On,則會清除例外狀況,且不適用於讓 Application Insights 自動收集。 您可以藉由覆寫 System.Web.Mvc.HandleErrorAttribute 類別,並且針對以下不同的 MVC 版本套用已覆寫的類別來修正該行為 (請參閱 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

使用您控制器中的新屬性取代 HandleError 屬性:

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

範例

MVC 3

登錄 AiHandleErrorAttribute 作為 Global.asax.cs 中的全域篩選:

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

範例

MVC 4、MVC 5

登錄 AiHandleErrorAttribute 作為 FilterConfig.cs 中的全域篩選:

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

範例

Web API

從 Application Insights Web SDK 2.6 版 (beta3 和更新版本) 開始,Application Insights 會自動針對 Web API 2+ 收集在控制器方法中擲回的未處理例外狀況。 如果您先前已新增自訂處理常式來追蹤此類例外狀況 (如下列範例中所述),您可以將其移除,以避免重複追蹤例外狀況。

有一些例外狀況篩選條件無法處理的案例。 例如:

  • 從控制器建構函式擲回的例外狀況。
  • 從訊息處理常式擲回的例外狀況。
  • 在路由期間擲回的例外狀況。
  • 在回應內容序列化期間擲回的例外狀況。
  • 在應用程式啟動期間擲回的例外狀況。
  • 背景工作中擲回的例外狀況。

由應用程式處理的所有例外狀況仍然需要手動追蹤。 源自控制器的未處理例外狀況通常會導致 500「內部伺服器錯誤」回應。 如果此類回應是因為已處理的例外狀況 (或根本沒有例外狀況) 而手動建構的,則對應的要求遙測會加以追蹤並產生 ResultCode 500。 不過,Application Insights SDK 無法追蹤對應的例外狀況。

舊版支援

如果您使用 Application Insights Web SDK 2.5 (和較早版本) 的 Web API 1 (和較早版本),請參閱以下範例以追蹤例外狀況。

Web API 1.x

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

您可以新增此覆寫的屬性至特定的控制器,或新增至 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());
        }
    }
}

範例

Web API 2.x

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

將此程式碼片段新增至 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());
        }
    }
}

範例

做為替代方案,您可以:

  • 使用 IExceptionHandler 自訂實作取代唯一的 ExceptionHandler 執行個體。 此例外處理常式只會在架構仍然可以選擇要針對執行個體傳送的回應訊息時呼叫 (不會在中止連接時呼叫)。
  • 使用在所有案例中均不會呼叫的例外狀況篩選條件 (如先前 Web API 1.x 控制器章節所述)。

WCF

新增擴充 Attribute 及實作 IErrorHandlerIServiceBehavior 的類別。

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

將屬性新增至服務實作:

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

範例

例外狀況效能計數器

如果伺服器已安裝 Azure 監視器 Application Insights 代理程式,即可取得 .NET 測量的例外狀況比率圖。 這包括已處理和未處理的 .NET 例外狀況。

開啟 [計量總管] 索引標籤,新增圖表。 在 [效能計數器] 底下,選取 [例外狀況比率]

.NET Framework 會計算間隔中的例外狀況次數並除以間隔長度,以計算得出例外狀況比率。

此計數與 Application Insights 入口網站執行 TrackException 報告計數算得的「例外狀況」計數不同。 取樣間隔不同,且 SDK 不會針對所有已處理與未處理的例外狀況傳送 TrackException 報告。

下一步