Mendiagnosis pengecualian di aplikasi web dengan Application Insights

Pengecualian dalam aplikasi web dapat dilaporkan dengan Application Insights. Anda dapat menghubungkan permintaan yang gagal dengan pengecualian dan peristiwa lain pada klien dan server, sehingga Anda dapat dengan cepat mendiagnosis penyebabnya. Dalam artikel ini, Anda akan mempelajari cara menyiapkan pelaporan pengecualian, melaporkan pengecualian secara eksplisit, mendiagnosis kegagalan, dan lainnya.

Menyiapkan pelaporan pengecualian

Anda dapat mengatur Application Insights untuk melaporkan pengecualian yang terjadi di server, atau klien. Bergantung pada platform yang digunakan aplikasi, Anda akan memerlukan ekstensi atau SDK yang sesuai.

Sisi server

Untuk memiliki pengecualian yang dilaporkan dari aplikasi sisi server Anda, pertimbangkan skenario berikut:

Sisi klien

JavaScript SDK menyediakan kemampuan untuk pelaporan sisi klien pengecualian yang terjadi di browser web. Untuk menyiapkan pelaporan pengecualian pada klien, lihat Application Insights untuk halaman web.

Kerangka kerja aplikasi

Dengan adanya beberapa kerangka kerja aplikasi, sedikit lebih banyak konfigurasi yang diperlukan. Pertimbangkan teknologi berikut:

Penting

Artikel ini secara khusus berfokus pada aplikasi .NET Framework dari perspektif contoh kode. Beberapa metode yang bekerja untuk .NET Framework sudah usang dalam .NET Core SDK. Untuk informasi selengkapnya, lihat dokumentasi .NET Core SDK saat membuat aplikasi dengan .NET Core.

Mendiagnosis pengecualian menggunakan Visual Studio

Buka solusi di Visual Studio. Jalankan aplikasi, baik di server Anda atau di mesin pengembangan Anda dengan menggunakan F5. Buat ulang pengecualian.

Buka jendela telemetri Pencarian Application Insights di Visual Studio. Saat melakukan penelusuran kesalahan, pilih dropdown Application Insights.

Klik kanan proyek, lalu pilih dan buka Application Insights.

Pilih laporan pengecualian untuk menampilkan jejak tumpukannya. Untuk membuka file kode yang relevan, pilih referensi baris di pelacakan tumpukan.

Jika CodeLens diaktifkan, Anda akan melihat data tentang pengecualian:

Pemberitahuan pengecualian CodeLens.

Mendiagnosis kegagalan menggunakan portal Azure

Application Insights dilengkapi dengan pengalaman Manajemen Performa Aplikasi (APM) yang dikumpulkan untuk membantu Anda mendiagnosis kegagalan dalam aplikasi yang dipantau. Untuk memulai, pilih opsi Kegagalan di menu sumber daya Application Insights yang terletak di bagian Selidiki. Anda akan melihat tren tingkat kegagalan untuk permintaan Anda, jumlah kegagalan, dan jumlah pengguna yang terkena dampak. Sebagai tampilan Keseluruhan, Anda akan melihat beberapa distribusi paling berguna khusus untuk operasi gagal yang dipilih, termasuk tiga kode respons teratas, tiga jenis pengecualian teratas, dan tiga jenis kegagalan dependensi teratas.

Tampilan triase kegagalan (tab operasi)

Untuk meninjau sampel perwakilan setiap subkumpulan operasi ini, pilih tautan yang sesuai. Sebagai contoh, untuk mendiagnosis pengecualian, Anda dapat memilih hitungan pengecualian tertentu untuk disajikan dengan tab detail Transaksi menyeluruh:

Tab detail transaksi menyeluruh

Atau, sebagai ganti melihat pengecualian untuk operasi tertentu yang gagal, Anda dapat memulai dari tampilan Keseluruhan pada pengecualian, dengan beralih ke tab Pengecualian di bagian atas. Di sini, Anda dapat melihat semua pengecualian yang dikumpulkan untuk aplikasi yang dipantau.

Pelacakan kustom dan data log

Untuk mendapatkan data diagnostik khusus untuk aplikasi, Anda dapat menyisipkan kode untuk mengirim data telemetri Anda sendiri. Telemetri kustom atau data log Anda ditampilkan dalam pencarian diagnostik beserta permintaan, tampilan halaman, dan data lain yang dikumpulkan secara otomatis.

Dengan menggunakan Microsoft.VisualStudio.ApplicationInsights.TelemetryClient, Anda memiliki beberapa API yang tersedia:

Untuk melihat peristiwa ini, buka Pencarian dari menu kiri, pilih menu drop-down Jenis peristiwa, lalu pilih Peristiwa Kustom, Pelacakan, atau Pengecualian.

Telusuri paling detail

Catatan

Jika aplikasi Anda menghasilkan banyak telemetri, modul pengambilan sampel adaptif akan secara otomatis mengurangi volume yang dikirim ke portal dengan hanya mengirim sebagian kecil dari peristiwa yang representatif. Peristiwa yang merupakan bagian dari operasi yang sama akan dipilih atau tidak dipilih sebagai grup, sehingga Anda dapat menavigasi di antara peristiwa terkait. Untuk informasi selengkapnya, lihat Mengambil sampel di Application Insights.

Cara melihat data POST permintaan

Detail permintaan tidak menyertakan data yang dikirim ke aplikasi Anda dalam panggilan POST. Agar data ini dilaporkan:

  • Instal SDK di proyek aplikasi Anda.
  • Masukkan kode dalam aplikasi Anda untuk memanggil Microsoft.ApplicationInsights.TrackTrace(). Kirim data POST dalam parameter pesan. Ada batas ukuran yang diizinkan, jadi Anda harus mencoba mengirim data penting saja.
  • Saat Anda menyelidiki permintaan yang gagal, temukan jejak terkait.

Pada awalnya, Anda tidak akan melihat di portal semua pengecualian yang menyebabkan kegagalan di aplikasi Anda. Anda akan melihat pengecualian browser apa pun (jika Anda menggunakan SDK JavaScript di halaman web Anda). Tetapi sebagian besar pengecualian server ditangkap oleh IIS dan Anda harus menulis sedikit kode untuk melihatnya.

Anda dapat:

  • Mencatat pengecualian secara eksplisit dengan memasukkan kode dalam penangan pengecualian untuk melaporkan pengecualian.
  • Menangkap pengecualian secara otomatis dengan mengonfigurasi kerangka kerja ASP.NET Anda. Penambahan yang diperlukan berbeda untuk berbagai jenis kerangka kerja.

Melaporkan pengecualian secara eksplisit

Cara paling mudah adalah menyisipkan panggilan ke trackException() dalam penangan pengecualian.

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

Parameter properti dan pengukuran bersifat opsional, tetapi berguna untuk memfilter dan menambahkan informasi tambahan. Misalnya, jika Anda memiliki aplikasi yang dapat menjalankan beberapa game, Anda dapat menemukan semua laporan pengecualian yang terkait dengan game tertentu. Anda dapat menambahkan item sebanyak yang Anda suka ke setiap kamus.

Pengecualian browser

Sebagian besar pengecualian browser dilaporkan.

Jika halaman web Anda menyertakan file skrip dari jaringan pengiriman konten atau domain lain, pastikan tag skrip Anda memiliki atribut crossorigin="anonymous", dan bahwa server mengirim header CORS. Hal ini akan memungkinkan Anda mendapatkan pelacakan tumpukan dan detail untuk pengecualian JavaScript yang tidak tertangani dari sumber daya ini.

Menggunakan kembali klien telemetri Anda

Catatan

TelemetryClient direkomendasikan untuk dibuat satu kali, dan digunakan kembali sepanjang masa aktif aplikasi.

Dengan Injeksi Dependensi (DI) di .NET, SDK .NET yang sesuai, dan mengonfigurasi Application Insights untuk DI dengan benar, Anda dapat memerlukan TelemetryClient sebagai parameter konstruktor.

public class ExampleController : ApiController
{
    private readonly TelemetryClient _telemetryClient;

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

Dalam contoh sebelumnya, TelemetryClient dimasukkan ke dalam kelas ExampleController.

Formulir web

Untuk formulir web, Modul HTTP dapat mengumpulkan pengecualian ketika tidak ada pengalihan yang dikonfigurasi dengan CustomErrors. Namun, ketika Anda memiliki pengalihan aktif, tambahkan baris berikut ke fungsi Application_Error di Global.asax.cs.

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

Dalam contoh sebelumnya, _telemetryClient adalah variabel yang dicakup kelas dari jenis TelemetryClient.

MVC

Mulai dengan Application Insights Web SDK versi 2.6 (beta3 dan yang lebih baru), Application Insights mengumpulkan pengecualian yang tidak tertangani di metode pengontrol MVC 5+ secara otomatis. Jika Anda menambahkan penangan kustom untuk melacak pengecualian tersebut, Anda dapat menghapusnya untuk mencegah pelacakan ganda pada pengecualian.

Ada sejumlah skenario ketika filter pengecualian tidak dapat menangani kesalahan dengan benar, ketika pengecualian ditampilkan:

  • Dari konstruktor pengontrol.
  • Dari penangan pesan.
  • Selama perutean.
  • Selama serialisasi konten respons.
  • Selama start-up aplikasi.
  • Dalam proses di latar belakang.

Semua pengecualian yang ditangani oleh aplikasi masih perlu dilacak secara manual. Pengecualian yang tidak tertangani yang berasal dari pengontrol biasanya menghasilkan 500 respons "Kesalahan Server Internal". Jika respons tersebut dibuat secara manual sebagai akibat dari pengecualian yang ditangani (atau tidak terkecuali sama sekali) respons dilacak dalam telemetri permintaan yang sesuai dengan ResultCode 500, namun Application Insights SDK tidak dapat melacak pengecualian yang sesuai.

Dukungan versi sebelumnya

Jika Anda menggunakan MVC 4 (dan sebelumnya) dari Application Insights Web SDK 2.5 (dan sebelumnya), lihat contoh berikut untuk melacak pengecualian.

Jika konfigurasi CustomErrors adalah Off, pengecualian akan tersedia untuk Modul HTTP yang akan dikumpulkan. Namun, jika konfigurasinya RemoteOnly (default), atau On, pengecualian akan dihapus dan tidak tersedia untuk Application Insights yang akan dikumpulkan secara otomatis. Anda dapat memperbaikinya dengan menimpa kelas System.Web.Mvc.HandleErrorAttribute, dan menerapkan kelas yang ditimpa seperti yang ditunjukkan untuk versi MVC yang berbeda di bawah ini (sumber 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)
            {
                //If customError is Off, then AI HTTPModule will report the exception
                if (filterContext.HttpContext.IsCustomErrorEnabled)
                {   //or reuse instance (recommended!). see note above
                    var ai = new TelemetryClient();
                    ai.TrackException(filterContext.Exception);
                }
            }
            base.OnException(filterContext);
        }
    }
}

MVC 2

Ganti atribut HandleError dengan atribut baru di pengontrol Anda.

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

Sampel

MVC 3

Mendaftar AiHandleErrorAttribute sebagai filter global di Global.asax.cs:

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

Sampel

MVC 4, MVC5

Mendaftar AiHandleErrorAttribute sebagai filter global di FilterConfig.cs:

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

Sampel

API Web

Mulai dengan Application Insights Web SDK versi 2.6 (beta3 dan yang lebih baru), Application Insights mengumpulkan pengecualian yang tidak tertangani ditampilkan di metode pengontrol untuk WebAPI 2+ secara otomatis. Jika sebelumnya Anda telah menambahkan penangan kustom untuk melacak pengecualian tersebut (seperti yang dijelaskan dalam contoh berikut), Anda dapat menghapusnya untuk mencegah pelacakan pengecualian ganda.

Ada sejumlah kasus yang tidak dapat ditangani oleh filter pengecualian. Contohnya:

  • Pengecualian dari konstruktor pengontrol.
  • Pengecualian dari pengelola pesan.
  • Pengecualian saat perutean.
  • Pengecualian selama serialisasi konten respons.
  • Pengecualian selama aplikasi dimulai.
  • Pengecualian tugas latar belakang.

Semua pengecualian yang ditangani oleh aplikasi masih perlu dilacak secara manual. Pengecualian yang tidak tertangani yang berasal dari pengontrol biasanya menghasilkan 500 respons "Kesalahan Server Internal". Jika respons tersebut dibuat secara manual sebagai akibat dari pengecualian yang ditangani (atau tidak terkecuali sama sekali) respons dilacak dalam telemetri permintaan yang sesuai dengan ResultCode 500, namun Application Insights SDK tidak dapat melacak pengecualian yang sesuai.

Dukungan versi sebelumnya

Jika Anda menggunakan WebAPI 1 (dan versi sebelumnya) dari Application Insights Web SDK 2.5 (dan versi sebelumnya), lihat contoh berikut untuk melacak pengecualian.

API Web 1.x

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

Anda dapat menambahkan atribut yang diambil alih ini ke pengontrol tertentu, atau menambahkannya ke konfigurasi filter global di kelas 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());
        }
    }
}

Sampel

API Web 2.x

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

Tambahkan ini ke layanan di 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());
        }
    }
}

Sampel

Sebagai alternatif, Anda dapat:

  1. Mengganti satu-satunya ExceptionHandler dengan implementasi kustom IExceptionHandler. Ini hanya dipanggil ketika kerangka kerja masih dapat memilih pesan respons mana yang akan dikirim (bukan ketika koneksi untuk instans)
  2. Filter Pengecualian (seperti yang dijelaskan di bagian pada pengontrol Web API 1.x di atas) - tidak dipanggil dalam semua kasus.

WCF

Tambahkan kelas yang memperluas Atribut dan mengimplementasikan IErrorHandler dan 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)
        {
        }
      }
    }

Tambahkan atribut ke implementasi layanan:

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

Sampel

Penghitung kinerja pengecualian

Jika Anda telah menginstal Agen Application Insights Azure Monitor di server Anda, Anda bisa mendapatkan bagan tingkat pengecualian, yang diukur dengan .NET. Hal ini termasuk pengecualian .NET yang ditangani dan tidak tertangani.

Buka tab Penjelajah Metrik, tambahkan bagan baru, dan pilih Tingkat pengecualian, yang tercantum di bawah Penghitung Kinerja.

Kerangka kerja .NET menghitung laju dengan menghitung jumlah pengecualian dalam interval dan membagi dengan panjang interval.

Hal ini berbeda dengan jumlah 'Pengecualian' yang dihitung oleh portal Application Insights yang menghitung laporan TrackException. Interval pengambilan sampel berbeda, dan SDK tidak mengirim laporan TrackException untuk semua pengecualian yang ditangani dan tidak tertangani.

Langkah berikutnya