From b029328af66c90252d529ed4a06c151ba4a00498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Louren=C3=A7o?= Date: Sat, 7 Jan 2023 11:27:52 -0300 Subject: [PATCH] perf(common): faster logs by caching intl.datetimeformat --- .../common/services/console-logger.service.ts | 22 ++- packages/common/services/logger.service.ts | 153 ++++++++---------- 2 files changed, 80 insertions(+), 95 deletions(-) diff --git a/packages/common/services/console-logger.service.ts b/packages/common/services/console-logger.service.ts index addc3167303..928dc9c7ce5 100644 --- a/packages/common/services/console-logger.service.ts +++ b/packages/common/services/console-logger.service.ts @@ -23,6 +23,15 @@ const DEFAULT_LOG_LEVELS: LogLevel[] = [ 'verbose', ]; +const dateTimeFormatter = Intl.DateTimeFormat(undefined, { + year: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + day: '2-digit', + month: '2-digit', +}); + @Injectable() export class ConsoleLogger implements LoggerService { private static lastTimestampAt?: number; @@ -162,18 +171,7 @@ export class ConsoleLogger implements LoggerService { } protected getTimestamp(): string { - const localeStringOptions = { - year: 'numeric', - hour: 'numeric', - minute: 'numeric', - second: 'numeric', - day: '2-digit', - month: '2-digit', - }; - return new Date(Date.now()).toLocaleString( - undefined, - localeStringOptions as Intl.DateTimeFormatOptions, - ); + return dateTimeFormatter.format(Date.now()); } protected printMessages( diff --git a/packages/common/services/logger.service.ts b/packages/common/services/logger.service.ts index 6f7f38712a8..d17fb661602 100644 --- a/packages/common/services/logger.service.ts +++ b/packages/common/services/logger.service.ts @@ -39,47 +39,26 @@ export interface LoggerService { setLogLevels?(levels: LogLevel[]): any; } -interface LogBufferRecord { - /** - * Method to execute. - */ - methodRef: Function; - - /** - * Arguments to pass to the method. - */ - arguments: unknown[]; -} - const DEFAULT_LOGGER = new ConsoleLogger(); +const dateTimeFormatter = Intl.DateTimeFormat(undefined, { + year: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + day: '2-digit', + month: '2-digit', +}); + @Injectable() export class Logger implements LoggerService { - protected static logBuffer = new Array(); + protected static logBuffer = new Array(); protected static staticInstanceRef?: LoggerService = DEFAULT_LOGGER; protected static logLevels?: LogLevel[]; private static isBufferAttached: boolean; protected localInstanceRef?: LoggerService; - private static WrapBuffer: MethodDecorator = ( - target: object, - propertyKey: string | symbol, - descriptor: TypedPropertyDescriptor, - ) => { - const originalFn = descriptor.value; - descriptor.value = function (...args: unknown[]) { - if (Logger.isBufferAttached) { - Logger.logBuffer.push({ - methodRef: originalFn.bind(this), - arguments: args, - }); - return; - } - return originalFn.call(this, ...args); - }; - }; - constructor(); constructor(context: string); constructor(context: string, options?: { timestamp?: boolean }); @@ -97,21 +76,29 @@ export class Logger implements LoggerService { return this.registerLocalInstanceRef(); } } + return Logger.staticInstanceRef; } + private static wrapBuffer(logMethod: Function): void { + if (!Logger.isBufferAttached) return logMethod(); + + Logger.logBuffer.push(logMethod); + } + /** * Write an 'error' level log. */ error(message: any, stack?: string, context?: string): void; error(message: any, ...optionalParams: [...any, string?, string?]): void; - @Logger.WrapBuffer error(message: any, ...optionalParams: any[]) { - optionalParams = this.context - ? optionalParams.concat(this.context) - : optionalParams; + Logger.wrapBuffer(() => { + optionalParams = this.context + ? optionalParams.concat(this.context) + : optionalParams; - this.localInstance?.error(message, ...optionalParams); + this.localInstance?.error(message, ...optionalParams); + }); } /** @@ -119,12 +106,14 @@ export class Logger implements LoggerService { */ log(message: any, context?: string): void; log(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer log(message: any, ...optionalParams: any[]) { - optionalParams = this.context - ? optionalParams.concat(this.context) - : optionalParams; - this.localInstance?.log(message, ...optionalParams); + Logger.wrapBuffer(() => { + optionalParams = this.context + ? optionalParams.concat(this.context) + : optionalParams; + + this.localInstance?.log(message, ...optionalParams); + }); } /** @@ -132,12 +121,14 @@ export class Logger implements LoggerService { */ warn(message: any, context?: string): void; warn(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer warn(message: any, ...optionalParams: any[]) { - optionalParams = this.context - ? optionalParams.concat(this.context) - : optionalParams; - this.localInstance?.warn(message, ...optionalParams); + Logger.wrapBuffer(() => { + optionalParams = this.context + ? optionalParams.concat(this.context) + : optionalParams; + + this.localInstance?.warn(message, ...optionalParams); + }); } /** @@ -145,12 +136,14 @@ export class Logger implements LoggerService { */ debug(message: any, context?: string): void; debug(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer debug(message: any, ...optionalParams: any[]) { - optionalParams = this.context - ? optionalParams.concat(this.context) - : optionalParams; - this.localInstance?.debug?.(message, ...optionalParams); + Logger.wrapBuffer(() => { + optionalParams = this.context + ? optionalParams.concat(this.context) + : optionalParams; + + this.localInstance?.debug(message, ...optionalParams); + }); } /** @@ -158,12 +151,14 @@ export class Logger implements LoggerService { */ verbose(message: any, context?: string): void; verbose(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer verbose(message: any, ...optionalParams: any[]) { - optionalParams = this.context - ? optionalParams.concat(this.context) - : optionalParams; - this.localInstance?.verbose?.(message, ...optionalParams); + Logger.wrapBuffer(() => { + optionalParams = this.context + ? optionalParams.concat(this.context) + : optionalParams; + + this.localInstance?.verbose?.(message, ...optionalParams); + }); } /** @@ -175,9 +170,10 @@ export class Logger implements LoggerService { message: any, ...optionalParams: [...any, string?, string?] ): void; - @Logger.WrapBuffer static error(message: any, ...optionalParams: any[]) { - this.staticInstanceRef?.error(message, ...optionalParams); + Logger.wrapBuffer(() => { + this.staticInstanceRef?.error(message, ...optionalParams); + }); } /** @@ -185,9 +181,10 @@ export class Logger implements LoggerService { */ static log(message: any, context?: string): void; static log(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer static log(message: any, ...optionalParams: any[]) { - this.staticInstanceRef?.log(message, ...optionalParams); + Logger.wrapBuffer(() => { + this.staticInstanceRef?.log(message, ...optionalParams); + }); } /** @@ -195,9 +192,10 @@ export class Logger implements LoggerService { */ static warn(message: any, context?: string): void; static warn(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer static warn(message: any, ...optionalParams: any[]) { - this.staticInstanceRef?.warn(message, ...optionalParams); + Logger.wrapBuffer(() => { + this.staticInstanceRef?.warn(message, ...optionalParams); + }); } /** @@ -206,9 +204,10 @@ export class Logger implements LoggerService { */ static debug(message: any, context?: string): void; static debug(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer static debug(message: any, ...optionalParams: any[]) { - this.staticInstanceRef?.debug?.(message, ...optionalParams); + Logger.wrapBuffer(() => { + this.staticInstanceRef?.debug(message, ...optionalParams); + }); } /** @@ -216,9 +215,10 @@ export class Logger implements LoggerService { */ static verbose(message: any, context?: string): void; static verbose(message: any, ...optionalParams: [...any, string?]): void; - @Logger.WrapBuffer static verbose(message: any, ...optionalParams: any[]) { - this.staticInstanceRef?.verbose?.(message, ...optionalParams); + Logger.wrapBuffer(() => { + this.staticInstanceRef?.verbose(message, ...optionalParams); + }); } /** @@ -226,15 +226,13 @@ export class Logger implements LoggerService { */ static flush() { this.isBufferAttached = false; - this.logBuffer.forEach(item => - item.methodRef(...(item.arguments as [string])), - ); + this.logBuffer.forEach(logMethod => logMethod()); this.logBuffer = []; } /** * Attach buffer. - * Turns on initialisation logs buffering. + * Turns on initialization logs buffering. */ static attachBuffer() { this.isBufferAttached = true; @@ -242,25 +240,14 @@ export class Logger implements LoggerService { /** * Detach buffer. - * Turns off initialisation logs buffering. + * Turns off initialization logs buffering. */ static detachBuffer() { this.isBufferAttached = false; } static getTimestamp() { - const localeStringOptions = { - year: 'numeric', - hour: 'numeric', - minute: 'numeric', - second: 'numeric', - day: '2-digit', - month: '2-digit', - }; - return new Date(Date.now()).toLocaleString( - undefined, - localeStringOptions as Intl.DateTimeFormatOptions, - ); + return dateTimeFormatter.format(Date.now()); } static overrideLogger(logger: LoggerService | LogLevel[] | boolean) {