Skip to content

Commit f47812d

Browse files
committed
Updates log client initialization
This update includes a timeout to handle clients initializing indefinitely, assuming some initial logs might be lost on application startup while the log client still loading. Now we can better handle this scenario since we have more control over the startup process of the log client. We've also updated error handling for this step, avoiding throwing errors on log client startup so the app is still available and able to use console.log fallback - ensuring the app is able to run even if the logger is not working properly.
1 parent f33bc58 commit f47812d

2 files changed

Lines changed: 27 additions & 16 deletions

File tree

src/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,5 @@ export const PRODUCTION = process.env.VTEX_PRODUCTION === 'true'
7272
export const INSPECT_DEBUGGER_PORT = 5858
7373

7474
export const cancellableMethods = new Set(['GET', 'OPTIONS', 'HEAD'])
75+
76+
export const LOG_CLIENT_INIT_TIMEOUT = 5000

src/service/logger/logger.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { APP } from '../../constants'
1+
import { APP, LOG_CLIENT_INIT_TIMEOUT } from '../../constants'
22
import { cleanError } from '../../utils/error'
33
import { cleanLog } from '../../utils/log'
44
import { LogClient } from '@vtex/diagnostics-nodejs/dist/types';
@@ -16,8 +16,7 @@ export class Logger {
1616
private production: boolean
1717
private tracingState?: TracingState
1818
private logClient: LogClient | undefined = undefined
19-
private clientInitialized: boolean = false
20-
private clientInitializing: boolean = false
19+
private clientInitPromise: Promise<LogClient | undefined> | undefined = undefined
2120

2221
constructor(ctx: LoggerContext) {
2322
this.account = ctx.account
@@ -36,21 +35,30 @@ export class Logger {
3635
this.initLogClient();
3736
}
3837

39-
private async initLogClient() {
40-
if (this.clientInitialized || this.clientInitializing) {
41-
return;
38+
private initLogClient(): Promise<LogClient | undefined> {
39+
if (this.clientInitPromise) {
40+
return this.clientInitPromise;
4241
}
4342

44-
this.clientInitializing = true;
45-
try {
46-
this.logClient = await getLogClient(this.account, this.workspace, APP.NAME);
47-
this.clientInitialized = true;
48-
} catch (error) {
49-
console.error('Failed to initialize log client:', error);
50-
throw error;
51-
} finally {
52-
this.clientInitializing = false;
53-
}
43+
this.clientInitPromise = (async () => {
44+
try {
45+
const timeoutPromise = new Promise<never>((_, reject) => {
46+
setTimeout(() => reject(new Error('Log client initialization timeout')), LOG_CLIENT_INIT_TIMEOUT);
47+
});
48+
49+
this.logClient = await Promise.race([
50+
getLogClient(this.account, this.workspace, APP.NAME),
51+
timeoutPromise
52+
]);
53+
54+
return this.logClient;
55+
} catch (error) {
56+
console.error('Failed to initialize log client:', error);
57+
return undefined;
58+
}
59+
})();
60+
61+
return this.clientInitPromise;
5462
}
5563

5664
public debug = (message: any) =>
@@ -115,6 +123,7 @@ export class Logger {
115123
console.error('Error using diagnostics client for logging:', e);
116124
}
117125
}
126+
118127
console.log(typeof inflatedLog === 'string' ? JSON.stringify(inflatedLog) : inflatedLog)
119128
}
120129
}

0 commit comments

Comments
 (0)