Aethel Bot OSS repository! aethel.xyz
bot fun ai discord discord-bot aethel
at dev 2.9 kB view raw
1import winston from 'winston'; 2import { LOG_LEVEL, NODE_ENV } from '@/config/index'; 3import path from 'path'; 4 5const sanitizeFormat = winston.format((info) => { 6 const sensitiveKeys = [ 7 'password', 8 'token', 9 'api_key', 10 'secret', 11 'authorization', 12 'userid', 13 'user_id', 14 'username', 15 'user_tag', 16 'guildid', 17 'guild_id', 18 'channelid', 19 'channel_id', 20 ]; 21 22 const sanitize = (obj: unknown): unknown => { 23 if (typeof obj !== 'object' || obj === null) return obj; 24 25 const sanitized = { ...obj } as Record<string, unknown>; 26 for (const key in sanitized) { 27 if (sensitiveKeys.some((sensitive) => key.toLowerCase().includes(sensitive))) { 28 sanitized[key] = '[REDACTED]'; 29 } else if (typeof sanitized[key] === 'string') { 30 sanitized[key] = (sanitized[key] as string).replace(/\b\d{17,19}\b/g, '[ID_REDACTED]'); 31 } else if (typeof sanitized[key] === 'object') { 32 sanitized[key] = sanitize(sanitized[key]); 33 } 34 } 35 return sanitized; 36 }; 37 38 return sanitize(info) as winston.Logform.TransformableInfo; 39}); 40 41const logger = winston.createLogger({ 42 level: LOG_LEVEL || 'info', 43 format: winston.format.combine( 44 winston.format.timestamp({ 45 format: 'YYYY-MM-DD HH:mm:ss', 46 }), 47 winston.format.errors({ stack: true }), 48 sanitizeFormat(), 49 winston.format.splat(), 50 winston.format.json(), 51 ), 52 defaultMeta: { 53 service: 'Aethel', 54 version: process.env.npm_package_version || '2.0.0', 55 environment: NODE_ENV, 56 }, 57 transports: [ 58 new winston.transports.Console({ 59 format: winston.format.combine( 60 winston.format.colorize(), 61 winston.format.printf(({ timestamp, level, message, service, ...meta }) => { 62 const metaStr = Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''; 63 return `${timestamp} [${service}] ${level}: ${message} ${metaStr}`; 64 }), 65 ), 66 }), 67 ], 68 exitOnError: false, 69}); 70 71if (NODE_ENV === 'production') { 72 const logsDir = path.join(process.cwd(), 'logs'); 73 74 logger.add( 75 new winston.transports.File({ 76 filename: path.join(logsDir, 'error.log'), 77 level: 'error', 78 maxsize: 5242880, 79 maxFiles: 5, 80 format: winston.format.combine(winston.format.timestamp(), winston.format.json()), 81 }), 82 ); 83 84 logger.add( 85 new winston.transports.File({ 86 filename: path.join(logsDir, 'combined.log'), 87 maxsize: 5242880, 88 maxFiles: 5, 89 format: winston.format.combine(winston.format.timestamp(), winston.format.json()), 90 }), 91 ); 92} 93 94logger.exceptions.handle( 95 new winston.transports.Console({ 96 format: winston.format.combine(winston.format.colorize(), winston.format.simple()), 97 }), 98); 99 100logger.rejections.handle( 101 new winston.transports.Console({ 102 format: winston.format.combine(winston.format.colorize(), winston.format.simple()), 103 }), 104); 105 106export default logger;