UNPKG

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
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