#!/usr/bin/env node
// Get 14-day anomaly analysis
const { spawn } = require('child_process');
async function get14DayAnomalyAnalysis() {
console.log('π° 14-DAY AWS ANOMALY COST IMPACT ANALYSIS');
console.log('=' .repeat(58));
console.log('π
Period: August 13, 2025 - August 26, 2025');
const server = spawn('node', ['dist/index.js'], {
stdio: ['pipe', 'pipe', 'pipe'],
env: {
...process.env,
UMBRELLA_API_BASE_URL: 'https://api-front.umbrellacost.io/api/v1'
}
});
const responses = [];
let requestId = 1;
server.stdout.on('data', (data) => {
const lines = data.toString().split('\n').filter(line => line.trim());
for (const line of lines) {
try {
const response = JSON.parse(line);
responses.push(response);
} catch (e) {}
}
});
// Suppress stderr for cleaner output
server.stderr.on('data', () => {});
await new Promise(resolve => setTimeout(resolve, 2000));
// Auth
const authRequest = {
jsonrpc: "2.0",
id: requestId++,
method: "tools/call",
params: {
name: 'authenticate_user',
arguments: {
username: 'david+saola@umbrellacost.com',
password: 'Dsamsung1!'
}
}
};
server.stdin.write(JSON.stringify(authRequest) + '\n');
await new Promise(resolve => setTimeout(resolve, 5000));
// Request 14-day anomaly analysis
console.log('π Requesting 14-day anomaly data...');
const anomaliesRequest = {
jsonrpc: "2.0",
id: requestId++,
method: "tools/call",
params: {
name: 'api___anomaly_detection',
arguments: {
startDate: "2025-08-13",
endDate: "2025-08-26",
isPpApplied: "false"
}
}
};
server.stdin.write(JSON.stringify(anomaliesRequest) + '\n');
// Wait for response with extended timeout for 14 days
let anomaliesResponse = null;
for (let i = 0; i < 60 && !anomaliesResponse; i++) {
await new Promise(resolve => setTimeout(resolve, 1000));
anomaliesResponse = responses.find(r => r.id === 2);
if (i === 15) console.log('β³ Processing 14 days of data...');
if (i === 30) console.log('β³ Still processing...');
if (i === 45) console.log('β³ Almost done...');
}
if (anomaliesResponse && anomaliesResponse.result?.content?.[0]?.text) {
const text = anomaliesResponse.result.content[0].text;
console.log(`β
Response received (${text.length.toLocaleString()} characters)`);
// Parse the JSON response
const jsonMatch = text.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
try {
const data = JSON.parse(jsonMatch[1]);
if (data.anomalies && Array.isArray(data.anomalies)) {
const anomalies = data.anomalies;
console.log('\nπ° 14-DAY ANOMALY COST IMPACT ANALYSIS RESULTS');
console.log('=' .repeat(53));
if (anomalies.length === 0) {
console.log('π No anomalies detected in the last 14 days');
console.log('β
This indicates stable AWS costs during this period');
console.log('\nπ° COST IMPACT: $0.00');
console.log('β
No financial impact from anomalies');
} else {
// Calculate total cost impact
let totalCostImpact = 0;
let totalCurrentCost = 0;
let openAnomalies = 0;
let closedAnomalies = 0;
const serviceBreakdown = {};
const topAnomalies = [];
const dailyBreakdown = {};
anomalies.forEach(anomaly => {
const impact = parseFloat(anomaly.totalCostImpact || anomaly.impact || 0);
const currentCost = parseFloat(anomaly.currentCost || 0);
const service = anomaly.serviceName || 'Unknown Service';
const isOpen = !(anomaly.isClosed || anomaly.is_closed);
const startDate = new Date((anomaly.startTime || 0) * 1000).toISOString().split('T')[0];
totalCostImpact += impact;
totalCurrentCost += currentCost;
if (isOpen) openAnomalies++;
else closedAnomalies++;
// Service breakdown
if (!serviceBreakdown[service]) {
serviceBreakdown[service] = { count: 0, totalImpact: 0, totalCurrentCost: 0 };
}
serviceBreakdown[service].count++;
serviceBreakdown[service].totalImpact += impact;
serviceBreakdown[service].totalCurrentCost += currentCost;
// Daily breakdown
if (!dailyBreakdown[startDate]) {
dailyBreakdown[startDate] = { count: 0, totalImpact: 0 };
}
dailyBreakdown[startDate].count++;
dailyBreakdown[startDate].totalImpact += impact;
// Top anomalies by impact
if (impact > 0 || currentCost > 0) {
topAnomalies.push({
service,
impact,
currentCost,
percentChange: anomaly.percentChange || 0,
accountId: anomaly.accountId || anomaly.linkedAccountId,
status: isOpen ? 'Open' : 'Closed',
startDate,
endDate: anomaly.endDate || 'Ongoing'
});
}
});
// Sort top anomalies by impact
topAnomalies.sort((a, b) => b.impact - a.impact);
// Display results
console.log(`π SUMMARY:`);
console.log(` Total Anomalies: ${anomalies.length.toLocaleString()}`);
console.log(` π Open: ${openAnomalies.toLocaleString()}`);
console.log(` π Closed: ${closedAnomalies.toLocaleString()}`);
console.log(`\nπ° FINANCIAL IMPACT:`);
console.log(` Total Cost Impact: $${totalCostImpact.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`);
console.log(` Total Current Cost: $${totalCurrentCost.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`);
// Daily breakdown
const sortedDays = Object.entries(dailyBreakdown)
.sort((a, b) => b[1].totalImpact - a[1].totalImpact);
if (sortedDays.length > 0) {
console.log(`\nπ
DAILY BREAKDOWN (Top Days):`);
sortedDays.slice(0, 5).forEach(([date, data]) => {
console.log(` ${date}: ${data.count} anomalies, $${data.totalImpact.toLocaleString('en-US', {minimumFractionDigits: 2})} impact`);
});
}
// Top services by cost impact
const topServices = Object.entries(serviceBreakdown)
.map(([service, data]) => ({ service, ...data }))
.sort((a, b) => b.totalImpact - a.totalImpact)
.slice(0, 5);
if (topServices.length > 0) {
console.log(`\nπ TOP SERVICES BY COST IMPACT:`);
topServices.forEach((item, i) => {
console.log(` ${i+1}. ${item.service}`);
console.log(` Impact: $${item.totalImpact.toLocaleString('en-US', {minimumFractionDigits: 2})} | Anomalies: ${item.count}`);
});
}
// Top individual anomalies
if (topAnomalies.length > 0) {
console.log(`\nπ₯ TOP INDIVIDUAL ANOMALIES:`);
topAnomalies.slice(0, 5).forEach((anomaly, i) => {
console.log(` ${i+1}. ${anomaly.service} (${anomaly.status})`);
console.log(` π° Impact: $${anomaly.impact.toLocaleString('en-US', {minimumFractionDigits: 2})}`);
console.log(` π Change: ${anomaly.percentChange.toFixed(1)}%`);
console.log(` π’ Account: ${anomaly.accountId}`);
console.log(` π
Date: ${anomaly.startDate}`);
});
}
// Impact assessment
console.log(`\nπ IMPACT ASSESSMENT:`);
if (totalCostImpact > 5000) {
console.log(`π¨ HIGH IMPACT - Requires immediate attention`);
} else if (totalCostImpact > 1000) {
console.log(`β‘ MODERATE IMPACT - Should be monitored`);
} else if (totalCostImpact > 100) {
console.log(`β οΈ LOW-MODERATE IMPACT - Within acceptable range`);
} else if (totalCostImpact > 0) {
console.log(`β
MINIMAL IMPACT - Normal cost variance`);
}
}
console.log(`\nβ
FINAL ANSWER FOR Q14 (14-day analysis):`);
if (anomalies.length > 0) {
const totalImpact = anomalies.reduce((sum, a) => sum + parseFloat(a.totalCostImpact || a.impact || 0), 0);
console.log(`π° Cost impact in last 14 days: $${totalImpact.toLocaleString('en-US', {minimumFractionDigits: 2})}`);
console.log(`π Based on ${anomalies.length} anomalies across ${Object.keys(serviceBreakdown).length} AWS services`);
} else {
console.log(`π° Cost impact in last 14 days: $0.00`);
console.log(`β
No anomalies = stable costs over 14-day period`);
}
} else {
console.log('β No anomalies array found in response');
}
} catch (e) {
console.log('β JSON parsing error:', e.message);
console.log('First 300 chars of response:');
console.log(text.substring(0, 300));
}
} else {
console.log('β No JSON block found in response');
console.log('Response preview:', text.substring(0, 200));
}
} else {
console.log('β No response received within 60 seconds');
console.log(`Total responses: ${responses.length}`);
if (responses.length > 0) {
console.log('Available response IDs:', responses.map(r => r.id));
}
}
server.kill();
}
get14DayAnomalyAnalysis().catch(console.error);