Search code examples
amazon-web-servicesamazon-elastic-beanstalkamazon-cloudwatchcloudwatch-alarms

How to setup cloudwatch alarm for beanstalk environment memory


I'm trying to setup the Cloudwatch Alarm for memory on all instances of an AWS Elastic Beanstalk environment. I've setup capability to get Memory usage on Cloudwatch using the following tutorial:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-cw.html

Now I want to setup an alarm that would trigger if the MemoryUtilization of any of these instances go beyond a certain threshold. I can select all and setup alert on each of those separately, but I want to make sure that even if Beanstalk scales up the cluster or swaps an instance, the alert doesn't have to be reconfigured.

Is there a way I can setup alarm for a condition where Instance Name = "env-name" and Metric is MemoryUtilization?


Solution

  • What I understand from your question are the following requirements:

    1. You have multiple metrics and want to use a logical OR condition when configuring an alarm, e.g. (avg metric1 > x || avg metric2 > y) ==> set alarm state to ALARM
    2. You want the alarm to consider new metrics as they become available when new instances are launched by elastic beanstalk during scale out.
    3. You want old metrics to not be considered as soon as elastic beanstalk scales in.

    I think this is currently not possible.
    There is an ongoing discussion on aws discussion forums [1] which reveals that at least (1) is possible using Metric Math. The Metric Math feature supports max. 10 metrics.

    Solution

    What you need to do is, to create a single metric which transports the information whether the alarm should be triggered or not ('computed metric'). There are multiple ways to achieve this:

    • For complex metrics you could write a bash script and run it on an EC2 instance using cron. The script would first query existing metrics using a dimension filter ('list-metrics'), then gather each metric ('get-metric-data'), aggregate it and then push the computed metric data point ('put-metric-data').
    • If the metric is rather simple, you could try the aggregate option of the AWS put-metric-data script [2]:
    option_settings:
      "aws:elasticbeanstalk:customoption" :
        CloudWatchMetrics : "--mem-util --mem-used --mem-avail --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ --auto-scaling --aggregated"
    

    The documentation for the aggregated option says:

    Adds aggregated metrics for instance type, AMI ID, and overall for the region.

    References

    [1] https://forums.aws.amazon.com/thread.jspa?threadID=94984
    [2] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/mon-scripts.html#put-metric-data