From e172d0201607ba827aaa41a8817675474fee37b9 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Fri, 18 Mar 2022 23:41:47 +0200 Subject: [PATCH] add logging --- apps/red-ui/src/app/app.module.ts | 28 ++++++++++++++++++- .../file-preview-screen.component.ts | 24 ++++++++-------- .../src/app/services/logger-rules.service.ts | 22 +++++++++++++++ libs/red-domain/src/lib/shared/index.ts | 1 + .../src/lib/shared/logger-config.ts | 11 ++++++++ package.json | 1 + yarn.lock | 13 +++++++++ 7 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 apps/red-ui/src/app/services/logger-rules.service.ts create mode 100644 libs/red-domain/src/lib/shared/logger-config.ts diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index ccb4e4d83..aeb4391d0 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -19,7 +19,7 @@ import { DownloadsListScreenComponent } from '@components/downloads-list-screen/ import { AppRoutingModule } from './app-routing.module'; import { SharedModule } from '@shared/shared.module'; import { FileUploadDownloadModule } from '@upload-download/file-upload-download.module'; -import { PlatformLocation } from '@angular/common'; +import { DatePipe as BaseDatePipe, PlatformLocation } from '@angular/common'; import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE, BASE_HREF } from './tokens'; import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; import { GlobalErrorHandler } from '@utils/global-error-handler.service'; @@ -48,6 +48,9 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic import { ArchivedDossiersService } from '@services/dossiers/archived-dossiers.service'; import { FeaturesService } from '@services/features.service'; import { MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip'; +import { LoggerModule, NgxLoggerLevel, TOKEN_LOGGER_CONFIG, TOKEN_LOGGER_RULES_SERVICE } from 'ngx-logger'; +import { LoggerRulesService } from '@services/logger-rules.service'; +import { ILoggerConfig } from '@red/domain'; export function httpLoaderFactory(httpClient: HttpClient, configService: ConfigService): PruningTranslationLoader { return new PruningTranslationLoader(httpClient, '/assets/i18n/', `.json?version=${configService.values.FRONTEND_APP_VERSION}`); @@ -98,6 +101,28 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp }, }), ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }), + LoggerModule.forRoot(undefined, { + ruleProvider: { + provide: TOKEN_LOGGER_RULES_SERVICE, + useClass: LoggerRulesService, + }, + configProvider: { + provide: TOKEN_LOGGER_CONFIG, + useValue: { + level: environment.production ? NgxLoggerLevel.ERROR : NgxLoggerLevel.DEBUG, + enableSourceMaps: true, + timestampFormat: 'hh:mm:ss SSS', + disableFileDetails: true, + features: { + ANNOTATIONS: { + color: 'aqua', + enabled: true, + level: NgxLoggerLevel.DEBUG, + }, + }, + } as ILoggerConfig, + }, + }), ], providers: [ { @@ -172,6 +197,7 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp }, }, DatePipe, + BaseDatePipe, ], bootstrap: [AppComponent], }) diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 72f052648..b1ea8c209 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -9,6 +9,7 @@ import { ErrorService, FilterService, LoadingService, + log, NestedFilter, OnAttach, OnDetach, @@ -49,6 +50,7 @@ import { PdfViewer } from './services/pdf-viewer.service'; import { FilePreviewDialogService } from './services/file-preview-dialog.service'; import { FileDataService } from './services/file-data.service'; import { ALL_HOTKEYS } from './shared/constants'; +import { NGXLogger } from 'ngx-logger'; import Annotation = Core.Annotations.Annotation; import PDFNet = Core.PDFNet; @@ -82,6 +84,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni readonly pdf: PdfViewer, private readonly _router: Router, private readonly _ngZone: NgZone, + private readonly _logger: NGXLogger, private readonly _filesService: FilesService, private readonly _errorService: ErrorService, readonly stateService: FilePreviewStateService, @@ -256,8 +259,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni AnnotationProcessingService.secondaryAnnotationFilters(this._fileDataService.viewedPages), ), }); - console.log(`[REDACTION] Process time: ${new Date().getTime() - processStartTime} ms`); - console.log(`[REDACTION] Filter rebuild time: ${new Date().getTime() - startTime}`); + + this._logger.debug(`[REDACTION] Process time: ${new Date().getTime() - processStartTime} ms`); + this._logger.debug(`[REDACTION] Filter rebuild time: ${new Date().getTime() - startTime}`); } async handleAnnotationSelected(annotationIds: string[]) { @@ -422,13 +426,14 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni let start; return combineLatest([documentLoaded$, this._fileDataService.annotations$]).pipe( debounceTime(300), + log(), tap(() => (start = new Date().getTime())), map(([, annotations]) => annotations), startWith({} as Record), pairwise(), tap(annotations => this.deleteAnnotations(...annotations)), switchMap(annotations => this.drawChangedAnnotations(...annotations)), - tap(() => console.log(`%c [ANNOTATIONS] Processing time: ${new Date().getTime() - start}`, 'color: aqua')), + tap(() => this._logger.debug(`[ANNOTATIONS] Processing time: ${new Date().getTime() - start}`)), tap(() => this.updateViewMode()), ); } @@ -440,7 +445,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return; } - console.log('%c [ANNOTATIONS] To delete: ', 'color: aqua', annotationsToDelete); + this._logger.debug('[ANNOTATIONS] To delete: ', annotationsToDelete); this.pdf.deleteAnnotations(annotationsToDelete.map(annotation => annotation.id)); } @@ -456,7 +461,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return firstValueFrom(of({})); } - console.log('%c [ANNOTATIONS] To draw: ', 'color: aqua', annotationsToDraw); + this._logger.debug('[ANNOTATIONS] To draw: ', annotationsToDraw); const annotationsToDrawIds = annotationsToDraw.map(a => a.annotationId); this.pdf.deleteAnnotations(annotationsToDrawIds); return this._cleanupAndRedrawAnnotations(annotationsToDraw); @@ -472,7 +477,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni const changed = JSON.stringify(oldAnnotation) !== JSON.stringify(newAnnotation); if (changed && this.userPreferenceService.areDevFeaturesEnabled) { import('@iqser/common-ui').then(commonUi => { - console.log('%c [ANNOTATIONS] Changed annotation: ', 'color: aqua', { + this._logger.debug('[ANNOTATIONS] Changed annotation: ', { value: oldAnnotation.value, before: commonUi.deepDiffObj(newAnnotation, oldAnnotation), after: commonUi.deepDiffObj(oldAnnotation, newAnnotation), @@ -517,7 +522,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni try { await clearStamps(pdfDoc, this.pdf.PDFNet, allPages); } catch (e) { - console.log('Error clearing stamps: ', e); + this._logger.debug('Error clearing stamps: ', e); return; } @@ -625,10 +630,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } await this._annotationDrawService.drawAnnotations(newAnnotations); - console.log( - `%c [ANNOTATIONS] Redraw time: ${new Date().getTime() - startTime} ms for ${newAnnotations.length} annotations`, - 'color: aqua', - ); + this._logger.debug(`[ANNOTATIONS] Redraw time: ${new Date().getTime() - startTime} ms for ${newAnnotations.length} annotations`); } private _handleDeltaAnnotationFilters(currentFilters: NestedFilter[], newAnnotations: AnnotationWrapper[]) { diff --git a/apps/red-ui/src/app/services/logger-rules.service.ts b/apps/red-ui/src/app/services/logger-rules.service.ts new file mode 100644 index 000000000..d522b9ed5 --- /dev/null +++ b/apps/red-ui/src/app/services/logger-rules.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import { INGXLoggerConfig, NgxLoggerLevel, NGXLoggerRulesService } from 'ngx-logger'; +import { ILoggerConfig } from '@red/domain'; + +@Injectable() +export class LoggerRulesService extends NGXLoggerRulesService { + shouldCallWriter(level: NgxLoggerLevel, config: ILoggerConfig, message?: unknown, additional?: unknown[]): boolean { + if (message && typeof message === 'string') { + const matches = message.match('(?<=\\[)(.*?)(?=\\])'); + + if (matches && matches.length > 0 && config.features[matches[0]]) { + const featureConfig = config.features[matches[0]]; + + if (!featureConfig.enabled || (featureConfig.level && featureConfig?.level < config.level)) { + return false; + } + } + } + + return super.shouldCallWriter(level, config as INGXLoggerConfig, message, additional); + } +} diff --git a/libs/red-domain/src/lib/shared/index.ts b/libs/red-domain/src/lib/shared/index.ts index fa1b7d849..57a45f6fd 100644 --- a/libs/red-domain/src/lib/shared/index.ts +++ b/libs/red-domain/src/lib/shared/index.ts @@ -8,3 +8,4 @@ export * from './colors'; export * from './view-mode'; export * from './expandable-file-actions'; export * from './pdf.types'; +export * from './logger-config'; diff --git a/libs/red-domain/src/lib/shared/logger-config.ts b/libs/red-domain/src/lib/shared/logger-config.ts new file mode 100644 index 000000000..d45b75c57 --- /dev/null +++ b/libs/red-domain/src/lib/shared/logger-config.ts @@ -0,0 +1,11 @@ +import { INGXLoggerConfig, NgxLoggerLevel } from 'ngx-logger'; + +interface ILoggerFeature { + color?: string; + enabled?: boolean; + level?: NgxLoggerLevel; +} + +export interface ILoggerConfig extends INGXLoggerConfig { + features: Record; +} diff --git a/package.json b/package.json index e77f14a20..0c1af82c7 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "moment": "^2.29.1", "monaco-editor": "^0.33.0", "ngx-color-picker": "^12.0.1", + "ngx-logger": "^5.0.9", "ngx-toastr": "^14.1.3", "ngx-translate-messageformat-compiler": "^5.0.1", "object-hash": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index e02dc288c..09bf8f44a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8939,6 +8939,14 @@ ngx-color-picker@^12.0.1: dependencies: tslib "^2.3.0" +ngx-logger@^5.0.9: + version "5.0.9" + resolved "https://registry.yarnpkg.com/ngx-logger/-/ngx-logger-5.0.9.tgz#b889a9160a6e47d6dd5ff41cc263ec37a5063015" + integrity sha512-iE3TzfcVcVi7k85CDcUGkF464JueFy0gqcaCg0x31wHnCSYr4MsbIydnNVr9Tasx7xtVnKSKAbWBB4WBkeTokg== + dependencies: + tslib "^2.3.0" + vlq "^1.0.0" + ngx-toastr@^14.1.3: version "14.2.2" resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-14.2.2.tgz#19a144e96a18523d8a196c2aab2e319ff762bf16" @@ -12087,6 +12095,11 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +vlq@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" + integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"