diff --git a/apps/portal/src/app/app.module.ts b/apps/portal/src/app/app.module.ts index 68937b4..4b429e7 100644 --- a/apps/portal/src/app/app.module.ts +++ b/apps/portal/src/app/app.module.ts @@ -1,13 +1,14 @@ -import { NgModule } from '@angular/core'; +import { NgModule, ErrorHandler } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; +import { MyErrorHandler } from './shared/services/error-handler.service'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, AppRoutingModule], - providers: [], + providers: [{ provide: ErrorHandler, useClass: MyErrorHandler }], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/apps/portal/src/app/shared/enum.ts b/apps/portal/src/app/shared/enum.ts new file mode 100644 index 0000000..96caf36 --- /dev/null +++ b/apps/portal/src/app/shared/enum.ts @@ -0,0 +1,13 @@ +export enum LogLevel { + Info = 'INFO', + Warn = 'WARN', + Error = 'ERROR', + Fatal = 'FATAL', +} + +export enum LogSeverity { + Critical = 'CRITICAL', + High = 'HIGH', + Medium = 'MEDIUM', + Low = 'LOW', +} diff --git a/apps/portal/src/app/shared/services/error-handler.service.spec.ts b/apps/portal/src/app/shared/services/error-handler.service.spec.ts new file mode 100644 index 0000000..5c87b3e --- /dev/null +++ b/apps/portal/src/app/shared/services/error-handler.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { MyErrorHandler } from './error-handler.service'; + +describe('ErrorHandlerService', () => { + let service: MyErrorHandler; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(MyErrorHandler); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/apps/portal/src/app/shared/services/error-handler.service.ts b/apps/portal/src/app/shared/services/error-handler.service.ts new file mode 100644 index 0000000..cb24781 --- /dev/null +++ b/apps/portal/src/app/shared/services/error-handler.service.ts @@ -0,0 +1,12 @@ +import { ErrorHandler, Injectable } from '@angular/core'; +import { Logger } from './logger.service'; + +@Injectable() +export class MyErrorHandler implements ErrorHandler { + constructor(private logger: Logger) {} + + // eslint-disable-next-line + handleError(error: any): void { + // code to use logger will be done here + } +} diff --git a/apps/portal/src/app/shared/services/logger.service.spec.ts b/apps/portal/src/app/shared/services/logger.service.spec.ts new file mode 100644 index 0000000..1b83b2f --- /dev/null +++ b/apps/portal/src/app/shared/services/logger.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { Logger } from './logger.service'; + +describe('LoggerService', () => { + let service: Logger; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(Logger); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/apps/portal/src/app/shared/services/logger.service.ts b/apps/portal/src/app/shared/services/logger.service.ts new file mode 100644 index 0000000..853bad6 --- /dev/null +++ b/apps/portal/src/app/shared/services/logger.service.ts @@ -0,0 +1,82 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable, throwError, catchError } from 'rxjs'; +import { LogLevel, LogSeverity } from '../enum'; + +@Injectable({ + providedIn: 'root', +}) +export class Logger { + private apiUrl = ''; + + constructor(private http: HttpClient) {} + + log( + severity: LogSeverity, + level: LogLevel, + sessionId: string | null, + screenName: string | null, + source: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data: any | null, + message: string, + stackTrace: string | null, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ): Observable { + try { + const timestamp = new Date().toISOString(); + const deviceInfo = this.getDeviceInfo(); + const logObject = { + timestamp, + level, + severity, + sessionId, + screenName, + source, + deviceInfo, + data, + message, + stackTrace, + }; + + // Dummy code for sending API request + return this.http.post(this.apiUrl, logObject).pipe( + catchError((error) => + // eslint-disable-line + throwError(() => new Error(error)), + ), + ); + } catch (error) { + return throwError(() => new Error('Error occured while logging')); + } + } + + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-explicit-any + private getDeviceInfo(): any { + const { userAgent } = window.navigator; + let platform = ''; + + if (userAgent.match(/Win/)) { + platform = 'Windows'; + } else if (userAgent.match(/Mac/)) { + platform = 'Mac'; + } else if (userAgent.match(/Linux/)) { + platform = 'Linux'; + } else if (userAgent.match(/Android/)) { + platform = 'Android'; + } else if (userAgent.match(/iPhone|iPad|iPod/)) { + platform = 'iOS'; + } else { + platform = 'Other'; + } + + return { + userAgent, + language: window.navigator.language, + platform, + screenResolution: `${window.screen.width}x${window.screen.height}`, + viewport: `${window.innerWidth}x${window.innerHeight}`, + onlineStatus: navigator.onLine, + }; + } +}