ngs-request-tracker
Version:
`ngs-request-tracker` is a library for tracking (requestTrackerInterceptor), storing (RequestTrackerService) and displaying statistics (RequestTrackerComponent) on all http requests.
60 lines • 7.87 kB
JavaScript
import { HttpResponse, } from '@angular/common/http';
import { inject } from '@angular/core';
import { tap, catchError, throwError, finalize } from 'rxjs';
import { RequestTrackerService } from '../services/request-tracker.service';
/**
* HTTP Interceptor for tracking HTTP request metrics.
*
* This interceptor integrates with the `RequestTrackerService` to monitor HTTP requests,
* enabling real-time tracking of:
* - Number of ongoing requests.
* - Success and error counts.
* - Average response time.
* - Success and error rates.
*
* ### Workflow
* 1. Assigns a unique ID to each HTTP request.
* 2. Notifies the `RequestTrackerService` when a request is initiated.
* 3. Uses RxJS operators to track successful completions, errors, and aborts.
* 4. Updates metrics in `RequestTrackerService` based on request outcomes.
*
* ### Request Lifecycle
* - On initiation: Notifies the tracker service with a unique request ID.
* - On success (2xx status): Marks the request as successful.
* - On error (non-2xx or network error): Marks the request as failed.
* - On request cancellation: Marks the request as aborted.
*
* @param req - The HTTP request being processed.
* @param next - The next handler in the interceptor chain.
* @returns An Observable emitting HTTP events or propagating errors if any occur.
*/
export const requestTrackerInterceptor = (req, next) => {
const requestTrackerService = inject(RequestTrackerService);
const currentRequestId = requestTrackerService.requestId++;
let requestWasHandled = false;
requestTrackerService.requestSent(currentRequestId);
return next(req).pipe(tap({
next: (event) => {
if (event instanceof HttpResponse) {
requestWasHandled = true;
if (event.status >= 200 && event.status < 300) {
requestTrackerService.requestSuccess(currentRequestId);
}
else {
requestTrackerService.requestError(currentRequestId);
}
}
},
error: () => {
requestWasHandled = true;
requestTrackerService.requestError(currentRequestId);
},
}), finalize(() => {
if (!requestWasHandled) {
requestTrackerService.requestAborted(currentRequestId);
}
}), catchError((error) => {
return throwError(() => error);
}));
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC10cmFja2VyLmludGVyY2VwdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmdzLXJlcXVlc3QtdHJhY2tlci9zcmMvbGliL2RhdGEtYWNjZXNzL2ludGVyY2VwdG9ycy9yZXF1ZXN0LXRyYWNrZXIuaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUtMLFlBQVksR0FDYixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQWMsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN6RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUU1RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUNILE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFzQixDQUMxRCxHQUFxQixFQUNyQixJQUFtQixFQUNTLEVBQUU7SUFDOUIsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUM1RCxNQUFNLGdCQUFnQixHQUFHLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzNELElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDO0lBRTlCLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBRXBELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FDbkIsR0FBRyxDQUFDO1FBQ0YsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDZCxJQUFJLEtBQUssWUFBWSxZQUFZLEVBQUUsQ0FBQztnQkFDbEMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO2dCQUN6QixJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksR0FBRyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7b0JBQzlDLHFCQUFxQixDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO3FCQUFNLENBQUM7b0JBQ04scUJBQXFCLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3ZELENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUNELEtBQUssRUFBRSxHQUFHLEVBQUU7WUFDVixpQkFBaUIsR0FBRyxJQUFJLENBQUM7WUFDekIscUJBQXFCLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdkQsQ0FBQztLQUNGLENBQUMsRUFDRixRQUFRLENBQUMsR0FBRyxFQUFFO1FBQ1osSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDdkIscUJBQXFCLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDekQsQ0FBQztJQUNILENBQUMsQ0FBQyxFQUNGLFVBQVUsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQ25CLE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUNILENBQUM7QUFDSixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBIdHRwRXZlbnQsXG4gIEh0dHBIYW5kbGVyRm4sXG4gIEh0dHBJbnRlcmNlcHRvckZuLFxuICBIdHRwUmVxdWVzdCxcbiAgSHR0cFJlc3BvbnNlLFxufSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRhcCwgY2F0Y2hFcnJvciwgT2JzZXJ2YWJsZSwgdGhyb3dFcnJvciwgZmluYWxpemUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFJlcXVlc3RUcmFja2VyU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3JlcXVlc3QtdHJhY2tlci5zZXJ2aWNlJztcblxuLyoqXG4gKiBIVFRQIEludGVyY2VwdG9yIGZvciB0cmFja2luZyBIVFRQIHJlcXVlc3QgbWV0cmljcy5cbiAqXG4gKiBUaGlzIGludGVyY2VwdG9yIGludGVncmF0ZXMgd2l0aCB0aGUgYFJlcXVlc3RUcmFja2VyU2VydmljZWAgdG8gbW9uaXRvciBIVFRQIHJlcXVlc3RzLFxuICogZW5hYmxpbmcgcmVhbC10aW1lIHRyYWNraW5nIG9mOlxuICogLSBOdW1iZXIgb2Ygb25nb2luZyByZXF1ZXN0cy5cbiAqIC0gU3VjY2VzcyBhbmQgZXJyb3IgY291bnRzLlxuICogLSBBdmVyYWdlIHJlc3BvbnNlIHRpbWUuXG4gKiAtIFN1Y2Nlc3MgYW5kIGVycm9yIHJhdGVzLlxuICpcbiAqICMjIyBXb3JrZmxvd1xuICogMS4gQXNzaWducyBhIHVuaXF1ZSBJRCB0byBlYWNoIEhUVFAgcmVxdWVzdC5cbiAqIDIuIE5vdGlmaWVzIHRoZSBgUmVxdWVzdFRyYWNrZXJTZXJ2aWNlYCB3aGVuIGEgcmVxdWVzdCBpcyBpbml0aWF0ZWQuXG4gKiAzLiBVc2VzIFJ4SlMgb3BlcmF0b3JzIHRvIHRyYWNrIHN1Y2Nlc3NmdWwgY29tcGxldGlvbnMsIGVycm9ycywgYW5kIGFib3J0cy5cbiAqIDQuIFVwZGF0ZXMgbWV0cmljcyBpbiBgUmVxdWVzdFRyYWNrZXJTZXJ2aWNlYCBiYXNlZCBvbiByZXF1ZXN0IG91dGNvbWVzLlxuICpcbiAqICMjIyBSZXF1ZXN0IExpZmVjeWNsZVxuICogLSBPbiBpbml0aWF0aW9uOiBOb3RpZmllcyB0aGUgdHJhY2tlciBzZXJ2aWNlIHdpdGggYSB1bmlxdWUgcmVxdWVzdCBJRC5cbiAqIC0gT24gc3VjY2VzcyAoMnh4IHN0YXR1cyk6IE1hcmtzIHRoZSByZXF1ZXN0IGFzIHN1Y2Nlc3NmdWwuXG4gKiAtIE9uIGVycm9yIChub24tMnh4IG9yIG5ldHdvcmsgZXJyb3IpOiBNYXJrcyB0aGUgcmVxdWVzdCBhcyBmYWlsZWQuXG4gKiAtIE9uIHJlcXVlc3QgY2FuY2VsbGF0aW9uOiBNYXJrcyB0aGUgcmVxdWVzdCBhcyBhYm9ydGVkLlxuICpcbiAqIEBwYXJhbSByZXEgLSBUaGUgSFRUUCByZXF1ZXN0IGJlaW5nIHByb2Nlc3NlZC5cbiAqIEBwYXJhbSBuZXh0IC0gVGhlIG5leHQgaGFuZGxlciBpbiB0aGUgaW50ZXJjZXB0b3IgY2hhaW4uXG4gKiBAcmV0dXJucyBBbiBPYnNlcnZhYmxlIGVtaXR0aW5nIEhUVFAgZXZlbnRzIG9yIHByb3BhZ2F0aW5nIGVycm9ycyBpZiBhbnkgb2NjdXIuXG4gKi9cbmV4cG9ydCBjb25zdCByZXF1ZXN0VHJhY2tlckludGVyY2VwdG9yOiBIdHRwSW50ZXJjZXB0b3JGbiA9IChcbiAgcmVxOiBIdHRwUmVxdWVzdDxhbnk+LFxuICBuZXh0OiBIdHRwSGFuZGxlckZuLFxuKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4gPT4ge1xuICBjb25zdCByZXF1ZXN0VHJhY2tlclNlcnZpY2UgPSBpbmplY3QoUmVxdWVzdFRyYWNrZXJTZXJ2aWNlKTtcbiAgY29uc3QgY3VycmVudFJlcXVlc3RJZCA9IHJlcXVlc3RUcmFja2VyU2VydmljZS5yZXF1ZXN0SWQrKztcbiAgbGV0IHJlcXVlc3RXYXNIYW5kbGVkID0gZmFsc2U7XG5cbiAgcmVxdWVzdFRyYWNrZXJTZXJ2aWNlLnJlcXVlc3RTZW50KGN1cnJlbnRSZXF1ZXN0SWQpO1xuXG4gIHJldHVybiBuZXh0KHJlcSkucGlwZShcbiAgICB0YXAoe1xuICAgICAgbmV4dDogKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmIChldmVudCBpbnN0YW5jZW9mIEh0dHBSZXNwb25zZSkge1xuICAgICAgICAgIHJlcXVlc3RXYXNIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoZXZlbnQuc3RhdHVzID49IDIwMCAmJiBldmVudC5zdGF0dXMgPCAzMDApIHtcbiAgICAgICAgICAgIHJlcXVlc3RUcmFja2VyU2VydmljZS5yZXF1ZXN0U3VjY2VzcyhjdXJyZW50UmVxdWVzdElkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVxdWVzdFRyYWNrZXJTZXJ2aWNlLnJlcXVlc3RFcnJvcihjdXJyZW50UmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICByZXF1ZXN0V2FzSGFuZGxlZCA9IHRydWU7XG4gICAgICAgIHJlcXVlc3RUcmFja2VyU2VydmljZS5yZXF1ZXN0RXJyb3IoY3VycmVudFJlcXVlc3RJZCk7XG4gICAgICB9LFxuICAgIH0pLFxuICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgIGlmICghcmVxdWVzdFdhc0hhbmRsZWQpIHtcbiAgICAgICAgcmVxdWVzdFRyYWNrZXJTZXJ2aWNlLnJlcXVlc3RBYm9ydGVkKGN1cnJlbnRSZXF1ZXN0SWQpO1xuICAgICAgfVxuICAgIH0pLFxuICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgfSksXG4gICk7XG59O1xuIl19