From 22e0c841488134d560f5332d8bab3bf39c6c602e Mon Sep 17 00:00:00 2001 From: Siim Raud Date: Wed, 18 Dec 2024 09:44:25 +0200 Subject: [PATCH 1/4] feat: unified logging with timestamp --- .../lib/services/graphql/graphql.service.ts | 26 ++++++++++--------- .../src/lib/util/logger/logger.ts | 24 +++++++++++++++++ 2 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 packages/javascript-api/src/lib/util/logger/logger.ts diff --git a/packages/javascript-api/src/lib/services/graphql/graphql.service.ts b/packages/javascript-api/src/lib/services/graphql/graphql.service.ts index cd06074b..e99b397e 100644 --- a/packages/javascript-api/src/lib/services/graphql/graphql.service.ts +++ b/packages/javascript-api/src/lib/services/graphql/graphql.service.ts @@ -13,6 +13,7 @@ import { calculateRandomizedExponentialBackoffTime } from '../../util/randomized import { sleepMs } from '../../util/sleep-ms/sleep-ms.js'; import { ApiBase, GraphqlQuery } from '../api-base/api-base.js'; import { TemporaryApiKeyService } from '../temporary-api-key/temporary-api-key.service'; +import { Logger } from '../../util/logger/logger'; type QueryOrDocument = string | DocumentNode; @@ -85,6 +86,7 @@ const CLIENT_SIDE_CLOSE_EVENT = 1000; * trying to import GraphQLService. */ export class GraphqlService { + private logger: Logger = new Logger('GraphQL'); private apiServer: string; private socket: WebSocket = null; @@ -280,7 +282,7 @@ export class GraphqlService { return; } this.setConnectionStatus(ConnectionStatus.CONNECTING); - console.info('[Qminder API]: Connecting to websocket 111'); + this.logger.info('Connecting to websocket'); this.fetchTemporaryApiKey() .then((temporaryApiKey: string) => { this.createSocketConnection(temporaryApiKey); @@ -321,7 +323,7 @@ export class GraphqlService { }; socket.onclose = (event: CloseEvent) => { - console.warn('[Qminder API] WebSocket connection closed:', { + this.logger.warn('WebSocket connection closed:', { code: event.code, reason: event.reason, }); @@ -334,8 +336,8 @@ export class GraphqlService { const timer = calculateRandomizedExponentialBackoffTime( this.connectionAttemptsCount, ); - console.log( - `[Qminder API]: Waiting for ${timer.toFixed( + this.logger.info( + `Waiting for ${timer.toFixed( 1, )}ms before reconnecting`, ); @@ -346,18 +348,18 @@ export class GraphqlService { } if (this.connectionStatus === ConnectionStatus.CONNECTING) { - console.error( + this.logger.error( `Received socket close event before a connection was established! Close code: ${event.code}`, ); } }; socket.onerror = () => { - const message = '[Qminder API]: Websocket error occurred!'; + const message = 'Websocket error occurred!'; if (this.isBrowserOnline()) { - console.error(message); + this.logger.error(message); } else { - console.info(message); + this.logger.info(message); } }; @@ -372,7 +374,7 @@ export class GraphqlService { case MessageType.GQL_CONNECTION_ACK: this.connectionAttemptsCount = 0; this.setConnectionStatus(ConnectionStatus.CONNECTED); - console.info('[Qminder API]: Connected to websocket'); + this.logger.info('Connected to websocket'); this.startConnectionMonitoring(); this.subscriptions.forEach((subscription) => { const payload = { query: subscription.query }; @@ -489,10 +491,10 @@ export class GraphqlService { return; } if (this.isBrowserOnline()) { - console.warn(`[Qminder API]: Websocket connection dropped!`); + this.logger.warn(`Websocket connection dropped!`); } else { - console.info( - `[Qminder API]: Websocket connection dropped. We are offline.`, + this.logger.info( + `Websocket connection dropped. We are offline.`, ); } this.setConnectionStatus(ConnectionStatus.DISCONNECTED); diff --git a/packages/javascript-api/src/lib/util/logger/logger.ts b/packages/javascript-api/src/lib/util/logger/logger.ts new file mode 100644 index 00000000..5f2f9542 --- /dev/null +++ b/packages/javascript-api/src/lib/util/logger/logger.ts @@ -0,0 +1,24 @@ +export class Logger { + private prefix = 'Qminder SDK'; + private readonly name: string; + + constructor(name: string) { + this.name = name; + } + + info(message: string, ...optionalParams: any[]): void { + console.log(this.constructStatement(message), ...optionalParams); + } + + warn(message: string, ...optionalParams: any[]): void { + console.warn(this.constructStatement(message), ...optionalParams); + } + + error(message: string, ...optionalParams: any[]): void { + console.error(this.constructStatement(message), ...optionalParams); + } + + private constructStatement(message: string): string { + return `[${this.prefix}][${this.name}] ${message}`; + } +} From 39c971a59a495383ddf14559af458e17d2d98a28 Mon Sep 17 00:00:00 2001 From: Siim Raud Date: Wed, 18 Dec 2024 09:45:29 +0200 Subject: [PATCH 2/4] Prettier --- .../src/lib/services/graphql/graphql.service.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/javascript-api/src/lib/services/graphql/graphql.service.ts b/packages/javascript-api/src/lib/services/graphql/graphql.service.ts index e99b397e..252cbb4b 100644 --- a/packages/javascript-api/src/lib/services/graphql/graphql.service.ts +++ b/packages/javascript-api/src/lib/services/graphql/graphql.service.ts @@ -337,9 +337,7 @@ export class GraphqlService { this.connectionAttemptsCount, ); this.logger.info( - `Waiting for ${timer.toFixed( - 1, - )}ms before reconnecting`, + `Waiting for ${timer.toFixed(1)}ms before reconnecting`, ); sleepMs(timer).then(() => { this.connectionAttemptsCount += 1; @@ -493,9 +491,7 @@ export class GraphqlService { if (this.isBrowserOnline()) { this.logger.warn(`Websocket connection dropped!`); } else { - this.logger.info( - `Websocket connection dropped. We are offline.`, - ); + this.logger.info(`Websocket connection dropped. We are offline.`); } this.setConnectionStatus(ConnectionStatus.DISCONNECTED); this.clearPingMonitoring(); From b91596f78b1708b1ab5eb3066555a0d0f5c64f0f Mon Sep 17 00:00:00 2001 From: Siim Raud Date: Wed, 18 Dec 2024 09:55:42 +0200 Subject: [PATCH 3/4] Timestamp --- .../temporary-api-key.service.ts | 17 ++++++++--------- .../src/lib/util/logger/logger.ts | 4 ++-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/javascript-api/src/lib/services/temporary-api-key/temporary-api-key.service.ts b/packages/javascript-api/src/lib/services/temporary-api-key/temporary-api-key.service.ts index 70043c2c..b1331512 100644 --- a/packages/javascript-api/src/lib/services/temporary-api-key/temporary-api-key.service.ts +++ b/packages/javascript-api/src/lib/services/temporary-api-key/temporary-api-key.service.ts @@ -1,7 +1,9 @@ import { RequestInit } from '../../model/fetch'; import { sleepMs } from '../../util/sleep-ms/sleep-ms'; +import { Logger } from '../../util/logger/logger'; export class TemporaryApiKeyService { + private logger: Logger = new Logger('TemporaryKey'); private readonly apiServer: string; private readonly permanentApiKey: string; @@ -26,10 +28,10 @@ export class TemporaryApiKeyService { response = await fetch(`https://${this.apiServer}/${url}`, body); } catch (e) { if (this.isBrowserOnline()) { - console.warn('[Qminder API]: Failed to fetch temporary API key'); + this.logger.warn('Failed to fetch temporary API key'); } else { - console.info( - '[Qminder API]: Failed to fetch temporary API key. The browser is offline.', + this.logger.info( + 'Failed to fetch temporary API key. The browser is offline.', ); } return this.retry(retryCount + 1); @@ -41,7 +43,7 @@ export class TemporaryApiKeyService { ); } if (response.status >= 500) { - console.error( + this.logger.error( `Failed to fetch API key from the server. Status: ${response.status}`, ); return this.retry(retryCount + 1); @@ -59,17 +61,14 @@ export class TemporaryApiKeyService { } return key; } catch (e) { - console.error( - '[Qminder API]: Failed to parse the temporary API key response', - e, - ); + this.logger.error('Failed to parse the temporary API key response', e); return this.retry(retryCount + 1); } } private async retry(retryCount = 0): Promise { const timeOutMs = Math.min(60000, Math.max(5000, 2 ** retryCount * 1000)); - console.info(`[Qminder API]: Retrying to fetch API key in ${timeOutMs} ms`); + this.logger.info(`Retrying to fetch API key in ${timeOutMs} ms`); await sleepMs(timeOutMs); return this.fetchTemporaryApiKey(retryCount + 1); } diff --git a/packages/javascript-api/src/lib/util/logger/logger.ts b/packages/javascript-api/src/lib/util/logger/logger.ts index 5f2f9542..430ca592 100644 --- a/packages/javascript-api/src/lib/util/logger/logger.ts +++ b/packages/javascript-api/src/lib/util/logger/logger.ts @@ -1,5 +1,5 @@ export class Logger { - private prefix = 'Qminder SDK'; + private prefix = 'QminderSDK'; private readonly name: string; constructor(name: string) { @@ -19,6 +19,6 @@ export class Logger { } private constructStatement(message: string): string { - return `[${this.prefix}][${this.name}] ${message}`; + return `[${new Date().toISOString()}][${this.prefix}][${this.name}] ${message}`; } } From f8dc35808b22a1cf55527f66e75b65914e2807f8 Mon Sep 17 00:00:00 2001 From: Siim Raud Date: Wed, 18 Dec 2024 09:57:36 +0200 Subject: [PATCH 4/4] Prettier --- packages/javascript-api/src/lib/util/logger/logger.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/javascript-api/src/lib/util/logger/logger.ts b/packages/javascript-api/src/lib/util/logger/logger.ts index 430ca592..fa5acdd5 100644 --- a/packages/javascript-api/src/lib/util/logger/logger.ts +++ b/packages/javascript-api/src/lib/util/logger/logger.ts @@ -19,6 +19,8 @@ export class Logger { } private constructStatement(message: string): string { - return `[${new Date().toISOString()}][${this.prefix}][${this.name}] ${message}`; + return `[${new Date().toISOString()}][${this.prefix}][${ + this.name + }] ${message}`; } }