// Load environment variables THIS MUST BE AT THE TOP const path = require("path"); require("dotenv").config({ path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`) }); const InstanceManager = require("../utils/instanceMgr").default; const winston = require("winston"); const WinstonCloudWatch = require("winston-cloudwatch"); const { isString, isEmpty } = require("lodash"); const createLogger = () => { try { const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME); const logGroupName = isLocal ? "development" : process.env.CLOUDWATCH_LOG_GROUP; const winstonCloudwatchTransportDefaults = { logGroupName: logGroupName, awsOptions: { region: InstanceManager({ imex: "ca-central-1", rome: "us-east-2" }) }, jsonMessage: true }; if (isLocal) { winstonCloudwatchTransportDefaults.awsOptions.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`; console.log( `Winston Transports set to LocalStack end point: ${winstonCloudwatchTransportDefaults.awsOptions.endpoint}` ); } const levelFilter = (levels) => { return winston.format((info) => { if (Array.isArray(levels)) { return levels.includes(info.level) ? info : false; } else { return info.level === levels ? info : false; } })(); }; const createProductionTransport = (level, logStreamName, filters) => { return new WinstonCloudWatch({ level, logStreamName: logStreamName || level, format: levelFilter(filters || level), ...winstonCloudwatchTransportDefaults }); }; const getDevelopmentTransports = () => [ new winston.transports.Console({ level: "silly", format: winston.format.combine( winston.format.colorize(), winston.format.timestamp(), winston.format.printf(({ level, message, timestamp, user, record, object }) => { return `${timestamp} [${level}]: ${message} ${ user ? `| user: ${JSON.stringify(user)}` : "" } ${record ? `| record: ${JSON.stringify(record)}` : ""} ${ object ? `| object: ${JSON.stringify(object, null, 2)}` : "" }`; }) ) }) ]; const getProductionTransports = () => [ createProductionTransport("error"), createProductionTransport("warn"), createProductionTransport("info"), createProductionTransport("silly", "debug", ["http", "verbose", "debug", "silly"]) ]; const winstonLogger = winston.createLogger({ format: winston.format.json(), transports: process.env.NODE_ENV === "production" ? getProductionTransports() : [...getDevelopmentTransports(), ...getProductionTransports()] }); const log = (message, type, user, record, meta) => { winstonLogger.log({ level: type.toLowerCase(), message, user, record, meta }); }; return { log, logger: winstonLogger }; } catch (e) { console.error("Error setting up enhanced Logger, defaulting to console.: " + e?.message || ""); return { log: console.log, logger: console.log }; } }; module.exports = createLogger();