| const path = require('path'); |
| const winston = require('winston'); |
| require('winston-daily-rotate-file'); |
| const { redactFormat, redactMessage, debugTraverse, jsonTruncateFormat } = require('./parsers'); |
|
|
| const logDir = path.join(__dirname, '..', 'logs'); |
|
|
| const { NODE_ENV, DEBUG_LOGGING = true, CONSOLE_JSON = false, DEBUG_CONSOLE = false } = process.env; |
|
|
| const useConsoleJson = |
| (typeof CONSOLE_JSON === 'string' && CONSOLE_JSON?.toLowerCase() === 'true') || |
| CONSOLE_JSON === true; |
|
|
| const useDebugConsole = |
| (typeof DEBUG_CONSOLE === 'string' && DEBUG_CONSOLE?.toLowerCase() === 'true') || |
| DEBUG_CONSOLE === true; |
|
|
| const useDebugLogging = |
| (typeof DEBUG_LOGGING === 'string' && DEBUG_LOGGING?.toLowerCase() === 'true') || |
| DEBUG_LOGGING === true; |
|
|
| const levels = { |
| error: 0, |
| warn: 1, |
| info: 2, |
| http: 3, |
| verbose: 4, |
| debug: 5, |
| activity: 6, |
| silly: 7, |
| }; |
|
|
| winston.addColors({ |
| info: 'green', |
| warn: 'italic yellow', |
| error: 'red', |
| debug: 'blue', |
| }); |
|
|
| const level = () => { |
| const env = NODE_ENV || 'development'; |
| const isDevelopment = env === 'development'; |
| return isDevelopment ? 'debug' : 'warn'; |
| }; |
|
|
| const fileFormat = winston.format.combine( |
| redactFormat(), |
| winston.format.timestamp({ format: () => new Date().toISOString() }), |
| winston.format.errors({ stack: true }), |
| winston.format.splat(), |
| |
| ); |
|
|
| const transports = [ |
| new winston.transports.DailyRotateFile({ |
| level: 'error', |
| filename: `${logDir}/error-%DATE%.log`, |
| datePattern: 'YYYY-MM-DD', |
| zippedArchive: true, |
| maxSize: '20m', |
| maxFiles: '14d', |
| format: fileFormat, |
| }), |
| ]; |
|
|
| if (useDebugLogging) { |
| transports.push( |
| new winston.transports.DailyRotateFile({ |
| level: 'debug', |
| filename: `${logDir}/debug-%DATE%.log`, |
| datePattern: 'YYYY-MM-DD', |
| zippedArchive: true, |
| maxSize: '20m', |
| maxFiles: '14d', |
| format: winston.format.combine(fileFormat, debugTraverse), |
| }), |
| ); |
| } |
|
|
| const consoleFormat = winston.format.combine( |
| redactFormat(), |
| winston.format.colorize({ all: true }), |
| winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), |
| |
| winston.format.printf((info) => { |
| const message = `${info.timestamp} ${info.level}: ${info.message}`; |
| if (info.level.includes('error')) { |
| return redactMessage(message); |
| } |
|
|
| return message; |
| }), |
| ); |
|
|
| |
| let consoleLogLevel = 'info'; |
| if (useDebugConsole) { |
| consoleLogLevel = 'debug'; |
| } |
|
|
| if (useDebugConsole) { |
| transports.push( |
| new winston.transports.Console({ |
| level: consoleLogLevel, |
| format: useConsoleJson |
| ? winston.format.combine(fileFormat, jsonTruncateFormat(), winston.format.json()) |
| : winston.format.combine(fileFormat, debugTraverse), |
| }), |
| ); |
| } else if (useConsoleJson) { |
| transports.push( |
| new winston.transports.Console({ |
| level: consoleLogLevel, |
| format: winston.format.combine(fileFormat, jsonTruncateFormat(), winston.format.json()), |
| }), |
| ); |
| } else { |
| transports.push( |
| new winston.transports.Console({ |
| level: consoleLogLevel, |
| format: consoleFormat, |
| }), |
| ); |
| } |
|
|
| const logger = winston.createLogger({ |
| level: level(), |
| levels, |
| transports, |
| }); |
|
|
| module.exports = logger; |
|
|