How To Integrate Azure Application Insights Service To An Angular Application

Introduction

 
Today, we are going to see how to integrate Azure Application Insights into an Angular application. Application Insights is one of the Azure services. The Application Insights is an analytic tool that monitors web application usage, performance, and exception. Please follow the below steps one by one.
  • Setup Application Insights to your Azure subscription
  • Configure Angular application and dependencies
  • Installing the Application insight library
  • Integrate the Application Insights SDK in TypeScript
  • Error handling
  • View the Error exception in the Azure Portal

Setup Application Insights to your Azure subscription

 
If an Application Insights resource has not added already or else you want to create a new one please visit portal.azure.com login and create a resource.
 
 
 
 
 

Configure Angular application and include dependencies

 
Get the instrumentation key value from application Insights into our Angular application. If your application was already built using the Angular CLI, then you will have an environment.ts file in your application.
 
Basically, the environment.ts file configures different settings at build time so we can also add the instrumentation key in the same file here. Please refer to the below codes.
  1. export const environment = {  
  2.     appInsights: {  
  3.         instrumentationKey: 'xxxxxxxxxxxxxx'  
  4.     }  
  5. };  
Installing Application Insights Libraries
 
The first thing we need to do is install the following NPM package. 
 
npm install @microsoft/applicationinsights-web --save
 
applicationinsights-web
 
JavaScript library supplied by Microsoft  interfaces with the Application Insights SDK. 
 

Integrate the Application Insights SDK in TypeScript

 
Next, we want to create an “ApplicationInsightsService” that can handle logging exceptions, setting the logged in user, and tracking page views. The service contents looks  like the below code.
  1. import {  
  2.     Injectable  
  3. } from '@angular/core';  
  4. import {  
  5.     ApplicationInsights,  
  6.     IExceptionTelemetry,  
  7.     DistributedTracingModes  
  8. } from '@microsoft/applicationinsights-web';  
  9. import {  
  10.     Router,  
  11.     NavigationEnd  
  12. } from '@angular/router';  
  13. import {  
  14.     filter  
  15. } from 'rxjs/operators';  
  16. @Injectable({  
  17.     providedIn: 'root',  
  18. })  
  19. export class ApplicationInsightsService {  
  20.     private appInsights: ApplicationInsights;  
  21.     constructor(private router: Router) {  
  22.         this.appInsights = new ApplicationInsights({  
  23.             config: {  
  24.                 instrumentationKey: "xxxxxxxxxxxxxx"  
  25.             }  
  26.         });  
  27.         this.appInsights.loadAppInsights();  
  28.         this.loadCustomTelemetryProperties();  
  29.         this.createRouterSubscription();  
  30.     }  
  31.     setUserId(userId: string) {  
  32.         this.appInsights.setAuthenticatedUserContext(userId);  
  33.     }  
  34.     clearUserId() {  
  35.         this.appInsights.clearAuthenticatedUserContext();  
  36.     }  
  37.     logPageView(name ? : string, uri ? : string) {  
  38.         this.appInsights.trackPageView({  
  39.             name,  
  40.             uri  
  41.         });  
  42.     }  
  43.     logException(error: Error) {  
  44.         let exception: IExceptionTelemetry = {  
  45.             exception: error  
  46.         };  
  47.         this.appInsights.trackException(exception);  
  48.     }  
  49.     private loadCustomTelemetryProperties() {  
  50.         this.appInsights.addTelemetryInitializer(envelope => {  
  51.             var item = envelope.baseData;  
  52.             item.properties = item.properties || {};  
  53.             item.properties["ApplicationPlatform"] = "Web";  
  54.             item.properties["ApplicationName"] = "ApplicationName";  
  55.         });  
  56.     }  
  57.     private createRouterSubscription() {  
  58.         this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => {  
  59.             this.logPageView(null, event.urlAfterRedirects);  
  60.         });  
  61.     }  
  62. }  
After creating an instance of the class defined above ApplicationInsightsService, the application starts in the AppComponent. Declare ApplicationInsightsService like this.
  1. export class AppComponent {  
  2.     constructor(private ApplicationInsightsService: ApplicationInsightsService) {}  

Error Handling

 
The Application Insights JS packages should catch all unhandled errors. But in reality Angular actually catches any internal errors, for example a bug in your code, and has its own way of handling them.
 
We want to create an ErrorHandler implementation that does nothing but log the exception to AppInsights, and  we want to print out to the console and cross check the code .
  1. import {  
  2.     ErrorHandler,  
  3.     Injector,  
  4.     Injectable  
  5. } from '@angular/core';  
  6. import {  
  7.     ApplicationInsightsService  
  8. } from './application-insights.service';  
  9. @Injectable()  
  10. export class ApplicationInsightsErrorHandler implements ErrorHandler {  
  11.     constructor(private injector: Injector) {}  
  12.     handleError(error: any): void {  
  13.         this.injector.get < ApplicationInsightsService > (ApplicationInsightsService).logException(error);  
  14.         console.log(error);  
  15.     }  
  16. }  
In our NGModule, we then want to create a provider for our error handler,
  1. import {  
  2.     NgModule  
  3. } from '@angular/core';  
  4. import {  
  5.     BrowserModule  
  6. } from '@angular/platform-browser';  
  7. import {  
  8.     FormsModule  
  9. } from '@angular/forms';  
  10. import {  
  11.     AppComponent  
  12. } from './app.component';  
  13. @NgModule({  
  14.     imports: [BrowserModule, FormsModule],  
  15.     declarations: [AppComponent],  
  16.     providers: [{  
  17.         provide: ErrorHandler,  
  18.         useClass: ApplicatioInsightsErrorHandler  
  19.     }, ],  
  20.     bootstrap: [AppComponent]  
  21. })  
  22. export class AppModule {}  

Using Distributed Tracing With CORS

 
If you are attempting to setup distributed tracing with CORS, while integrateApplicationInsightsc Service is pointing to an Azure domain and the front  also points to another domain  then we face the CORS issue. So we can resolve the issue in our ApplicationInsightsService file and add enableCorsCorrelationflag.
 
The first thing is that CORS is not turned on within the App Insights Angular library by default. To do so, in our ApplicationInsightsService we want to pass an extra flag when creating our ApplicationInsights object,
  1. this.appInsights = new ApplicationInsights({  
  2.     config: {  
  3.         instrumentationKey: "xxxxxxxxxxxxxxxx",  
  4.         enableCorsCorrelation: true  
  5.     }  
  6. });  

View the Error exception in the Azure Portal

 
The included App Insights JS library will automatically send metrics to Application Insights. To view the exceptions, navigate to the Failure menu and choose the Exceptions tab. Make sure to toggle to Browser in the top right-hand corner.
 
Go to Azure Portal -> open AngularDemoApp Application Insights -> left side panel has performance and failure menu available. Click the failure menu and open the Exception menu and see the logs.
 
 
Finally, we have received an exception log from the portal. I hope this article is most helpful for you. Thanks