diff --git a/apps/data-service/src/index.ts b/apps/data-service/src/index.ts index 3394389..8b99bc5 100644 --- a/apps/data-service/src/index.ts +++ b/apps/data-service/src/index.ts @@ -240,11 +240,12 @@ shutdown.onShutdown(async () => { } }); +// Logger shutdown - registered last so it runs after all other shutdown operations shutdown.onShutdown(async () => { try { logger.info('Shutting down loggers...'); await shutdownLoggers(); - logger.info('Loggers shut down successfully'); + // Don't log after shutdown } catch (error) { // Silently ignore logger shutdown errors } diff --git a/libs/logger/src/logger.ts b/libs/logger/src/logger.ts index 887ddf2..7d5d4a0 100644 --- a/libs/logger/src/logger.ts +++ b/libs/logger/src/logger.ts @@ -54,7 +54,6 @@ function createTransports(serviceName: string, config: LoggerConfig = globalConf ignore: 'pid,hostname,service,environment,version,childName', errorLikeObjectKeys: ['err', 'error'], errorProps: 'message,stack,name,code', - sync: false, }, }); } @@ -119,7 +118,8 @@ function getPinoLogger(serviceName: string, config: LoggerConfig = globalConfig) loggerOptions.transport = transport; } - loggerCache.set(cacheKey, pino(loggerOptions)); + const logger = pino(loggerOptions); + loggerCache.set(cacheKey, logger); } const logger = loggerCache.get(cacheKey); @@ -307,32 +307,49 @@ export function getLogger( /** * Gracefully shutdown all logger instances - * This should be called during application shutdown to ensure all logs are flushed + * This ensures all transports are flushed and closed properly */ export async function shutdownLoggers(): Promise { - const flushPromises = Array.from(loggerCache.values()).map(logger => { - return new Promise(resolve => { - if (typeof logger.flush === 'function') { - logger.flush(err => { - if (err) { - // eslint-disable-next-line no-console - console.error('Logger flush error:', err); - } - resolve(); - }); - } else { - resolve(); - } - }); - }); - try { - await Promise.allSettled(flushPromises); + // Log final message before shutdown + for (const logger of loggerCache.values()) { + logger.info('Logger shutting down...'); + } - // console.log('All loggers flushed successfully'); + // Flush all loggers + const flushPromises = Array.from(loggerCache.values()).map(logger => { + return new Promise((resolve) => { + // First try to flush if the method exists + if (typeof logger.flush === 'function') { + const timeout = setTimeout(() => { + // eslint-disable-next-line no-console + console.warn('Logger flush timeout after 100ms'); + resolve(); + }, 100); + + logger.flush((err) => { + clearTimeout(timeout); + if (err) { + // eslint-disable-next-line no-console + console.error('Logger flush error:', err); + } + resolve(); + }); + } else { + resolve(); + } + }); + }); + + await Promise.all(flushPromises); + + // Give transports time to finish writing + // This is especially important for file and network transports + await new Promise(resolve => setTimeout(resolve, 100)); + } catch (error) { // eslint-disable-next-line no-console - console.error('Logger flush failed:', error); + console.error('Logger shutdown failed:', error); } finally { loggerCache.clear(); }