UNPKG

@bernierllc/logging

Version:

A comprehensive logging package with Winston integration for audit and system logging

382 lines (381 loc) 13.7 kB
"use strict"; /* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ServiceLoggingManager = void 0; exports.createServiceLoggingManager = createServiceLoggingManager; exports.getServiceLoggingManager = getServiceLoggingManager; exports.resetServiceLoggingManager = resetServiceLoggingManager; exports.createConfiguredLogger = createConfiguredLogger; const coreLogger_1 = require("./mocks/coreLogger"); const loadConfiguration_1 = require("./config/loadConfiguration"); const systemLogger_1 = require("./systemLogger"); const auditLogger_1 = require("./auditLogger"); const coreLoggerBridge_1 = require("./coreLoggerBridge"); /** * Service Logging Manager * * This class orchestrates the entire logging service, managing both: * 1. Core @bernierllc/logger integration with runtime configuration * 2. Service-level Winston-based system and audit logging * * It provides a unified interface that bridges the gap between the * atomic core logger and the comprehensive service-level logging needs. */ class ServiceLoggingManager { config; configSources = []; coreLogger; systemLogger; auditLogger; coreLoggerBridge; isInitialized = false; constructor(runtimeConfig) { // Load configuration with inheritance from core logger this.initializeConfiguration(runtimeConfig); } /** * Initialize configuration synchronously */ initializeConfiguration(runtimeConfig) { try { // Load service configuration without core logger first const { config, sources } = (0, loadConfiguration_1.loadServiceLoggingConfigurationWithSources)(); // Apply runtime configuration overrides if (runtimeConfig) { this.mergeConfiguration(config, runtimeConfig); sources.push({ key: 'runtime-override', value: runtimeConfig, source: 'override', description: 'Runtime configuration override' }); } this.config = config; this.configSources = sources; } catch (error) { console.error('❌ Failed to load logging service configuration:', error); throw new Error(`Logging service configuration failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Load and merge configuration from all sources (async version for core logger integration) */ async loadConfigurationWithCoreLogger(runtimeConfig) { try { // First, try to get core logger configuration to inherit from let coreLoggerConfig; try { const coreLogger = await (0, coreLogger_1.createLoggerFromConfig)(); coreLoggerConfig = coreLogger.getConfig(); } catch (error) { console.warn('⚠️ Could not load core logger configuration, using service defaults'); } // Load service configuration with core logger inheritance const { config, sources } = (0, loadConfiguration_1.loadServiceLoggingConfigurationWithSources)(coreLoggerConfig); // Apply runtime configuration overrides if (runtimeConfig) { this.mergeConfiguration(config, runtimeConfig); sources.push({ key: 'runtime-override', value: runtimeConfig, source: 'override', description: 'Runtime configuration override' }); } this.config = config; this.configSources = sources; // Log configuration loading transparency console.log('⚙️ Service Logging: Configuration loaded successfully'); const nonDefaultSources = sources.filter(s => s.source !== 'default'); if (nonDefaultSources.length > 0) { console.log(' Configuration sources:'); nonDefaultSources.forEach(source => { console.log(` └── ${source.source}: ${source.description}`); }); } } catch (error) { console.error('❌ Failed to load logging service configuration:', error); throw new Error(`Logging service configuration failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Initialize the logging service with all configured loggers */ async initialize() { if (this.isInitialized) return; try { // Initialize core logger with service configuration await this.initializeCoreLogger(); // Initialize service-level loggers await this.initializeServiceLoggers(); this.isInitialized = true; console.log('✅ Service Logging: All loggers initialized successfully'); } catch (error) { console.error('❌ Failed to initialize logging service:', error); throw new Error(`Logging service initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Initialize core logger with service configuration */ async initializeCoreLogger() { try { // Create core logger configuration from service configuration const coreConfig = this.mapServiceConfigToCoreConfig(); // Create core logger bridge this.coreLoggerBridge = await (0, coreLoggerBridge_1.createCoreSystemLogger)(); this.coreLogger = this.coreLoggerBridge.getCoreLogger(); console.log('✅ Core logger bridge initialized'); } catch (error) { console.warn('⚠️ Core logger initialization failed, service will use Winston fallback:', error); } } /** * Initialize service-level Winston loggers */ async initializeServiceLoggers() { // Initialize system logger if (this.config.system.enabled) { this.systemLogger = this.createWinstonSystemLogger(); console.log('✅ Winston system logger initialized'); } // Initialize audit logger if (this.config.audit.enabled) { this.auditLogger = this.createWinstonAuditLogger(); console.log('✅ Winston audit logger initialized'); } } /** * Map service configuration to core logger configuration */ mapServiceConfigToCoreConfig() { return { level: this.config.level, enableCorrelation: this.config.enableCorrelation, sanitize: this.config.sanitize, sanitizeFields: this.config.sanitizeFields, context: this.config.context, transports: { console: this.config.system.console, file: this.config.system.file, http: this.config.system.http } }; } /** * Create Winston system logger from service configuration */ createWinstonSystemLogger() { const systemConfig = this.config.system; return (0, systemLogger_1.createSystemLogger)({ level: systemConfig.level, enableConsole: systemConfig.console?.enabled, enableFile: systemConfig.file?.enabled, filePath: systemConfig.file?.filename || './logs/system.log', maxSize: systemConfig.file?.maxSize?.toString() || '10m', maxFiles: systemConfig.file?.maxFiles?.toString() || '5', defaultMeta: { service: this.config.context.service, version: this.config.context.version, environment: this.config.context.environment, hostname: this.config.context.hostname, pid: this.config.context.pid } }); } /** * Create Winston audit logger from service configuration */ createWinstonAuditLogger() { const auditConfig = this.config.audit; return (0, auditLogger_1.createAuditLogger)({ level: auditConfig.level, enableConsole: auditConfig.console?.enabled || false, enableFile: auditConfig.file?.enabled ?? true, filePath: auditConfig.file?.filename || './logs/audit.log', defaultMeta: { service: this.config.context.service, version: this.config.context.version, environment: this.config.context.environment, hostname: this.config.context.hostname, pid: this.config.context.pid } }); } /** * Merge configuration objects recursively */ mergeConfiguration(target, source) { Object.keys(source).forEach(key => { if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { if (!target[key]) target[key] = {}; this.mergeConfiguration(target[key], source[key]); } else { target[key] = source[key]; } }); } /** * Get the core logger instance (preferred for new code) */ getCoreLogger() { return this.coreLogger; } /** * Get the core logger bridge (Winston-compatible interface) */ getCoreLoggerBridge() { return this.coreLoggerBridge; } /** * Get the Winston system logger (legacy compatibility) */ getSystemLogger() { return this.systemLogger; } /** * Get the Winston audit logger */ getAuditLogger() { return this.auditLogger; } /** * Get resolved configuration */ getConfiguration() { return this.config; } /** * Get configuration sources for transparency */ getConfigurationSources() { return [...this.configSources]; } /** * Log using the best available logger (core logger preferred, Winston fallback) */ log(level, message, metadata) { if (this.coreLogger) { this.coreLogger.log(level, message, metadata || {}); } else if (this.systemLogger) { this.systemLogger.log(level, message, metadata); } else { console.log(`[${level.toUpperCase()}] ${message}`, metadata); } } /** * Convenience logging methods */ error(message, error, metadata) { if (error && metadata) { metadata.error = error.message; metadata.stack = error.stack; } this.log('error', message, metadata); } warn(message, metadata) { this.log('warn', message, metadata); } info(message, metadata) { this.log('info', message, metadata); } debug(message, metadata) { this.log('debug', message, metadata); } /** * Audit logging method */ audit(entry) { const auditEntry = { ...entry, timestamp: new Date().toISOString(), service: this.config.context.service, environment: this.config.context.environment }; if (this.auditLogger) { this.auditLogger.info('Audit Event', auditEntry); } else if (this.coreLogger) { this.coreLogger.info('Audit Event', auditEntry); } else { console.log('[AUDIT]', auditEntry); } } /** * Check if service is initialized */ isReady() { return this.isInitialized; } /** * Shutdown all loggers gracefully */ async shutdown() { console.log('🔄 Service Logging: Shutting down...'); // Close Winston loggers if (this.systemLogger) { this.systemLogger.end(); } if (this.auditLogger) { this.auditLogger.end(); } // Core logger cleanup would happen here if needed console.log('✅ Service Logging: Shutdown complete'); } } exports.ServiceLoggingManager = ServiceLoggingManager; /** * Global service logging manager instance */ let globalServiceLoggingManager = null; /** * Create or get the global service logging manager */ async function createServiceLoggingManager(runtimeConfig) { if (!globalServiceLoggingManager) { globalServiceLoggingManager = new ServiceLoggingManager(runtimeConfig); await globalServiceLoggingManager.initialize(); } return globalServiceLoggingManager; } /** * Get the global service logging manager (must be created first) */ function getServiceLoggingManager() { return globalServiceLoggingManager; } /** * Reset global service logging manager (for testing) */ function resetServiceLoggingManager() { globalServiceLoggingManager = null; } /** * Convenience function to create a logger with runtime configuration */ async function createConfiguredLogger(runtimeConfig) { const manager = await createServiceLoggingManager(runtimeConfig); return { coreLogger: manager.getCoreLogger(), systemLogger: manager.getSystemLogger(), auditLogger: manager.getAuditLogger(), manager }; } //# sourceMappingURL=serviceLoggingManager.js.map