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 f0847427..55c66942 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.js'; +import { Logger } from '../../util/logger/logger.js'; type QueryOrDocument = string | DocumentNode; @@ -85,6 +86,7 @@ const CLIENT_SIDE_CLOSE_EVENT = 1000; * trying to import GraphQLService. */ export class GraphqlService { + private 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,10 +336,8 @@ export class GraphqlService { const timer = calculateRandomizedExponentialBackoffTime( this.connectionAttemptsCount, ); - console.log( - `[Qminder API]: Waiting for ${timer.toFixed( - 1, - )}ms before reconnecting`, + this.logger.info( + `Waiting for ${timer.toFixed(1)}ms before reconnecting`, ); sleepMs(timer).then(() => { this.connectionAttemptsCount += 1; @@ -346,18 +346,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 +372,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,11 +489,9 @@ 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); this.clearPingMonitoring(); 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 a5d234c5..b683b809 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.js'; import { sleepMs } from '../../util/sleep-ms/sleep-ms.js'; +import { Logger } from '../../util/logger/logger.js'; export class TemporaryApiKeyService { + private 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 new file mode 100644 index 00000000..fa5acdd5 --- /dev/null +++ b/packages/javascript-api/src/lib/util/logger/logger.ts @@ -0,0 +1,26 @@ +export class Logger { + private prefix = 'QminderSDK'; + 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 `[${new Date().toISOString()}][${this.prefix}][${ + this.name + }] ${message}`; + } +}