UNPKG

@cloud-carbon-footprint/aws

Version:

The core logic to get cloud usage data and estimate energy and carbon emissions from Amazon Web Services.

130 lines 5.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@cloud-carbon-footprint/core"); const common_1 = require("@cloud-carbon-footprint/common"); const AWSInstanceTypes_1 = require("./AWSInstanceTypes"); const domain_1 = require("../domain"); const ramda_1 = require("ramda"); const ReplicationFactors_1 = require("./ReplicationFactors"); const CostAndUsageTypes_1 = require("./CostAndUsageTypes"); const GLUE_VCPUS_PER_USAGE = 4; const SIMPLE_DB_VCPUS_PER_USAGE = 1; class CostAndUsageReportsRow extends core_1.BillingDataRow { constructor(timestamp, accountId, accountName, region, serviceName, usageType, usageUnit, vCpus, usageAmount, cost, tags) { super({ timestamp, accountId, accountName, region, serviceName, usageType, usageUnit: cleanUsageUnit(usageUnit, serviceName, usageType), vCpus, usageAmount: cleanUsageAmount(usageAmount, usageUnit, serviceName), cost, tags, }); this.vCpuHours = this.getVCpuHours(this.vCpus); this.gpuHours = this.getGpuHours(); this.cloudProvider = 'AWS'; this.instanceType = this.parseInstanceTypeFromUsageType(); this.replicationFactor = this.getReplicationFactor(); } getVCpuHours(vCpuFromReport) { const instanceType = this.extractInstanceTypeFromUsageType(); if (this.serviceName === 'AWSGlue') return GLUE_VCPUS_PER_USAGE * this.usageAmount; if (this.serviceName === 'AmazonSimpleDB') return SIMPLE_DB_VCPUS_PER_USAGE * this.usageAmount; if (this.usageType.includes('Aurora:ServerlessUsage')) return this.usageAmount / 4; if ((0, common_1.containsAny)(['Fargate-vCPU-Hours', 'CPUCredits'], this.usageType)) return this.usageAmount; if ((0, common_1.containsAny)(Object.keys(AWSInstanceTypes_1.BURSTABLE_INSTANCE_BASELINE_UTILIZATION), this.usageType)) { return (this.getBurstableInstanceVCPu(instanceType.split('.', 2).join('.')) * this.usageAmount); } if (!vCpuFromReport) return this.extractVCpuFromInstanceType(instanceType) * this.usageAmount; return vCpuFromReport * this.usageAmount; } getGpuHours() { const instanceType = this.extractInstanceTypeFromUsageType(); return AWSInstanceTypes_1.GPU_INSTANCES_TYPES[instanceType] * this.usageAmount || 0; } extractInstanceTypeFromUsageType() { return this.usageType .split(':') .pop() .replace(/^((db|cache|dax|dms|ml|mq|KernelGateway-ml|.+Kafka)\.)/, ''); } getBurstableInstanceVCPu(instanceType) { return (this.extractVCpuFromInstanceType(instanceType) * (AWSInstanceTypes_1.BURSTABLE_INSTANCE_BASELINE_UTILIZATION[instanceType] / domain_1.AWS_CLOUD_CONSTANTS.AVG_CPU_UTILIZATION_2020)); } extractVCpuFromInstanceType(instanceType) { const [instanceFamily, instanceSize] = instanceType.split('.'); if (this.usageType.includes('Kafka')) return AWSInstanceTypes_1.MSK_INSTANCE_TYPES[`Kafka${this.usageType.split('Kafka').pop()}`]; if (this.serviceName === 'AmazonRedshift') return AWSInstanceTypes_1.REDSHIFT_INSTANCE_TYPES[instanceFamily]?.[instanceSize]?.[0] / 3600; return AWSInstanceTypes_1.EC2_INSTANCE_TYPES[instanceFamily]?.[instanceSize]?.[0]; } parseInstanceTypeFromUsageType() { if (this.usageType.endsWith('xl')) this.usageType = this.usageType.concat('arge'); const prefixes = ['db', 'cache', 'Kafka']; const includesPrefix = prefixes.find((prefix) => this.usageType.includes(prefix)); return includesPrefix ? this.usageType.split((0, ramda_1.concat)(includesPrefix, '.')).pop() : this.usageType.split(':').pop(); } getReplicationFactor() { return ((ReplicationFactors_1.AWS_REPLICATION_FACTORS_FOR_SERVICES[this.serviceName] && ReplicationFactors_1.AWS_REPLICATION_FACTORS_FOR_SERVICES[this.serviceName](this.usageType, this.region)) || ReplicationFactors_1.AWS_REPLICATION_FACTORS_FOR_SERVICES.DEFAULT()); } getComputeProcessors() { if (this.serviceName === 'AWSLambda') { if (this.usageType.endsWith('-ARM')) { return [core_1.COMPUTE_PROCESSOR_TYPES.AWS_GRAVITON_2]; } else { return [core_1.COMPUTE_PROCESSOR_TYPES.UNKNOWN]; } } return (AWSInstanceTypes_1.INSTANCE_TYPE_COMPUTE_PROCESSOR_MAPPING[this.instanceType] || [ core_1.COMPUTE_PROCESSOR_TYPES.UNKNOWN, ]); } getGPUComputeProcessors() { if (this.serviceName === 'AWSLambda') { return [core_1.COMPUTE_PROCESSOR_TYPES.UNKNOWN]; } return (AWSInstanceTypes_1.INSTANCE_TYPE_GPU_PROCESSOR_MAPPING[this.instanceType] || [ core_1.COMPUTE_PROCESSOR_TYPES.UNKNOWN, ]); } } exports.default = CostAndUsageReportsRow; const cleanUsageUnit = (rawUsageUnit, serviceName, usageType) => { if (usageType.includes('Fargate-GB-Hours')) { return CostAndUsageTypes_1.KNOWN_USAGE_UNITS.GB_HOURS; } if (isRedshiftComputeUsage(serviceName, rawUsageUnit)) { return CostAndUsageTypes_1.KNOWN_USAGE_UNITS.HOURS_1; } return rawUsageUnit; }; const isRedshiftComputeUsage = (serviceName, usageUnit) => { return (serviceName === 'AmazonRedshift' && usageUnit === CostAndUsageTypes_1.KNOWN_USAGE_UNITS.SECONDS_1); }; const cleanUsageAmount = (rawUsageAmount, rawUsageUnit, serviceName) => { if (isRedshiftComputeUsage(serviceName, rawUsageUnit)) { return rawUsageAmount / 3600; } return rawUsageAmount; }; //# sourceMappingURL=CostAndUsageReportsRow.js.map