media-exporter-processor
Version:
Media processing API with thumbnail generation and cloud storage
96 lines (95 loc) • 3.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = handler;
const client_cloudwatch_1 = require("@aws-sdk/client-cloudwatch");
const client_ecs_1 = require("@aws-sdk/client-ecs");
const client_sns_1 = require("@aws-sdk/client-sns");
const cloudWatch = new client_cloudwatch_1.CloudWatchClient({});
const ecs = new client_ecs_1.ECSClient({});
const sns = new client_sns_1.SNSClient({});
async function handler(event) {
const BUDGET_LIMIT = parseFloat(process.env.BUDGET_LIMIT || "50");
const WARNING_THRESHOLD = BUDGET_LIMIT * 0.8; // 80% of budget ($40)
const PAUSE_THRESHOLD = BUDGET_LIMIT * 0.9; // 90% of budget ($45)
const clusterName = process.env.CLUSTER_NAME;
const serviceName = process.env.SERVICE_NAME;
const snsTopicArn = process.env.SNS_TOPIC_ARN;
try {
// Get current month's spending
const currentSpending = await getCurrentMonthSpending();
console.log(`💰 Current ECS spending: $${currentSpending.toFixed(2)} / $${BUDGET_LIMIT}`);
if (currentSpending >= PAUSE_THRESHOLD) {
// CRITICAL: Pause service
await pauseService(clusterName, serviceName);
await sendAlert(snsTopicArn, "CRITICAL", currentSpending, "Service automatically paused due to budget limit");
}
else if (currentSpending >= WARNING_THRESHOLD) {
// WARNING: Send alert but don't pause
await sendAlert(snsTopicArn, "WARNING", currentSpending, "Approaching budget limit");
}
return {
statusCode: 200,
body: JSON.stringify({
currentSpending,
budgetLimit: BUDGET_LIMIT,
status: currentSpending >= PAUSE_THRESHOLD
? "PAUSED"
: currentSpending >= WARNING_THRESHOLD
? "WARNING"
: "OK",
}),
};
}
catch (error) {
console.error("Cost monitoring error:", error);
return {
statusCode: 500,
body: JSON.stringify({ error: "Cost monitoring failed" }),
};
}
}
async function getCurrentMonthSpending() {
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const command = new client_cloudwatch_1.GetMetricStatisticsCommand({
Namespace: "AWS/Billing",
MetricName: "EstimatedCharges",
Dimensions: [
{ Name: "Currency", Value: "USD" },
{ Name: "ServiceName", Value: "AmazonECS" },
],
StartTime: startOfMonth,
EndTime: now,
Period: 86400, // Daily
Statistics: ["Maximum"],
});
const response = await cloudWatch.send(command);
const latestDatapoint = response.Datapoints?.slice(-1)[0];
return latestDatapoint?.Maximum || 0;
}
async function pauseService(clusterName, serviceName) {
const command = new client_ecs_1.UpdateServiceCommand({
cluster: clusterName,
service: serviceName,
desiredCount: 0,
});
await ecs.send(command);
console.log(`🚨 SERVICE PAUSED: ${serviceName} scaled to 0 due to budget limit`);
}
async function sendAlert(topicArn, level, amount, message) {
const command = new client_sns_1.PublishCommand({
TopicArn: topicArn,
Subject: `🔔 Media Processor Cost Alert - ${level}`,
Message: `
Cost Alert: ${level}
Current Spending: $${amount.toFixed(2)}
Message: ${message}
Timestamp: ${new Date().toISOString()}
${level === "CRITICAL"
? "⚠️ Service has been automatically paused to prevent further charges."
: ""}
`.trim(),
});
await sns.send(command);
}
//# sourceMappingURL=cost-monitor.js.map