UNPKG

thrilled-be-core

Version:

Core Express backend package with middleware, logging, security, and base application setup

126 lines (125 loc) 4.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultLogger = exports.Logger = void 0; exports.createLogger = createLogger; const tslib_1 = require("tslib"); const fs_1 = require("fs"); const path_1 = require("path"); const winston_1 = tslib_1.__importDefault(require("winston")); const winston_daily_rotate_file_1 = tslib_1.__importDefault(require("winston-daily-rotate-file")); class Logger { winston; config; constructor(config) { this.config = { level: 'info', dir: './logs', format: 'simple', httpLogging: true, maxFiles: 30, correlationId: true, ...config, }; this.winston = this.createLogger(); } static create(config) { return new Logger(config); } info(message, meta) { this.winston.info(message, this.addCorrelation(meta)); } error(error, context) { if (error instanceof Error) { this.winston.error(error.message, this.addCorrelation({ ...context, stack: error.stack, name: error.name, })); } else { this.winston.error(error, this.addCorrelation(context)); } } warn(message, meta) { this.winston.warn(message, this.addCorrelation(meta)); } debug(message, meta) { this.winston.debug(message, this.addCorrelation(meta)); } createLogger() { // Ensure log directory exists const logDir = this.config.dir || './logs'; if (!(0, fs_1.existsSync)(logDir)) { (0, fs_1.mkdirSync)(logDir, { recursive: true }); } const format = this.config.format === 'json' ? winston_1.default.format.combine(winston_1.default.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss', }), winston_1.default.format.errors({ stack: true }), winston_1.default.format.json()) : winston_1.default.format.combine(winston_1.default.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston_1.default.format.errors({ stack: true }), winston_1.default.format.printf(({ timestamp, level, message }) => { return `${timestamp} ${level}: ${message}`; })); // Console format for development (timestamp first, then colorized) const consoleFormat = winston_1.default.format.combine(winston_1.default.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston_1.default.format.errors({ stack: true }), winston_1.default.format.printf(({ timestamp, level, message }) => { return `${timestamp} ${level}: ${message}`; }), winston_1.default.format.colorize({ all: true })); const transports = [ // Console transport for development new winston_1.default.transports.Console({ level: process.env.NODE_ENV === 'production' ? 'info' : 'debug', format: consoleFormat, }), // File transport for all logs new winston_daily_rotate_file_1.default({ level: this.config.level, datePattern: 'YYYY-MM-DD', dirname: (0, path_1.join)(logDir, 'combined'), filename: '%DATE%.log', maxFiles: this.config.maxFiles, zippedArchive: true, format, }), // Error-only file transport new winston_daily_rotate_file_1.default({ level: 'error', datePattern: 'YYYY-MM-DD', dirname: (0, path_1.join)(logDir, 'error'), filename: '%DATE%.log', maxFiles: this.config.maxFiles, zippedArchive: true, format, }), ]; return winston_1.default.createLogger({ level: this.config.level, format, transports, exitOnError: false, }); } addCorrelation(meta) { if (!this.config.correlationId) { return meta || {}; } // In a real implementation, you'd get this from async local storage // or from the request context return { ...meta, correlationId: this.generateCorrelationId(), }; } generateCorrelationId() { return Math.random().toString(36).substring(2, 15); } } exports.Logger = Logger; // Default logger instance for convenience exports.defaultLogger = new Logger({ level: 'info', dir: './logs', format: 'simple', }); // Convenience function to create a logger with custom config function createLogger(config) { return new Logger(config); }