UNPKG

@cloud-carbon-footprint/aws

Version:

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

142 lines (130 loc) 3.48 kB
/* * © 2021 Thoughtworks, Inc. */ import { GetCostAndUsageCommandInput, GetCostAndUsageCommandOutput, } from '@aws-sdk/client-cost-explorer' import { ServiceWithCPUUtilization, ComputeUsage, Cost, } from '@cloud-carbon-footprint/core' import { getComputeUsage } from './ComputeUsageMapper' import { RDS_INSTANCE_TYPES } from './AWSInstanceTypes' import { ServiceWrapper } from './ServiceWrapper' import { getCostFromCostExplorer } from './CostMapper' import { GetMetricDataCommandInput } from '@aws-sdk/client-cloudwatch' export default class RDSComputeService extends ServiceWithCPUUtilization { serviceName = 'rds' constructor(private readonly serviceWrapper: ServiceWrapper) { super() } async getUsage( start: Date, end: Date, region: string, ): Promise<ComputeUsage[]> { const metricDataResponses = await this.getCpuUtilization(start, end) const costAndUsageResponses = await this.getTotalVCpusByDate( start.toISOString().substr(0, 10), end.toISOString().substr(0, 10), region, ) return getComputeUsage( metricDataResponses, costAndUsageResponses, RDS_INSTANCE_TYPES, ) } private async getCpuUtilization(start: Date, end: Date) { const params: GetMetricDataCommandInput = { StartTime: start, EndTime: end, MetricDataQueries: [ { Id: 'cpuUtilizationWithEmptyValues', Expression: "SEARCH('{AWS/RDS} MetricName=\"CPUUtilization\"', 'Average', 3600)", ReturnData: false, }, { Id: 'cpuUtilization', Expression: 'REMOVE_EMPTY(cpuUtilizationWithEmptyValues)', }, ], ScanBy: 'TimestampAscending', } return await this.serviceWrapper.getMetricDataResponses(params) } private async getTotalVCpusByDate( startDate: string, endDate: string, region: string, ): Promise<GetCostAndUsageCommandOutput[]> { const params: GetCostAndUsageCommandInput = { TimePeriod: { Start: startDate, End: endDate, }, Filter: { And: [ { Dimensions: { Key: 'REGION', Values: [region], }, }, { Dimensions: { Key: 'USAGE_TYPE_GROUP', Values: ['RDS: Running Hours'], }, }, ], }, Granularity: 'DAILY', GroupBy: [ { Key: 'USAGE_TYPE', Type: 'DIMENSION', }, ], Metrics: ['UsageQuantity'], } return await this.serviceWrapper.getCostAndUsageResponses(params) } async getCosts(start: Date, end: Date, region: string): Promise<Cost[]> { const params: GetCostAndUsageCommandInput = { TimePeriod: { Start: start.toISOString().substr(0, 10), End: end.toISOString().substr(0, 10), }, Filter: { And: [ { Dimensions: { Key: 'REGION', Values: [region], }, }, { Dimensions: { Key: 'USAGE_TYPE_GROUP', Values: ['RDS: Running Hours'], }, }, ], }, Granularity: 'DAILY', GroupBy: [ { Key: 'USAGE_TYPE', Type: 'DIMENSION', }, ], Metrics: ['AmortizedCost'], } return getCostFromCostExplorer(params, this.serviceWrapper) } }