UNPKG

@cloud-copilot/iam-collect

Version:

Collect IAM information from AWS Accounts

116 lines 4.52 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (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 () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.conductLogAnalysis = conductLogAnalysis; const fs = __importStar(require("fs")); const path = __importStar(require("path")); function keyToString(k) { return [k.service, k.accountId, k.region, k.sync].join('|'); } function stringToKey(s) { const [service, accountId, region, sync] = s.split('|'); return { service, accountId, region, sync }; } function parseLogs(filePath) { const raw = fs.readFileSync(filePath, 'utf8'); return raw .split('\n') .filter((line) => line.trim().length > 0) .map((line) => JSON.parse(line)); } function analyzeJobs(entries) { const startTimes = new Map(); const finishTimes = new Map(); const fmt = (ts) => new Date(ts); for (const e of entries) { const keyProps = { service: e.service, accountId: e.accountId, region: e.region ?? '', // global jobs will have empty region sync: e.sync }; // only consider entries with a full set of job identifiers if (!keyProps.service || !keyProps.accountId || !keyProps.sync) { continue; } const keyStr = keyToString(keyProps); const when = fmt(e.timestamp); if (e.message.includes('Executing') && e.message.includes('sync')) { // first start time wins if (!startTimes.has(keyStr)) { startTimes.set(keyStr, when); } } else if (e.message.includes('Finished') && e.message.includes('sync')) { finishTimes.set(keyStr, when); } } // 1) Jobs that started but didn't finish const incomplete = Array.from(startTimes.keys()) .filter((k) => !finishTimes.has(k)) .map(stringToKey); // 2) Compute durations for completed jobs const durations = Array.from(startTimes.entries()) .filter(([k]) => finishTimes.has(k)) .map(([k, start]) => { const finish = finishTimes.get(k); const deltaSec = (finish.getTime() - start.getTime()) / 1000; return { ...stringToKey(k), durationSec: deltaSec }; }); return { incomplete, durations }; } /** * Analyze the provided log file for job execution times and incomplete jobs. * * @param logFilePath the path to the log file to analyze * @returns true if all jobs completed successfully, false if there are incomplete jobs */ async function conductLogAnalysis(logFilePath) { const logFile = path.resolve(logFilePath); const entries = parseLogs(logFile); const { incomplete, durations } = analyzeJobs(entries); if (incomplete.length > 0) { console.log('\n🔴 Incomplete Jobs:'); incomplete.forEach((j) => { console.log(` • ${j.service} | ${j.accountId} | ${j.region} | ${j.sync}`); }); } console.log('\n⏱️ Job Durations (seconds):'); durations.forEach((d) => { console.log(` • ${d.service} | ${d.accountId} | ${d.region} | ${d.sync}: ${d.durationSec.toFixed(3)}s`); }); return incomplete.length === 0; } //# sourceMappingURL=analyze.js.map