logs-interceptor
Version:
High-performance, production-ready log interceptor for Node.js applications with Loki integration. Built with Clean Architecture principles. Supports Node.js, Browser, and Node-RED.
125 lines • 3.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = void 0;
/**
* Presentation: Logger
* Public API for the logs interceptor
*/
const events_1 = require("events");
class Logger extends events_1.EventEmitter {
constructor(createLogEntryUseCase, logRepository, contextService) {
super();
this.createLogEntryUseCase = createLogEntryUseCase;
this.logRepository = logRepository;
this.contextService = contextService;
this.isDestroyed = false;
this.startTime = Date.now();
this.metrics = {
logsProcessed: 0,
logsDropped: 0,
logsSanitized: 0,
flushCount: 0,
errorCount: 0,
bufferSize: 0,
avgFlushTime: 0,
lastFlushTime: 0,
memoryUsage: 0,
cpuUsage: 0,
circuitBreakerTrips: 0,
};
}
async log(level, message, context) {
if (this.isDestroyed) {
return;
}
try {
await this.createLogEntryUseCase.execute({ level, message, context });
this.metrics.logsProcessed++;
this.emit('log', { level, message, context });
}
catch (error) {
this.metrics.logsDropped++;
this.emit('error', error);
}
}
debug(message, context) {
this.log('debug', message, context).catch(() => {
// Silent fail
});
}
info(message, context) {
this.log('info', message, context).catch(() => {
// Silent fail
});
}
warn(message, context) {
this.log('warn', message, context).catch(() => {
// Silent fail
});
}
error(message, context) {
this.log('error', message, context).catch(() => {
// Silent fail
});
}
fatal(message, context) {
this.log('fatal', message, context)
.then(() => this.flush())
.catch(() => {
// Silent fail
});
}
trackEvent(eventName, properties) {
this.info(`[EVENT] ${eventName}`, properties);
}
async flush() {
try {
await this.logRepository.flush();
this.metrics.flushCount++;
this.metrics.lastFlushTime = Date.now();
this.emit('flush');
}
catch (error) {
this.metrics.errorCount++;
this.emit('error', error);
throw error;
}
}
runWithContext(context, fn) {
return this.contextService.runWithContext(context, fn);
}
async runWithContextAsync(context, fn) {
return this.contextService.runWithContextAsync(context, fn);
}
getMetrics() {
return { ...this.metrics };
}
async getHealth() {
var _a;
const repoHealth = await this.logRepository.getHealth();
const metadata = this.contextService.getMetadata();
return {
healthy: repoHealth.healthy,
lastSuccessfulFlush: repoHealth.lastSuccessfulFlush,
consecutiveErrors: repoHealth.errorCount,
bufferUtilization: repoHealth.pendingEntries / 100,
uptime: Date.now() - this.startTime,
memoryUsageMB: (_a = metadata.memoryUsage) !== null && _a !== void 0 ? _a : 0,
circuitBreakerState: 'closed', // TODO: Get from circuit breaker service
};
}
async destroy() {
if (this.isDestroyed)
return;
this.isDestroyed = true;
try {
await this.flush();
}
catch {
// Ignore errors during destroy
}
this.removeAllListeners();
}
}
exports.Logger = Logger;
//# sourceMappingURL=Logger.js.map