question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Not possible to use alarm with anomaly detector within alarm widget of a Cloudwatch dashboard

See original GitHub issue

Currently 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

  1. 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)
  1. 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:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
oleksii-donohacommented, May 20, 2020

@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 L2 AlarmWidget. Alternative way would be to rewrite entire dashboard logic to CfnDashboard, 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?

0reactions
mrsiejascommented, Apr 2, 2021

Managed to fix it by moving the dimensions from CfnAnomalyDetector construct to CfnAlarm under metrics parameter

            metrics=[
                aws_cloudwatch.CfnAlarm.MetricDataQueryProperty(
                    id='m1',
                    metric_stat=aws_cloudwatch.CfnAlarm.MetricStatProperty(
                        metric=aws_cloudwatch.CfnAlarm.MetricProperty(
                            metric_name=billing_anomaly_detector.metric_name,
                            namespace=billing_anomaly_detector.namespace,
                            dimensions=[
                                aws_cloudwatch.CfnAlarm.DimensionProperty(
                                    name='Currency',
                                    value='USD'
                                )
                            ]
                        ),
                        period=core.Duration.hours(360).to_minutes(),
                        stat='Maximum'
                    )
                ),
Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating a CloudWatch alarm based on anomaly detection
You can create an alarm based on CloudWatch anomaly detection, which analyzes past metric data and creates a model of expected values.
Read more >
Add or remove an alarm widget from a CloudWatch dashboard
Add or remove an alarm widget from a CloudWatch dashboard · In the navigation pane, choose Dashboards, and then choose a dashboard. ·...
Read more >
aws cloudwatch get-insight-rule-report - Fig
This operation returns the time series data collected by a Contributor Insights rule. The data includes the identity and number of contributors to...
Read more >
Create a dashboard & custom widget - Observability
Creating and working with widgets on CloudWatch dashboards which covers all types of widgets, not just custom widgets. Previous. Next.
Read more >
CloudWatch in rusoto_cloudwatch - Rust - Docs.rs
It does not return alarms based on math expressions that use the specified ... Lists the anomaly detection models that you have created...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found