Hey guys,
I don't know if this is a feature request or a gap in the current documentation but I was wondering if it would be possible to create cloudwatch alarms on existing metrics. For example, when creating an ELB with CDK specific metrics come out of the box like: Response times. It would be great to be able to reference an already created cloudwatch metric like:
const myExistingMetric = fn.metricErrors({
namespace: "SomeNameSpace",
metricName: "someMetricName"
});
new Alarm(this, 'CustomeAlarm', {
metric: myExistingMetric,
EvaluationPeriods: 2,
threshold: 1,
Statistic: 'Average',
Period: 300, // five minutes
});
I don't exactly know great error handling mechanisms when those metrics don't exist, but perhaps it would even expose what metrics are available out of the box.
@rix0rrr what do you think?
As far as I understand what you're trying to do, this is possible today. It looks like this:
https://github.com/awslabs/aws-cdk/blob/master/packages/@aws-cdk/aws-cloudwatch/test/integ.alarm-and-dashboard.ts#L16
const metric = new cloudwatch.Metric({
namespace: 'AWS/SQS',
metricName: 'ApproximateNumberOfMessagesVisible',
dimensions: { QueueName: queue.getAtt('QueueName') }
});
new cloudwatch.Alarm(stack, 'Alarm', {
metric,
threshold: 100,
evaluationPeriods: 3,
datapointsToAlarm: 2,
});
Sounds like we need a doc topic on this, @Doug-AWS.
On it.
As far as I can tell, Queue.getAtt('QueueName') no longer exists. I believe it's been replaced by Queue.queueName.
I'm on CDK version 0.24.1.
Even though getAtt() does exist, using queueName would certainly have been better in this particular example. But we probably shouldn't even be using that phrasing.
The question is about adding alarms on arbitrary metrics (apart from the ones that we provide accessor objects for). Feel free to substitute arbitrary/fake dimensions. Here, this will do nicely:
const metric = new cloudwatch.Metric({
namespace: 'MyNamespace',
metricName: 'MyMetric',
dimensions: { MyDimension: 'MyDimensionValue' }
});
Gotcha. I'll create something for you to review by EOD.
Is there any way to import existing metrics so that they can be used when creating alarms? I was thinking of something similar to Vpc.fromLookup.
As I understand it, the approach outlined in Doug's link only works if you know the correct values needed to construct the metric (the namespace, metric name, and dimensions). We have a use case where a dimension of the metric is the ID of the container posting it, and so we cannot predict the dimensions from the CDK code.
It would be ideal if we could do something like:
import {Alarm, Metric, TreatMissingData} from "@aws-cdk/aws-cloudwatch";
import {App, Stack, StackProps} from "@aws-cdk/core";
export class AlarmStack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
const containerErrorMetrics = Metric.importMetrics({ namespace: "MyContainers", metricName: "errors" });
// containerErrorMetrics:
// [
// Metric { namespace: "MyContainers", metricName: "errors", dimensions: { id: "1" } },
// Metric { namespace: "MyContainers", metricName: "errors", dimensions: { id: "2" } },
// ]
containerErrorMetrics.forEach(metric => {
const props = {
metric,
threshold: 1,
evaluationPeriods: 1,
treatMissingData: TreatMissingData.NOT_BREACHING,
};
new Alarm(this, `ContainerErrors${metric.dimensions.id}Alarm`, props);
});
}
}
In the absence of such a method to import existing metrics, the best approach I can think of is to use ListMetrics from the CloudWatch SDK to get the metrics from the account. However, the SDK is async, so the call to ListMetrics (and the subsequent creation of alarms on these metrics) can't be done in a constructor, as a constructor can't be async. Instead, it has to be done in some sort of initalizer method. This feels like it breaks the normal CDK pattern of creating all child resources in the constructor.
Overall, my questions are:
initialize method to our CDK classes?We ended up deciding to create alarms with the CloudWatch SDK when the container is created rather than trying to keep these alarms in our CDK code. Answers to the questions above would still be interesting and potentially valuable others who end up on this thread though.
Most helpful comment
Is there any way to import existing metrics so that they can be used when creating alarms? I was thinking of something similar to
Vpc.fromLookup.As I understand it, the approach outlined in Doug's link only works if you know the correct values needed to construct the metric (the namespace, metric name, and dimensions). We have a use case where a dimension of the metric is the ID of the container posting it, and so we cannot predict the dimensions from the CDK code.
It would be ideal if we could do something like:
In the absence of such a method to import existing metrics, the best approach I can think of is to use
ListMetricsfrom the CloudWatch SDK to get the metrics from the account. However, the SDK is async, so the call toListMetrics(and the subsequent creation of alarms on these metrics) can't be done in a constructor, as a constructor can't be async. Instead, it has to be done in some sort of initalizer method. This feels like it breaks the normal CDK pattern of creating all child resources in the constructor.Overall, my questions are:
initializemethod to our CDK classes?