Search code examples
c#asp.netasp.net-mvcazure-application-insights

How to track dependencies, exceptions and requests for Live Metrics in ASP.NET MVC app?


I've configured Live Metrics for my ASP.NET MVC app with target framework 4.7.2 using the tutorial given in Microsoft Docs:

https://learn.microsoft.com/en-us/azure/azure-monitor/app/live-stream#enable-livemetrics-using-code-for-any-net-application

In this tutorial, they've given a sample client.TrackDependency() and client.TrackRequest() call in the end. They've also mentioned in comments that those are samples and we must replace it with actual application logic to work. I'm new to all these and I don't know what to replace. Since my application is huge and has a lot of methods, it is impractical to call the tracking methods in each method or controller. Since it is not ASP.NET Core, there are no middlewares and I have to enable Live Metrics by code too. I've added the code in the Application_Start() of Global.asax.cs of my application, so that it runs during startup.

This is what I've done so far,

// Create a TelemetryConfiguration instance.
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration telemetryConfig = Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CreateDefault();
telemetryConfig.InstrumentationKey = System.Web.Configuration.WebConfigurationManager.AppSettings["AppInsightsInstrumentationKey"];
QuickPulseTelemetryProcessor quickPulseProcessor = null;
telemetryConfig.DefaultTelemetrySink.TelemetryProcessorChainBuilder
    .Use((next) =>
    {
        quickPulseProcessor = new QuickPulseTelemetryProcessor(next);
        return quickPulseProcessor;
    })
    .Build();

var quickPulseModule = new QuickPulseTelemetryModule();

// Secure the control channel.
// This is optional, but recommended.
//quickPulseModule.AuthenticationApiKey = "YOUR-API-KEY-HERE";
quickPulseModule.Initialize(telemetryConfig);
quickPulseModule.RegisterTelemetryProcessor(quickPulseProcessor);

// Create a TelemetryClient instance. It is important
// to use the same TelemetryConfiguration here as the one
// used to setup Live Metrics.
TelemetryClient client = new TelemetryClient(telemetryConfig);

// I need some method by which I can track all the requests, exceptions,
// dependencies etc. here. 

I searched and searched a lot for a solution but couldn't get a concrete solution. As a last resort I'm requesting you guys to help me. What can I do to track all requests, dependencies, exceptions, etc. globally...?


Solution

  • I found a solution myself. I found out that I can use the Application_BeginRequest() event handler to catch all requests inside Global.asax itself. All I had to do is to store the TelemetryConfiguration into a global variable and access it from the Application_BeginRequest() handler. This is what I did:

    
    using Microsoft.ApplicationInsights;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
     
    protected void Application_Start()
    {
      RegisterLiveMetrics();
      // Omitted the other code for brevity
    }
    
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
      var telemetryConfig = Application["TelemetryConfig"] as TelemetryConfiguration;
      TelemetryClient client = new TelemetryClient(telemetryConfig);
    
      var httpContextCurrent = HttpContext.Current;
      client.TrackRequest(httpContextCurrent.Request.RawUrl, DateTimeOffset.Now, 
      TimeSpan.FromMilliseconds(230), httpContextCurrent.Response.StatusCode.ToString(), 
      true);
    }
    
    private void RegisterLiveMetrics()
    {
      // Create a TelemetryConfiguration instance.
    Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration telemetryConfig = Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CreateDefault();
    telemetryConfig.InstrumentationKey = System.Web.Configuration.WebConfigurationManager.AppSettings["AppInsightsInstrumentationKey"];
    QuickPulseTelemetryProcessor quickPulseProcessor = null;
    telemetryConfig.DefaultTelemetrySink.TelemetryProcessorChainBuilder
        .Use((next) =>
        {
            quickPulseProcessor = new QuickPulseTelemetryProcessor(next);
            return quickPulseProcessor;
        })
        .Build();
    
    var quickPulseModule = new QuickPulseTelemetryModule();
    
    quickPulseModule.Initialize(telemetryConfig);
    quickPulseModule.RegisterTelemetryProcessor(quickPulseProcessor);
    
    Application["TelemetryConfig"] = telemetryConfig;
    }
    

    Luckily this seems to work fine. Currently I'm only tracking requests.

    Note: I'm not sure about the namespaces mentioned above.