UNPKG

@rasla/express-logify

Version:

A beautiful, fast, and type-safe logging middleware for Express.js applications

131 lines (130 loc) 4.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Logger = void 0; const chalk_1 = __importDefault(require("chalk")); const fs_1 = require("fs"); const path_1 = require("path"); const LOG_COLORS = { debug: chalk_1.default.gray, info: chalk_1.default.blue, warn: chalk_1.default.yellow, error: chalk_1.default.red, }; class Logger { constructor(options = {}) { this.options = { ...Logger.DEFAULT_OPTIONS, ...options }; this.initializeFileLogger(); } debug(input) { this.log('debug', input); } info(input) { this.log('info', input); } warn(input) { this.log('warn', input); } error(input) { this.log('error', input); } log(level, input) { if (!this.shouldLog(level)) return; const entry = this.createLogEntry(level, input); const formattedMessage = this.formatLogEntry(entry); if (this.options.console) { const colorize = LOG_COLORS[level] || chalk_1.default.white; console.log(colorize(formattedMessage)); } if (this.options.file) { this.writeToFile(formattedMessage); } } shouldLog(level) { const levels = ['debug', 'info', 'warn', 'error']; const configuredLevel = levels.indexOf(this.options.level || 'info'); const currentLevel = levels.indexOf(level); return currentLevel >= configuredLevel; } createLogEntry(level, input) { const timestamp = new Date(); if (typeof input === 'string') { return { timestamp, level, method: '', path: '', statusCode: 0, duration: 0, message: input, }; } return { timestamp, level, method: input.method || '', path: input.path || '', statusCode: input.statusCode || 0, duration: input.duration || 0, message: input.message || '', ip: input.ip, }; } formatLogEntry(entry) { const format = this.options.format || Logger.DEFAULT_OPTIONS.format; const timestamp = entry.timestamp.toISOString(); const level = entry.level.toUpperCase().padEnd(5); const method = (entry.method || '').toUpperCase().padEnd(7); const path = entry.path || '-'; const statusCode = entry.statusCode ? `${entry.statusCode}` : ''; const duration = entry.duration ? `${entry.duration}` : ''; const message = entry.message || ''; const ip = entry.ip && this.options.includeIp ? ` from ${entry.ip}` : ''; return format .replace('{timestamp}', timestamp) .replace('{level}', level) .replace('{method}', method) .replace('{path}', path) .replace('{statusCode}', statusCode) .replace('{duration}', duration) .replace('{message}', message) .replace('{ip}', ip) .trim(); } writeToFile(message) { if (this.options.file && this.options.filePath) { try { (0, fs_1.appendFileSync)(this.options.filePath, message + '\n'); } catch (error) { console.error('Failed to write to log file:', error); } } } initializeFileLogger() { if (this.options.file && this.options.filePath) { try { const dir = (0, path_1.dirname)(this.options.filePath); if (!(0, fs_1.existsSync)(dir)) { (0, fs_1.mkdirSync)(dir, { recursive: true }); } } catch (error) { console.error('Failed to initialize log directory:', error); } } } } exports.Logger = Logger; Logger.DEFAULT_OPTIONS = { console: true, file: false, filePath: './logs/app.log', level: 'info', skip: [], includeIp: false, format: '[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip}', };