Skip to main content
Glama
get-30day-anomaly-analysis.cjsβ€’8.11 kB
#!/usr/bin/env node // Get the actual 30-day anomaly analysis with proper handling const { spawn } = require('child_process'); async function get30DayAnomalyAnalysis() { console.log('πŸ’° 30-DAY AWS ANOMALY COST IMPACT ANALYSIS'); console.log('=' .repeat(60)); console.log('πŸ“… Period: July 27, 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; let responseComplete = false; 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); if (response.id === 2) { // Our anomaly request responseComplete = true; console.log('βœ… Anomaly response received!'); } } 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 30-day anomaly analysis console.log('πŸ” Requesting 30-day anomaly data...'); const anomaliesRequest = { jsonrpc: "2.0", id: requestId++, method: "tools/call", params: { name: 'api___anomaly_detection', arguments: { startDate: "2025-07-27", endDate: "2025-08-26", isPpApplied: "false" } } }; server.stdin.write(JSON.stringify(anomaliesRequest) + '\n'); // Wait for the response with extended timeout console.log('⏳ Processing large dataset (this may take 2-3 minutes)...'); let waitTime = 0; while (!responseComplete && waitTime < 300) { // 5 minutes max await new Promise(resolve => setTimeout(resolve, 5000)); waitTime += 5; if (waitTime % 30 === 0) { console.log(`⏳ Still processing... ${waitTime}s elapsed`); } } const anomaliesResponse = responses.find(r => r.id === 2); 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πŸ’° 30-DAY ANOMALY COST IMPACT ANALYSIS RESULTS'); console.log('=' .repeat(55)); // Calculate total cost impact let totalCostImpact = 0; let totalCurrentCost = 0; let openAnomalies = 0; let closedAnomalies = 0; const serviceBreakdown = {}; const topAnomalies = []; 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); 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; // Top anomalies by impact if (impact > 0) { topAnomalies.push({ service, impact, currentCost, percentChange: anomaly.percentChange || 0, accountId: anomaly.accountId || anomaly.linkedAccountId, status: isOpen ? 'Open' : 'Closed', startDate: new Date((anomaly.startTime || 0) * 1000).toISOString().split('T')[0], 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})}`); // Top 5 services by cost impact const topServices = Object.entries(serviceBreakdown) .map(([service, data]) => ({ service, ...data })) .sort((a, b) => b.totalImpact - a.totalImpact) .slice(0, 5); console.log(`\nπŸ† TOP 5 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 5 individual anomalies console.log(`\nπŸ”₯ TOP 5 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(` πŸ“… Period: ${anomaly.startDate} β†’ ${anomaly.endDate}`); }); console.log(`\nβœ… FINAL ANSWER FOR Q14:`); console.log(`πŸ’° The cost impact of AWS anomalies in the last 30 days is:`); console.log(` $${totalCostImpact.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`); if (totalCostImpact > 10000) { console.log(`⚠️ HIGH IMPACT - Requires immediate attention`); } else if (totalCostImpact > 1000) { console.log(`⚑ MODERATE IMPACT - Should be monitored`); } else { console.log(`βœ… LOW IMPACT - Within acceptable variance`); } } else { console.log('❌ No anomalies array found in response'); } } catch (e) { console.log('❌ JSON parsing error:', e.message); console.log('First 500 chars of response:'); console.log(text.substring(0, 500)); } } else { console.log('❌ No JSON block found in response'); } } else { console.log('❌ No response received or timeout'); console.log(`Responses received: ${responses.length}`); } server.kill(); } get30DayAnomalyAnalysis().catch(console.error);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server