Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse a CloudWatch alert in AWS Lambda Python function

I'm working on Lambda function that will perform several actions based on CloudWatch alerts.

The JSON format of the alerts is:

{
    'SignatureVersion': '1',
    'Timestamp': '2018-03-08T16: 06: 27.163Z',
    'MessageId': 'df82d564-1651-5dc6-a37a-867f779226ec',
    'Message': '{
        "AlarmName": "awsec2-i-08c38bb8af7962797-CPU-Utilization",
        "AlarmDescription": "Created from EC2 Console",
        "AWSAccountId": "111111111111",
        "NewStateValue": "ALARM",
        "NewStateReason": "Threshold Crossed: 1 datapoint [1.49999999999939 (08/03/18 16:04:00)] was greater than or equal to the threshold (1.0).",
        "StateChangeTime": "2018-03-08T16:06:27.124+0000",
        "Region": "EU (Ireland)",
        "OldStateValue": "OK",
        "Trigger": {
            "MetricName": "CPUUtilization",
            "Namespace": "AWS/EC2",
            "StatisticType": "Statistic",
            "Statistic": "AVERAGE",
            "Unit": null,
            "Dimensions": [
                {
                    "name": "InstanceId",
                    "value": "i-08c38bb8af7962797"
                }
            ],
            "Period": 60,
            "EvaluationPeriods": 1,
            "ComparisonOperator": "GreaterThanOrEqualToThreshold",
            "Threshold": 1.0,
            "TreatMissingData": "",
            "EvaluateLowSampleCountPercentile": ""
        }
    }',
    'Type': 'Notification',
    'TopicArn': 'arn:aws:sns:eu-west-1: 11111111111:test',
    'Subject': 'ALARM: "awsec2-i-08c38bb8af7962797-CPU-Utilization" in EU (Ireland)'
}

What I need to understand is how I tell my function to extract only the InstanceId value and use it as variable for the rest of the function.

like image 784
Tomer Leibovich Avatar asked Sep 18 '26 03:09

Tomer Leibovich


1 Answers

The Message is JSON provided as a string. To access the contents of the string, you'll need to use the json.loads() function:

import json

alert = ... (from CloudWatch)

message = json.loads(alert['Message'])

[msg['value'] for msg in message['Trigger']['Dimensions'] if msg['name']=='InstanceId']

However, please note that this will merely output the InstanceId that was provided as the Dimension for the alarm. It is not specifically saying that this instance caused the alarm (but that is true).

For example, you could create an alarm based on a group of EC2 instances. If the average CPU went above a threshold, the alarm would be triggered. However, the dimension would relate to the group, not a specific instance.

Think of it as saying "The Alarm with a filter of Instance i-xxx has been triggered", as opposed to saying "Instance i-xxx triggered the alarm".

As long as your alarm is always based on a single instance, then the Dimension will be what you expect.

like image 98
John Rotenstein Avatar answered Sep 19 '26 19:09

John Rotenstein



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!