未加星标

Logging HTTP Response Times in Angular

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

Most API and Backend Services have a metric service to measure to measure request response times. The one downside of this is, it doesn’t consider network latency, or how the device capability is affecting the performance of your web app.

This is important, since a lot of the people access your web apps using low end mobile devices. Collecting such telemetry data is vital, as it can help you fine tune the performance of your web app. In this post, we will look at how you can measure the time it takes to send and receive HTTP responses, from the frontend.

Once you have access to the data, you can then send it to a logging server. To make this information useful for analyses in future, we will also be collecting browser, operating system and any device information we can get. Remember to update your apps terms of use and privacy policy accordingly.

How it Works

We are going to be using aHTTP Interceptor to intercept both outgoing requests and incoming responses. Then, we will be adding a timestamp for outgoing requests and then read it on responses. And then, we are going to find a difference between the current timestamp and the one for outgoing request.

We will then take that information, together with device information and send it to a logging server. To collect device data, we are going to be using ngx-device-detector library. This will give us information such as OS, Browser, User Agent etc.

So, without further ado.

Initial App Setup

First, we need to create a new angular application:

$ ng new ng-measure-http-response-times

Next, we will install our app dependency, using your favorite package manager:

$ yarn add ngx-device-detector $ npm install ngx-device-detector

And then, import both DeviceDetectorModule and HttpClientModule in your application module.

... import { HttpClientModule } from '@angular/common/http'; import { DeviceDetectorModule } from 'ngx-device-detector'; ... @NgModule({ ... imports: [ ... HttpClientModule, DeviceDetectorModule.forRoot() ... ], ... }) export class AppModule {} Create a HTTP Interceptor

Next up, let’s create a HTTP Interceptor. You can do this by generating a class using angular cli and then adding support for dependency injection.

$ ng g class http-response-time-logger

Then implement http interceptor interface, add dependency injection support and an intercept method for our class:

... @Injectable() export class HttpResponseTimeLogger implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { ... } }

Next, we need to inject DeviceDetectorService to our class, so we can use it within our intercept method:

constructor(private deviceService: DeviceDetectorService) {}

And then register our interceptor class in the app module, list of providers:

@NgModule({ ... providers: [ ... { provide: HTTP_INTERCEPTORS, useClass: HttpResponseTimeLogger, multi: true } ], ... }) Adding A Timestamp Header

Now, we need to get the current timestamp header when the request is being sent. Our timestamp will be in millisecond for some level of accuracy.

const startTimestamp = new Date().getTime();

Then, we need to clone our request and add the timestamp header:

const newReq = req.clone({headers: req.headers.set('startTimestamp', startTimestamp.toString())});

The idea here is, you will get the header from the request on the server and return it with the response. You can use a middleware to automatically retrieve the header and attach it to the response.

Next, return the newly cloned request and tap to the response.

return next.handle(newReq).pipe( tap((res: Response) => { }); Calculating and Logging HTTP Response Time

Then, inside our tap method , we need to read the timestamp from the response header and get the current timestamp in millisecond, then finally get the difference.

// another timestamp const endTimestamp: number = new Date().getTime(); const startTimestamp2: number = Number( res.headers.get('startTimestamp')); // get the difference const responseTimes = endTimestamp - startTimestamp2;

NB: You don’t have to get the difference inside your http interceptor. You can also log the start and end timestamps and let the server handle the calculation for you.

Next up, we need to get the device information using the DeviceDetectorService method.

const deviceInfo = this.deviceService.getDeviceInfo();

Now we have everything we need to log the data. One option would be to send the data over to the logging server directly.

this.http .post('URL HERE', { startTime: startTimestamp2, endTime: endTimestamp, difference: difference, deviceInfo: JSON.stringify(deviceInfo) // decode the data on the server }) .subscribe();

NB: You can also store the logs locally and collect them periodically on the background .

Logging a Portion of all Requests

You can also decide instead of logging all requests, to log some of the requests. One way you can achieve this, is by generating a random number between 1 and 6. And then check if the number is greater than 3. If the number is greater than 3, don’t log the request, otherwise log the request.

At the beginning of the intercept method, we need to add the following code:

const random = Math.floor(Math.random() * 6) + 1; // if number is less than 3 skip logging if (random > 3) { return next.handle(req); }

If everything works perfectly, you will be logging three in every six requests, about 50 % of the requests at random.

So, our final class should look like this:

@Injectable() export class HttpResponseTimeLogger implements HttpInterceptor { constructor(private deviceService: DeviceDetectorService, private http: HttpClient) {} intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const random = Math.floor(Math.random() * 6) + 1; // if number is less 3 skip logging if (random > 3) { return next.handle(req); } // get timestamp const startTimestamp = new Date().getTime(); const newReq = req.clone({ headers: req.headers.set('startTimestamp', startTimestamp.toString()) }); return next.handle(newReq).pipe( tap((res: Response) => { // another timestamp const endTimestamp: number = new Date().getTime(); const startTimestamp2: number = Number( res.headers.get('startTimestamp') ); // get the difference const responseTimes = endTimestamp - startTimestamp2; // get browser information const deviceInfo = this.deviceService.getDeviceInfo(); // send the data to the server this.http .post('URL HERE', { startTime: startTimestamp2, endTime: endTimestamp, deviceInfo: JSON.stringify(deviceInfo) }) .subscribe(); }) ); } }

Liked it? Take a second to support The InfoGrid on Patreon!


Logging HTTP Response Times in Angular

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

tags: get,const,gt,class,will
分页:12
转载请注明
本文标题:Logging HTTP Response Times in Angular
本站链接:https://www.codesec.net/view/597058.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(31)