#!/usr/bin/env node
const { spawn } = require('child_process');
async function getAccurateCloudWatchData() {
console.log('π― GETTING ACCURATE CLOUDWATCH DATA FROM API');
console.log('Retrieving real daily costs for last 30 days');
console.log('=' .repeat(70));
const server = spawn('node', ['dist/index.js'], {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: process.cwd(),
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) {}
}
});
// Show authentication progress
server.stderr.on('data', (data) => {
const message = data.toString();
if (message.includes('Successfully authenticated')) {
console.log('β
Authentication successful');
} else if (message.includes('API REQUEST') || message.includes('API RESPONSE')) {
console.log('π‘ API call in progress...');
}
});
console.log('π Starting server...');
await new Promise(resolve => setTimeout(resolve, 3000));
console.log('π Authenticating...');
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, 6000));
const authResponse = responses.find(r => r.id === authRequest.id);
if (!authResponse?.result?.content?.[0]?.text?.includes('Successfully authenticated')) {
console.log('β Authentication failed');
server.kill();
return;
}
console.log('π Requesting CloudWatch data for last 30 days...');
console.log(' Period: 2025-07-27 to 2025-08-26');
console.log(' Parameters: service grouping, daily granularity, amortized costs');
const costRequest = {
jsonrpc: "2.0",
id: requestId++,
method: "tools/call",
params: {
name: 'api___invoices_caui',
arguments: {
startDate: "2025-07-27",
endDate: "2025-08-26",
costType: ["cost", "discount"],
periodGranLevel: "day",
groupBy: "service",
isAmortized: true,
accountId: "932213950603"
}
}
};
server.stdin.write(JSON.stringify(costRequest) + '\n');
console.log('β³ Waiting for API response...');
// Wait longer and check more frequently
let responseReceived = false;
const maxWaitTime = 60; // 60 seconds
for (let seconds = 0; seconds < maxWaitTime && !responseReceived; seconds++) {
await new Promise(resolve => setTimeout(resolve, 1000));
const costResponse = responses.find(r => r.id === costRequest.id);
if (costResponse) {
responseReceived = true;
console.log('β
API response received!');
if (costResponse.result?.content?.[0]?.text) {
const text = costResponse.result.content[0].text;
console.log(`π Response length: ${text.length} characters`);
const jsonMatch = text.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
try {
const data = JSON.parse(jsonMatch[1]);
console.log(`π Total API records: ${data.length}`);
// Filter for CloudWatch
const cloudwatchRecords = data.filter(item => {
const serviceName = (item.service_name || '').toLowerCase();
return serviceName === 'amazoncloudwatch';
});
console.log(`π CloudWatch records found: ${cloudwatchRecords.length}\n`);
if (cloudwatchRecords.length === 0) {
console.log('β No CloudWatch data found in API response');
// Show first few services for debugging
const sampleServices = [...new Set(data.slice(0, 10).map(item => item.service_name))]
.filter(s => s);
console.log('π Sample services in response:');
sampleServices.slice(0, 8).forEach(service => {
console.log(` - ${service}`);
});
server.kill();
return;
}
// Extract daily costs
const dailyCloudWatchCosts = {};
let grandTotal = 0;
cloudwatchRecords.forEach(record => {
const date = record.usage_date.split('T')[0]; // Get YYYY-MM-DD
const cost = parseFloat(record.total_cost) || 0;
dailyCloudWatchCosts[date] = cost;
grandTotal += cost;
});
// Sort and display
const sortedDates = Object.keys(dailyCloudWatchCosts).sort();
console.log('ποΈ ACCURATE DAILY CLOUDWATCH COSTS (FROM API):');
console.log('='.repeat(60));
sortedDates.forEach((date, index) => {
const cost = dailyCloudWatchCosts[date];
const dateObj = new Date(date + 'T12:00:00Z');
const dayName = dateObj.toLocaleDateString('en-US', { weekday: 'short' });
const monthDay = dateObj.toLocaleDateString('en-US', {
month: 'short',
day: '2-digit'
});
console.log(`${String(index + 1).padStart(2)}. ${monthDay} (${dayName}): $${cost.toFixed(2)}`);
});
console.log('='.repeat(60));
console.log(`π° TOTAL CLOUDWATCH (${sortedDates.length} days): $${grandTotal.toFixed(2)}`);
// Calculate statistics
const costs = Object.values(dailyCloudWatchCosts);
const avgDaily = grandTotal / sortedDates.length;
const maxCost = Math.max(...costs);
const minCost = Math.min(...costs);
const maxDate = sortedDates.find(date => dailyCloudWatchCosts[date] === maxCost);
const minDate = sortedDates.find(date => dailyCloudWatchCosts[date] === minCost);
console.log(`\nπ ACCURATE STATISTICS:`);
console.log(` Average daily: $${avgDaily.toFixed(2)}`);
console.log(` Highest day: $${maxCost.toFixed(2)} (${new Date(maxDate).toLocaleDateString('en-US', { month: 'short', day: '2-digit' })})`);
console.log(` Lowest day: $${minCost.toFixed(2)} (${new Date(minDate).toLocaleDateString('en-US', { month: 'short', day: '2-digit' })})`);
console.log(` Daily range: $${(maxCost - minCost).toFixed(2)}`);
console.log(` Standard deviation: $${calculateStdDev(costs).toFixed(2)}`);
// Verify this is exactly 30 days
if (sortedDates.length === 30) {
console.log(`\nβ
CONFIRMED: Exactly 30 days of data retrieved`);
} else {
console.log(`\nβ οΈ Note: Retrieved ${sortedDates.length} days (not exactly 30)`);
}
} catch (parseError) {
console.log(`β JSON parsing error: ${parseError.message}`);
console.log('Raw response preview (first 500 chars):');
console.log(text.substring(0, 500));
}
} else {
console.log('β No JSON data block found in API response');
console.log('Response preview (first 300 chars):');
console.log(text.substring(0, 300));
}
} else if (costResponse.error) {
console.log('β API Error:');
console.log(JSON.stringify(costResponse.error, null, 2));
} else {
console.log('β Empty response from API');
}
break;
}
// Progress indicator
if (seconds % 10 === 0 && seconds > 0) {
console.log(`β³ Still waiting... (${seconds}/${maxWaitTime}s)`);
}
}
if (!responseReceived) {
console.log(`β API request timed out after ${maxWaitTime} seconds`);
console.log(`π Total responses received: ${responses.length}`);
}
server.kill();
}
// Helper function to calculate standard deviation
function calculateStdDev(values) {
const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
const squaredDiffs = values.map(val => Math.pow(val - mean, 2));
const avgSquaredDiff = squaredDiffs.reduce((sum, val) => sum + val, 0) / values.length;
return Math.sqrt(avgSquaredDiff);
}
getAccurateCloudWatchData().catch(console.error);