import * as fs from 'fs' import * as path from 'path' import Logger, { LoggerType } from '#application/logger' export class LogReader { private logger = Logger.type(LoggerType.CONSOLE) private watchers: fs.FSWatcher[] = [] private readonly logsDirectory: string constructor(rootPath: string) { this.logsDirectory = path.join(rootPath, 'logs') } public start(): void { this.logger.info('Starting log reader...') this.watchLogs() } public stop(): void { this.watchers.forEach((watcher) => watcher.close()) this.watchers = [] } private watchLogs(): void { // Watch directory for new files const directoryWatcher = fs.watch(this.logsDirectory, (_, filename) => { if (filename?.endsWith('.log')) { this.watchLogFile(filename) } }) this.watchers.push(directoryWatcher) // Watch existing files try { fs.readdirSync(this.logsDirectory) .filter((file) => file.endsWith('.log')) .forEach((file) => this.watchLogFile(file)) } catch (error) { this.logger.error(`Error reading logs directory: ${error}`) } } private watchLogFile(filename: string): void { const filePath = path.join(this.logsDirectory, filename) let currentPosition = fs.existsSync(filePath) ? fs.statSync(filePath).size : 0 const watcher = fs.watch(filePath, () => { try { const stat = fs.statSync(filePath) const newPosition = stat.size if (newPosition < currentPosition) { currentPosition = 0 } if (newPosition > currentPosition) { const stream = fs.createReadStream(filePath, { start: currentPosition, end: newPosition }) stream.on('data', (data) => { console.log(`[${filename}]`); console.log(data.toString()); // }) currentPosition = newPosition } } catch { watcher.close() } }) this.watchers.push(watcher) } }