UNPKG

blanc-logger

Version:

Advanced Winston logger for NestJS & TypeORM with structured logging.

106 lines (105 loc) 5.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.blancLogger = void 0; const chalk = require("chalk"); const nest_winston_1 = require("nest-winston"); const util = require("util"); const winston = require("winston"); const DailyRotateFile = require("winston-daily-rotate-file"); const uuid_1 = require("../helper/uuid"); const logger_config_1 = require("./logger.config"); const { LOG_DIR, CONSOLE_LOG_LEVEL, FILE_LOG_LEVEL, ROTATION_DAYS, MAX_FILE_SIZE } = logger_config_1.LOGGING_CONFIG; const MAX_OBJECT_DEPTH = 5; const MAX_OBJECT_WIDTH = 120; /** util.inspect의 사전 정의된 옵션을 사용하여 객체를 문자열로 포맷팅 */ const deepInspector = (obj) => util.inspect(obj, { colors: true, depth: MAX_OBJECT_DEPTH, breakLength: MAX_OBJECT_WIDTH, compact: false, sorted: true, }); /** 로그 레벨에 해당하는 이모지를 매핑 */ const emojiMap = { error: '🚨', warn: '⚠️', info: '🍀', verbose: '📢', debug: '🐛', }; /** 로그 레벨에 해당하는 chalk 색상 함수를 매핑 */ const levelColorMap = { error: chalk.hex('#FF6B6B'), warn: chalk.hex('#FFD93D'), info: chalk.hex('#845EC2'), debug: chalk.hex('#4D96FF'), verbose: chalk.hex('#6BCB77'), }; /** 모듈 경로를 색상이 적용된 계층적 문자열로 변환 */ const moduleHierarchyTransform = (info) => { var _a, _b, _c, _d; info.moduleName = (_d = (_c = (_b = (_a = info.moduleName) === null || _a === void 0 ? void 0 : _a.split('/')) === null || _b === void 0 ? void 0 : _b.map((part) => chalk.cyan(part))) === null || _c === void 0 ? void 0 : _c.join(chalk.dim(' → '))) !== null && _d !== void 0 ? _d : info.moduleName; return info; }; /** 파일 로그에 대한 타임스탬프와 JSON 포맷을 결합 */ const fileLogFormat = winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.json()); /** 로그 파일 순환을 위한 DailyRotateFile 전송 객체를 생성 */ const createDailyRotateFileTransport = (filename, level) => new DailyRotateFile({ dirname: LOG_DIR, filename: `${filename}-%DATE%.log`, datePattern: 'YYYY-MM-DD', level, zippedArchive: true, maxSize: MAX_FILE_SIZE, maxFiles: ROTATION_DAYS, format: fileLogFormat, }); /** 로그 메타데이터에 고유한 logId가 없으면 추가 */ const addMetaDataTransform = (info) => { var _a; (_a = info.logId) !== null && _a !== void 0 ? _a : (info.logId = (0, uuid_1.generateUUID)()); return info; }; /** 제공된 moduleName 또는 context 속성을 사용하여 모듈 이름을 포맷팅 */ const formatModuleName = (info) => { var _a, _b; const moduleName = (_a = info.moduleName) !== null && _a !== void 0 ? _a : (typeof info.context === 'object' ? (_b = info.context) === null || _b === void 0 ? void 0 : _b.moduleName : info.context); return moduleName ? `[${moduleName}]` : ''; }; /** 로그 메시지를 포맷팅하며, 객체인 경우 deepInspector를 사용하여 포맷팅 */ const formatMessage = (info) => { const message = info.stack || info.message; return typeof message === 'object' ? deepInspector(message) : String(message); }; /** 이모지를 추가하고 대문자로 변환하여 로그 레벨을 변환 */ const transformLogLevel = (info) => { info.rawLevel = info.level; info.level = `${emojiMap[info.level] || ''} ${info.level.toUpperCase()}`.padEnd(5); return info; }; /** 다양한 포맷팅 함수를 결합하여 최종 콘솔 로그 포맷을 생성 */ const customConsoleFormat = winston.format.combine(winston.format(addMetaDataTransform)(), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format(moduleHierarchyTransform)(), winston.format(transformLogLevel)(), winston.format.printf((info) => { var _a; const colorFunc = levelColorMap[(_a = info.rawLevel) !== null && _a !== void 0 ? _a : ''] || ((text) => chalk.bold.white(text)); const coloredLevel = colorFunc(info.level); const simpleLogId = info.logId ? chalk.hex('#00008B')(`[${info.logId.substring(0, 8)}]`) : ''; const moduleStr = formatModuleName(info); const messageStr = formatMessage(info); return `${simpleLogId} ${chalk.dim(info.timestamp)} ${coloredLevel} ${moduleStr} - ${chalk.blueBright(messageStr)}`; })); /** 구성된 전송 및 포맷을 사용하여 WinstonModule로 blancLogger를 생성 */ exports.blancLogger = nest_winston_1.WinstonModule.createLogger({ transports: [ new winston.transports.Console({ level: CONSOLE_LOG_LEVEL, format: customConsoleFormat, handleExceptions: true, handleRejections: true, }), createDailyRotateFileTransport('error', 'error'), createDailyRotateFileTransport('combined', FILE_LOG_LEVEL), ], exceptionHandlers: [createDailyRotateFileTransport('exceptions', 'error')], rejectionHandlers: [createDailyRotateFileTransport('rejections', 'error')], });