Using Azure Application Insights with Angular (5/7)
Tags: spring, angular, azure, java
Published: 2019-05-28 14:07:15

---
title:  Using Azure Application Insights with Angular (5/7)
published: true
description: In this series of blog posts, we are going to deploy a full-stack application to Azure, and learn how to set up many components efficiently, and in a cost-conscious way.
tags: spring, angular, azure, java
series: "Spring and Angular applications on Azure"
---
This blog post is part of a series on "deploying a Spring Boot and Angular application on Azure", here is the full list of posts:

- [Creating a Spring Boot and Angular application for Azure (1/7)](https://dev.to/jdubois/creating-a-spring-boot-and-angular-application-for-azure-1-7-2mb8)
- [Creating and configuring Azure Web App and MySQL to host a Spring Boot application (2/7)](https://dev.to/jdubois/creating-and-configuring-azure-web-app-and-mysql-to-host-a-spring-boot-application-2-7-1n13)
- [Using Azure Pipelines to build, test and deploy a Spring Boot and Angular application (3/7)](https://dev.to/azure/using-azure-pipelines-to-build-test-and-deploy-a-spring-boot-and-angular-application-3-7-593j)
- [Using Azure Application Insights with Spring Boot (4/7)](https://dev.to/azure/using-azure-application-insights-with-spring-boot-4-7-263i)
- Using Azure Application Insights with Angular (5/7)
- [Configuring Azure CDN to boost Angular performance (6/7)](https://dev.to/azure/configuring-azure-cdn-to-boost-angular-performance-6-7-5ebe)
- [Configuring Azure Redis Cache to boost Spring Boot performance (7/7)](https://dev.to/azure/configuring-azure-redis-cache-to-boost-spring-boot-performance-7-7-52dl)

## Azure Application Insights and Angular

In [the previous blog post]((https://dev.to/azure/using-azure-application-insights-with-spring-boot-4-7-263i)), we configured Azure Application Insights with Spring Boot, so we could monitor our server-side application. But what about our client-side application? And how about doing joint dashboards, showing both server-side and client-side data, in order to better understand why our user feel that our application is slow?

We're going to do all this in this blog post, by configuring our existing Application Insights instance to also monitor client-side data.

## Installing Application Insights for Angular

First of all, be careful! There is a very popular and official [applicationinsights-js](https://www.npmjs.com/package/applicationinsights-js) library, and in you should not use it! This version is packaged as an AMD module, which will cause issues with our unit tests. There's a new version, packaged as an UMD module, that will work everywhere, and which has a new (and better!) name: [@microsoft/applicationinsights-web](https://www.npmjs.com/package/@microsoft/applicationinsights-web). At the time of this writing, nearly nobody uses this new and improved release, so we hope to change this thanks to this blog post!

First of all, install this library by doing `npm i --save @microsoft/applicationinsights-web@2.0.0`.

Now we need to configure it, and please note that your Azure Application Insights instrumentation key will be public (but that shouldn't cause any trouble):

```javascript
private appInsights = new ApplicationInsights({
  config: {
    instrumentationKey: 'a8aca698-844c-4515-9875-fb6b480e4fec'
  }
});

// ...

this.appInsights.loadAppInsights();

```

Then, in order to record what users do on the application, we have hooked this mechanism on the Angular Router: each time a route changes, an event will be sent to Azure Application Insights, so we can record what people are doing.

Here is the Angular service we created:

```javascript
import { Injectable, OnInit } from '@angular/core';
import { ApplicationInsights } from '@microsoft/applicationinsights-web';
import { ActivatedRouteSnapshot, ResolveEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';
import { Subscription } from 'rxjs';

@Injectable()
export class ApplicationInsightsService {
  private routerSubscription: Subscription;

  private appInsights = new ApplicationInsights({
    config: {
      instrumentationKey: 'a8aca698-844c-4515-9875-fb6b480e4fec'
    }
  });

  constructor(private router: Router) {
    this.appInsights.loadAppInsights();
    this.routerSubscription = this.router.events.pipe(filter(event => event instanceof ResolveEnd)).subscribe((event: ResolveEnd) => {
      const activatedComponent = this.getActivatedComponent(event.state.root);
      if (activatedComponent) {
        this.logPageView(`${activatedComponent.name} ${this.getRouteTemplate(event.state.root)}`, event.urlAfterRedirects);
      }
    });
  }

  setUserId(userId: string) {
    this.appInsights.setAuthenticatedUserContext(userId);
  }

  clearUserId() {
    this.appInsights.clearAuthenticatedUserContext();
  }

  logPageView(name?: string, uri?: string) {
    this.appInsights.trackPageView({ name, uri });
  }

  private getActivatedComponent(snapshot: ActivatedRouteSnapshot): any {
    if (snapshot.firstChild) {
      return this.getActivatedComponent(snapshot.firstChild);
    }

    return snapshot.component;
  }

  private getRouteTemplate(snapshot: ActivatedRouteSnapshot): string {
    let path = '';
    if (snapshot.routeConfig) {
      path += snapshot.routeConfig.path;
    }

    if (snapshot.firstChild) {
      return path + this.getRouteTemplate(snapshot.firstChild);
    }

    return path;
  }
}
```

(You can see [the whole file here](https://github.com/jdubois/spring-on-azure/blob/2de5baed87e8f0c269864810def347774574b80d/src/main/webapp/app/core/insights/application-insights.service.ts))

Please note that we have created `setUserId()` and `clearUserId()` methods: we will use them when a user authenticates or logs out of the application, so we can better track what individuals are doing. We hooked those methods in the `account.service.ts` file generated by JHipster, so we could directly use the account login.

Also, user data is sent when the browser window is closed, which is very good in production, but might be annoying in development. One interesting method to use is `appInsights.flush();`, which will force the data to be sent. This could be used in development in our new Angular service, in order to test it more easily.

As this part required quite a lot code, check [this commit](https://github.com/jdubois/spring-on-azure/commit/2de5baed87e8f0c269864810def347774574b80d) to see all the details that we have changed to make this part work. Please note that we needed to mock the Azure Application Insights service in our tests, and this is why we needed to use the UMD module.

## Using Application Insights to track users

As we are tracking user sessions as well as logins, we can have very detailed informations on our users' behavior, and also better understand the performance issues of our application.

The first thing you will probably do is just to check users and sessions on your website:

![](https://thepracticaldev.s3.amazonaws.com/i/t9dxbkglzlzv1459r7sa.png)

But you'll be able to do much more, for example you can check the flow of users in your application:

![](https://thepracticaldev.s3.amazonaws.com/i/34ztw56e7h55r6xycsr4.png)

You will then be able to combine dashboards with data from the Spring Boot application, in order to better understand what your users do, and which issues they encounter.

This will lead us to our next two blog posts, on improving both client-side and server-side performance. Thanks to Azure Application Insights we will be able to make the right choices, and better understand if our performance tunings have the right impact.