Not possible to use alarm with anomaly detector within alarm widget of a Cloudwatch dashboard
See original GitHub issueCurrently I cannot find explicit support of anomaly detectors in CW Alarms in CDK, only this related issue: https://github.com/aws/aws-cdk/issues/6562
Issue’s author created SO thread, in which following working snippet can be found:
anomaly_cfnalarm = cw.CfnAlarm(self, "AnomalyAlarm",
actions_enabled=True,
alarm_actions=[slack_topic.topic_arn],
alarm_description="<..>",
alarm_name="AnomalyAlarm",
comparison_operator="LessThanLowerOrGreaterThanUpperThreshold",
datapoints_to_alarm=1,
evaluation_periods=1,
insufficient_data_actions=[slack_topic.topic_arn],
metrics=[
cw.CfnAlarm.MetricDataQueryProperty(
expression="ANOMALY_DETECTION_BAND(m1, 2)",
id="ad1"
),
cw.CfnAlarm.MetricDataQueryProperty(
id="m1",
metric_stat=cw.CfnAlarm.MetricStatProperty(
metric=cw.CfnAlarm.MetricProperty(
metric_name=anomaly_detector.metric_name,
namespace=anomaly_detector.namespace
),
period=core.Duration.minutes(5).to_seconds(),
stat="Sum"
)
)
],
ok_actions=[slack_topic.topic_arn],
threshold_metric_id="ad1",
treat_missing_data="breaching"
)
This code works by itself.
But if we reference this alarm inside AlarmWidget
and add this widget to Dashboard
, then synth passes, but deployment fails.
Reproduction Steps
- Define resources similar to this
anomaly_detector = aws_cloudwatch.CfnAnomalyDetector(
self,
id="Error anomaly detector",
metric_name="Errors",
namespace="AWS/Lambda",
stat="Average",
dimensions=[
aws_cloudwatch.CfnAnomalyDetector.DimensionProperty(
name="FunctionName",
value=some_function.function_name
)
]
)
error_alarm = aws_cloudwatch.CfnAlarm(
self,
id="Error alarm",
metrics=[
aws_cloudwatch.CfnAlarm.MetricDataQueryProperty(
expression="ANOMALY_DETECTION_BAND(m1, 2)",
id="ad1"
),
aws_cloudwatch.CfnAlarm.MetricDataQueryProperty(
id="m1",
metric_stat=aws_cloudwatch.CfnAlarm.MetricStatProperty(
metric=aws_cloudwatch.CfnAlarm.MetricProperty(
metric_name=anomaly_detector.metric_name,
namespace=anomaly_detector.namespace
),
period=300,
stat="Average"
)
)
],
evaluation_periods=2,
threshold_metric_id="ad1",
comparison_operator="GreaterThanUpperThreshold"
)
error_rate_alarm_widget = aws_cloudwatch.AlarmWidget(
alarm=error_alarm,
height=6,
width=6,
title="Collector error rate alarm status",
region=core.Aws.REGION
)
dashboard = aws_cloudwatch.Dashboard(
self,
id="Monitoring dashboard",
dashboard_name="foobar"
)
dashboard.add_widgets(error_rate_alarm_widget)
- Try to deploy
Error Log
The dashboard body is invalid, there are 2 validation errors:
[
{
"dataPath": "/widgets/0/properties",
"message": "The metric widget should have specified a region and a data source or an alarm annotation"
},
{
"dataPath": "/widgets/0/properties",
"message": "Should have required property 'metrics' or 'insightRule'"
}
] (Service: AmazonCloudWatch; Status Code: 400; Error Code: InvalidParameterInput; Request ID: f2fb5110-095b-495e-aeec-7d8db031e65b)
new Dashboard (/tmp/jsii-kernel-fioN2e/node_modules/@aws-cdk/aws-cloudwatch/lib/dashboard.js:38:9)
\_ obj._wrapSandboxCode (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7853:49)
\_ Kernel._wrapSandboxCode (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:8313:20)
\_ Kernel._create (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7853:26)
\_ Kernel.create (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7600:21)
\_ KernelHost.processRequest (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7388:28)
\_ KernelHost.run (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7328:14)
\_ Immediate.setImmediate [as _onImmediate] (../lib/python3.8/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7331:37)
\_ runCallback (timers.js:705:18)
\_ tryOnImmediate (timers.js:676:5)
\_ processImmediate (timers.js:658:5)
Environment
- CLI Version :1.38.0 (build d5fa31f)
- Framework Version:1.38.0
- OS :Linux
- Language :Python
Other
My digging led me to the fact that within JSON document of dashboard body generated by CDK there is no annotation for the alarm: "annotations":{"alarms":[]}
.
If one were to use regular Alarm
, not CfnAlarm
, this field is populated correctly:
..."annotations":{"alarms":["'
- Fn::GetAtt:
- mycoolalarm677232EC
- Arn
- '"]}...
Which leads me to believe that CfnAlarm
is not transformed into annotation the right way.
Ideally Alarm
should support anomaly detection, or if it does - there should be an accessible example.
This is 🐛 Bug Report
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
@rix0rrr
I understand that mixing Cfn and L2 constructs isn’t a good idea. But for this particular functionality (alarm based on anomaly detection) there is no L2 support. One other issue https://github.com/aws/aws-cdk/issues/4569 points user to … using Cfn resources.
But there is no
CfnAlarmWidget
, only L2AlarmWidget
. Alternative way would be to rewrite entire dashboard logic toCfnDashboard
, but writing huge JSON document for dashboard body by hand defeats the purpose of using CDK.I would open feature request to add this functionality to
Alarm
, but it’s been done in https://github.com/aws/aws-cdk/issues/4569 and it was closed.@SomayaB should I open separate feature request issue with this use case?
Managed to fix it by moving the dimensions from CfnAnomalyDetector construct to CfnAlarm under
metrics
parameter