UNPKG

@454creative/easy-email

Version:

A framework-agnostic email service library for Node.js with observability and monitoring

144 lines (124 loc) 3.47 kB
export enum LogLevel { DEBUG = 'debug', INFO = 'info', WARN = 'warn', ERROR = 'error', } export interface LogEntry { timestamp: string; level: LogLevel; message: string; details?: any; } export interface Metrics { totalEmailsSent: number; successfulEmails: number; failedEmails: number; averageSendTime: number; lastError?: LogEntry; } export class Logger { private static instance: Logger; private logLevel: LogLevel = LogLevel.INFO; private logs: LogEntry[] = []; private metrics: Metrics = { totalEmailsSent: 0, successfulEmails: 0, failedEmails: 0, averageSendTime: 0, }; private startTime?: number; private constructor() {} static getInstance(): Logger { if (!Logger.instance) { Logger.instance = new Logger(); } return Logger.instance; } setLogLevel(level: LogLevel): void { this.logLevel = level; } debug(message: string, details?: any): void { this.log(LogLevel.DEBUG, message, details); } info(message: string, details?: any): void { this.log(LogLevel.INFO, message, details); } warn(message: string, details?: any): void { this.log(LogLevel.WARN, message, details); } error(message: string, details?: any): void { this.log(LogLevel.ERROR, message, details); this.metrics.lastError = { timestamp: new Date().toISOString(), level: LogLevel.ERROR, message, details, }; } private log(level: LogLevel, message: string, details?: any): void { if (this.shouldLog(level)) { const entry: LogEntry = { timestamp: new Date().toISOString(), level, message, details, }; this.logs.push(entry); console.log(`[${entry.timestamp}] ${level.toUpperCase()}: ${message}`, details || ''); } } private shouldLog(level: LogLevel): boolean { const levels = Object.values(LogLevel); return levels.indexOf(level) >= levels.indexOf(this.logLevel); } startOperation(): void { this.startTime = Date.now(); } endOperation(success: boolean): void { if (this.startTime) { const duration = Date.now() - this.startTime; this.metrics.totalEmailsSent++; if (success) { this.metrics.successfulEmails++; } else { this.metrics.failedEmails++; } this.metrics.averageSendTime = (this.metrics.averageSendTime * (this.metrics.totalEmailsSent - 1) + duration) / this.metrics.totalEmailsSent; this.startTime = undefined; } } getMetrics(): Metrics { return { ...this.metrics }; } getLogs(level?: LogLevel): LogEntry[] { if (level) { return this.logs.filter(log => log.level === level); } return [...this.logs]; } clearLogs(): void { this.logs = []; } resetMetrics(): void { this.metrics = { totalEmailsSent: 0, successfulEmails: 0, failedEmails: 0, averageSendTime: 0, }; } /** * Create a standardized log entry for email operations * @param operation - The email operation being performed * @param success - Whether the operation was successful * @param details - Additional details about the operation */ logEmailOperation(operation: string, success: boolean, details?: any): void { const level = success ? LogLevel.INFO : LogLevel.ERROR; const message = `${operation} ${success ? 'completed successfully' : 'failed'}`; this.log(level, message, details); } }