UNPKG

@metacall/faas

Version:

Reimplementation of MetaCall FaaS platform written in TypeScript.

116 lines (115 loc) 4.82 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.logProcessOutput = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const ANSICode = [ 166, 154, 142, 118, 203, 202, 190, 215, 214, 32, 6, 4, 220, 208, 184, 172 ]; // Maps a PID to a color code const PIDToColorCodeMap = {}; // Tracks whether a color code is assigned const assignedColorCodes = {}; const logFilePath = path.join(__dirname, '../../logs/'); const logFileName = 'app.log'; const logFileFullPath = path.resolve(path.join(logFilePath, logFileName)); // TODO: Implement this properly? // const maxWorkerWidth = (maxIndexWidth = 3): number => { // const workerLengths = Object.keys(Applications).map( // worker => worker.length // ); // return Math.max(...workerLengths) + maxIndexWidth; // }; // TODO: There is a problem with this code, looking randomly for an unique code // will end in an endless loop whenever all color codes are allocated, we should // use a better way of managing this const assignColorToWorker = (deploymentName, workerPID) => { if (!PIDToColorCodeMap[workerPID]) { let colorCode; // Keep looking for unique code do { colorCode = ANSICode[Math.floor(Math.random() * ANSICode.length)]; } while (assignedColorCodes[colorCode]); // Assign the unique code and mark it as used PIDToColorCodeMap[workerPID] = colorCode; assignedColorCodes[colorCode] = true; } const assignColorCode = PIDToColorCodeMap[workerPID]; return `\x1b[38;5;${assignColorCode}m${deploymentName}\x1b[0m`; }; class Logger { constructor() { this.logQueue = []; this.isProcessing = false; } async processQueue() { if (this.isProcessing || this.logQueue.length === 0) return; this.isProcessing = true; while (this.logQueue.length > 0) { const logEntry = this.logQueue.shift(); if (logEntry) { const { deploymentName, workerPID, message } = logEntry; this.store(deploymentName, message); this.present(deploymentName, workerPID, message); await new Promise(resolve => setTimeout(resolve, 0)); } } this.isProcessing = false; } enqueueLog(deploymentName, workerPID, message) { this.logQueue.push({ deploymentName, workerPID, message }); this.processQueue().catch(console.error); } store(deploymentName, message) { const timeStamp = new Date().toISOString(); const logMessage = `${timeStamp} - ${deploymentName} | ${message}\n`; if (!fs.existsSync(logFilePath)) { fs.mkdirSync(logFilePath, { recursive: true }); } fs.appendFileSync(logFileFullPath, logMessage, { encoding: 'utf-8' }); } present(deploymentName, workerPID, message) { message = message.trim(); const fixedWidth = 24; let paddedName = deploymentName.padEnd(fixedWidth, ' '); if (deploymentName.length > fixedWidth) { paddedName = deploymentName.substring(0, fixedWidth - 2) + '_1'; } // Regular expression for splitting by '\n', '. ', or ' /' const messageLines = message.split(/(?:\n|\. | \/)/); const coloredName = assignColorToWorker(`${paddedName} |`, workerPID); const formattedMessageLines = messageLines.map(line => `${coloredName} ${line}`); const logMessage = formattedMessageLines.join('\n'); console.log(logMessage); } } const logger = new Logger(); function logProcessOutput(proc, deploymentName) { proc.stdout?.on('data', (data) => { logger.enqueueLog(deploymentName, proc.pid || 0, data.toString()); }); proc.stderr?.on('data', (data) => { logger.enqueueLog(deploymentName, proc.pid || 0, data.toString()); }); } exports.logProcessOutput = logProcessOutput;