Measure Reliability

First, we can start to measure the reliability of critical requests. We'll use the PolarisService to measure the reliability of an HTTP request in a service.

React
export class DataService {

  constructor(private http: HttpClient, private polaris: PolarisService) {}

  getRows(): Observable<Row[]> {
    const instrument = this.polaris.getInstrument('grid-data');
    return this.http.get<Row[]>('/api/rows').pipe(
      tap(() => {
        instrument.done();
      }),
      catchError((error) => {
        instrument.fail(error);
        return throwError(error);
      }),
    );
  }
}

Let's review the code above:

  • First, we inject the PolarisService into our service. Note, you can also use the inject() function to inject the service where necessary.
  • Next, we create a new instrument using the getInstrument() method. We'll use the name grid-data as the event name.
  • Then, we make the HTTP request and use the tap() operator to call instrument.done() when the request completes successfully.
  • Finally, we use the catchError() operator to call instrument.fail() when the request fails.

Intercepting HTTP Requests

Angular's HttpClient allows us to intercept HTTP requests to create measurements for any/all HTTP requests by the Angular application.

You can create your own Angular interceptor to measure the error rate of your API, or you can choose to use the provided polarisInterceptor Angular interceptor.

Create an Angular Interceptor

Let's look at an example of creating your own Angular interceptor.

React
import { measure } from '@getpolaris.ai/sdk';

export const measureApiInterceptor: HttpInterceptorFn = (req, next) => {
  // optionally filter requests

  const instrument = measure('request', {
    method: req.method,
    url: req.url,
  });
  return next(req).pipe(
    tap((event) => {
      if (event.type === HttpEventType.Response) {
        instrument.done({
          status: event.status,
        });
      }
    }),
    catchError((error) => {
      instrument.fail({ error });
      throw error;
    })
  );
};

Let's review the code above.

  1. Import the measure function from the Polaris SDK.
  2. Create an interceptor function that takes the HTTP request and the next interceptor in the chain.
  3. Optionally filter the requests.
  4. Create a new measurement using the measure function with the event name request and the metadata method and url.
  5. Return the next interceptor in the chain and add a tap operator to handle the response.
  6. If the response is successful, call the done method on the measurement with the metadata status.
  7. If the response fails, call the fail method on the measurement with the metadata error.

If you're using Angular modules in your application, you can create an Angular interceptor by implementing the HttpInterceptor interface.

React
import { measure } from '@getpolaris.ai/sdk';

@Injectable()
export class MeasureApiInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const instrument = measure('request', {
      method: req.method,
      url: req.url,
    });
    return next.handle(req).pipe(
      tap((event) => {
        if (event.type === HttpEventType.Response) {
          instrument.done({
            status: event.status,
          });
        }
      }),
      catchError((error) => {
        instrument.fail({ error });
        throw error;
      })
    );
  }
}

Provide polarisInterceptor to Angular HTTP client

Provide the polarisInterceptor function to the Angular HTTP client using the withInterceptors() function.

React
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { providePolaris, polarisInterceptor } from '@getpolaris.ai/sdk-angular';

bootstrapApplication(AppComponent, {
  providers: [
    providePolaris({
      apiKey: API_KEY,
    }),
    provideHttpClient(withInterceptors([polarisInterceptor]))
  ],
});

You can customize the eventName of the measurement. The default event name value is request.

React
import { providePolaris } from '@getpolaris.ai/sdk-angular';

bootstrapApplication(AppComponent, {
  providers: [
    providePolaris({
      apiKey: API_KEY,
      interceptor: {
        eventName: 'api-request'
      }
    }),
  ],
});

If you're using Angular modules in your application, configure the eventName by specifying the options to the forRoot method.

React
import { PolarisModule } from '@getpolaris.ai/sdk-angular';

@NgModule({
  imports: [
    PolarisModule.forRoot({
      apiKey: API_KEY,
      interceptor: {
        eventName: 'api-request'
      }
    }),
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

Interceptor Metadata

If you are using the Angular interceptor for all HTTP requests, the following user-defined metadata will be added to the measurement:

  • url: The URL of the HTTP request.
  • method: The HTTP method of the request.
  • status: The HTTP status code of the response.

Here is an example of a measurement with the interceptor metadata:

TS
  {
    eventName: 'request',
    userMetadata: {
      url: 'https://api.example.com',
      method: 'GET',
      status: 200
    },
    duration: 1000
  }