From 6b361960da8c955cb334bebaced26134b3b490dd Mon Sep 17 00:00:00 2001 From: Rishi Kumar <1720744+mrrishimeena@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:37:42 +0530 Subject: [PATCH] refactor: errsole capturing logs before initialize --- lib/errsole.js | 4 +-- lib/main/logs/index.js | 55 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/errsole.js b/lib/errsole.js index 852558a..55876e0 100644 --- a/lib/errsole.js +++ b/lib/errsole.js @@ -1,11 +1,11 @@ 'use strict'; - +const ErrsoleMain = require('./main'); const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware'); const koaProxies = require('koa-proxies'); const h2o2 = require('@hapi/h2o2'); const util = require('util'); const http = require('http'); -const ErrsoleMain = require('./main'); + const Errsole = { port: 8001 }; diff --git a/lib/main/logs/index.js b/lib/main/logs/index.js index 25dc431..f8656e1 100644 --- a/lib/main/logs/index.js +++ b/lib/main/logs/index.js @@ -10,13 +10,20 @@ const LogLevel = { const CollectLogsHook = { storage: {}, - collectLogs: [], + collectLogs: ['info', 'error'], hostname: null, pid, + pendingLogs: [], enableConsoleOutput: process.env.NODE_ENV !== 'production' }; +const timeoutId = setTimeout(() => { + CollectLogsHook.addEmptyStreamToLogs(); + console.error('Error: Unable to initialize the errsole'); +}, 10000); + CollectLogsHook.initialize = function (options) { + const self = this; this.storage = options.storage; this.hostname = options.serverName || os.hostname(); if (options && typeof options.enableConsoleOutput !== 'undefined') { @@ -24,17 +31,23 @@ CollectLogsHook.initialize = function (options) { } this.collectLogs = options.collectLogs || ['info', 'error']; if (this.collectLogs.includes(LogLevel.INFO)) { - this.captureLogs(LogLevel.INFO); console.log('Errsole is capturing INFO logs.'); } else { + process.stdout.write = originalStdoutWrite; console.log('Errsole is NOT capturing INFO logs.'); } if (this.collectLogs.includes(LogLevel.ERROR)) { - this.captureLogs(LogLevel.ERROR); console.log('Errsole is capturing ERROR logs.'); } else { + process.stderr.write = originalStderrWrite; console.log('Errsole is NOT capturing ERROR logs.'); } + if (self.storage.once) { + self.storage.once('ready', function () { + clearTimeout(timeoutId); + self.addStreamToLogs(); + }); + } }; CollectLogsHook.captureLogs = function (level) { @@ -74,6 +87,18 @@ CollectLogsHook.captureLogs = function (level) { }; }; +// Start capturing logs immediately with default settings +const originalStdoutWrite = process.stdout.write; +const originalStderrWrite = process.stderr.write; + +if (CollectLogsHook.collectLogs.includes(LogLevel.INFO)) { + CollectLogsHook.captureLogs(LogLevel.INFO); +} + +if (CollectLogsHook.collectLogs.includes(LogLevel.ERROR)) { + CollectLogsHook.captureLogs(LogLevel.ERROR); +} + CollectLogsHook.customLogger = function (level, message, metadata) { try { const logEntry = { timestamp: new Date().toISOString(), message, meta: metadata || '{}', source: 'errsole', level, hostname: this.hostname || '', pid: this.pid || 0 }; @@ -84,11 +109,33 @@ CollectLogsHook.customLogger = function (level, message, metadata) { CollectLogsHook.logStream = new stream.Writable({ objectMode: true, write (logEntry, encoding, callback) { - CollectLogsHook.storage.postLogs([logEntry]); + CollectLogsHook.pendingLogs.push(logEntry); setImmediate(() => callback()); } }); +CollectLogsHook.addStreamToLogs = function () { + this.logStream = new stream.Writable({ + objectMode: true, + write (logEntry, encoding, callback) { + CollectLogsHook.storage.postLogs([logEntry]); + setImmediate(() => callback()); + } + }); + this.pendingLogs.forEach(logEntry => { + this.logStream.write(logEntry); + }); +}; + +CollectLogsHook.addEmptyStreamToLogs = function () { + this.logStream = new stream.Writable({ + objectMode: true, + write (logEntry, encoding, callback) { + setImmediate(() => callback()); + } + }); +}; + CollectLogsHook.clearLogsBeforeExit = async function (timeout = 5000) { if (typeof this.storage.flushLogs === 'function') { try {