Skip to content

Commit

Permalink
feat(ecs-patterns): allow imported IBaseService (#471)
Browse files Browse the repository at this point in the history
The existing logic to get metrics on `BaseService` [is pretty simple](https://github.com/aws/aws-cdk/blob/v2.115.0/packages/aws-cdk-lib/aws-ecs/lib/base/base-service.ts#L1195-L1220) and can probably be lifted up to `IBaseService` upstream (similar [to the change for load balancers](aws/aws-cdk@cb889bc)), but I don't have bandwidth to tackle that right now.

---

_By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license_
  • Loading branch information
echeung-amzn authored Jan 2, 2024
1 parent fadb7b5 commit 3acfd0f
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 29 deletions.
18 changes: 9 additions & 9 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 28 additions & 15 deletions lib/monitoring/aws-ecs-patterns/BaseServiceMetricFactory.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,60 @@
import { BaseService } from "aws-cdk-lib/aws-ecs";
import { DimensionsMap } from "aws-cdk-lib/aws-cloudwatch";
import { IBaseService } from "aws-cdk-lib/aws-ecs";

import { MetricFactory, MetricStatistic } from "../../common";

const EcsNamespace = "AWS/ECS";
const EcsContainerInsightsNamespace = "ECS/ContainerInsights";

/**
* Props to create BaseServiceMetricFactory.
*/
export interface BaseServiceMetricFactoryProps {
readonly service: BaseService;
readonly service: IBaseService;
}

/**
* Metric factory for a base service (parent class for e.g. Fargate and EC2 services).
*/
export class BaseServiceMetricFactory {
protected readonly metricFactory: MetricFactory;
protected readonly service: BaseService;
protected readonly dimensionsMap: DimensionsMap;
/**
* @deprecated This isn't required by cdk-monitoring-constructs anymore; use your own reference.
*/
protected readonly service: IBaseService;

constructor(
metricFactory: MetricFactory,
props: BaseServiceMetricFactoryProps
) {
this.metricFactory = metricFactory;
this.dimensionsMap = {
ClusterName: props.service.cluster.clusterName,
ServiceName: props.service.serviceName,
};
this.service = props.service;
}

metricClusterCpuUtilisationInPercent() {
return this.metricFactory.adaptMetric(
this.service.metricCpuUtilization({
label: "Cluster CPU Utilization",
})
return this.metricFactory.createMetric(
"CPUUtilization",
MetricStatistic.AVERAGE,
"Cluster CPU Utilization",
this.dimensionsMap,
undefined,
EcsNamespace
);
}

metricClusterMemoryUtilisationInPercent() {
return this.metricFactory.adaptMetric(
this.service.metricMemoryUtilization({
label: "Cluster Memory Utilization",
})
return this.metricFactory.createMetric(
"MemoryUtilization",
MetricStatistic.AVERAGE,
"Cluster Memory Utilization",
this.dimensionsMap,
undefined,
EcsNamespace
);
}

Expand All @@ -47,10 +63,7 @@ export class BaseServiceMetricFactory {
"RunningTaskCount",
MetricStatistic.AVERAGE,
"Running Tasks",
{
ServiceName: this.service.serviceName,
ClusterName: this.service.cluster.clusterName,
},
this.dimensionsMap,
undefined,
EcsContainerInsightsNamespace
);
Expand Down
4 changes: 2 additions & 2 deletions lib/monitoring/aws-ecs-patterns/Ec2ServiceMonitoring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
IMetric,
IWidget,
} from "aws-cdk-lib/aws-cloudwatch";
import { Ec2Service } from "aws-cdk-lib/aws-ecs";
import { Ec2Service, IBaseService } from "aws-cdk-lib/aws-ecs";
import {
ApplicationLoadBalancedEc2Service,
NetworkLoadBalancedEc2Service,
Expand Down Expand Up @@ -147,7 +147,7 @@ export interface Ec2ApplicationLoadBalancerMonitoringProps

export interface CustomEc2ServiceMonitoringProps
extends BaseLoadBalancedEc2ServiceMonitoringProps {
readonly ec2Service: Ec2Service;
readonly ec2Service: IBaseService;
readonly loadBalancer?: IApplicationLoadBalancer | INetworkLoadBalancer;
readonly targetGroup?: IApplicationTargetGroup | INetworkTargetGroup;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/monitoring/aws-ecs-patterns/FargateServiceMonitoring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
IMetric,
IWidget,
} from "aws-cdk-lib/aws-cloudwatch";
import { FargateService } from "aws-cdk-lib/aws-ecs";
import { FargateService, IBaseService } from "aws-cdk-lib/aws-ecs";
import {
ApplicationLoadBalancedFargateService,
NetworkLoadBalancedFargateService,
Expand Down Expand Up @@ -147,7 +147,7 @@ export interface FargateApplicationLoadBalancerMonitoringProps

export interface CustomFargateServiceMonitoringProps
extends BaseLoadBalancedFargateServiceMonitoringProps {
readonly fargateService: FargateService;
readonly fargateService: IBaseService;
readonly loadBalancer?: IApplicationLoadBalancer | INetworkLoadBalancer;
readonly targetGroup?: IApplicationTargetGroup | INetworkTargetGroup;
}
Expand Down
28 changes: 27 additions & 1 deletion test/monitoring/aws-ecs-patterns/Ec2ServiceMonitoring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Stack } from "aws-cdk-lib";
import { Template } from "aws-cdk-lib/assertions";
import { InstanceType } from "aws-cdk-lib/aws-ec2";
import { Repository } from "aws-cdk-lib/aws-ecr";
import { Cluster, EcrImage } from "aws-cdk-lib/aws-ecs";
import { Cluster, Ec2Service, EcrImage } from "aws-cdk-lib/aws-ecs";
import {
ApplicationLoadBalancedEc2Service,
NetworkLoadBalancedEc2Service,
Expand Down Expand Up @@ -261,3 +261,29 @@ import { TestMonitoringScope } from "../TestMonitoringScope";
});
}
);

test("snapshot test: with imported service", () => {
const stack = new Stack();

const importedService = Ec2Service.fromEc2ServiceAttributes(
stack,
"ImportedEc2Service",
{
cluster: Cluster.fromClusterArn(
stack,
"ImportedCluster",
"arn:aws:ecs:us-west-2:123456789012:cluster/DummyCluster"
),
serviceName: "DummyService",
}
);

const scope = new TestMonitoringScope(stack, "Scope");
const monitoring = new Ec2ServiceMonitoring(scope, {
ec2Service: importedService,
alarmFriendlyName: "DummyEc2Service",
});

addMonitoringDashboardsToStack(stack, monitoring);
expect(Template.fromStack(stack)).toMatchSnapshot();
});
26 changes: 26 additions & 0 deletions test/monitoring/aws-ecs-patterns/FargateServiceMonitoring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,29 @@ import { TestMonitoringScope } from "../TestMonitoringScope";
});
}
);

test("snapshot test: with imported service", () => {
const stack = new Stack();

const importedService = FargateService.fromFargateServiceAttributes(
stack,
"ImportedEc2Service",
{
cluster: Cluster.fromClusterArn(
stack,
"ImportedCluster",
"arn:aws:ecs:us-west-2:123456789012:cluster/DummyCluster"
),
serviceName: "DummyService",
}
);

const scope = new TestMonitoringScope(stack, "Scope");
const monitoring = new FargateServiceMonitoring(scope, {
fargateService: importedService,
alarmFriendlyName: "DummyFargateService",
});

addMonitoringDashboardsToStack(stack, monitoring);
expect(Template.fromStack(stack)).toMatchSnapshot();
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3acfd0f

Please sign in to comment.