Skip to main content
 首页 » 编程设计

Python之AWS Lambda 从 JSON 输入中提取 key

2025年05月04日22xxx_UU

我正在尝试实现一个函数,该函数将从 cloudwatch 获取事件并打印结果。我能够获得该事件,但我想从该 JSON 中提取一个特定的 key 。

这是我的功能:

import json 
    def lambda_handler(event, context): 
        print("Received event: " + json.dumps(event, indent=2))  
        message = event['Records'][0]['Sns']['Message'] 
        print(message) 

从 Cloudwatch 获取的事件:

"Records": [ 
{ 
"EventVersion": "1.0",  
"EventSubscriptionArn": "arn:aws:sns:us-east-1:xxxxxxxxxxxxx:bhuvi:XXXXXXXXXXXXXXXXXXXXXXXXXX",  
"EventSource": "aws:sns",  
"Sns": { 
"SignatureVersion": "1",  
"Timestamp": "2018-01-13T19:18:44.369Z",  
"Signature": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",  
"SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem",  
"MessageId": "4b76b0ea-5e0f-502f-81ec-e23e03dbaf01",  
"Message": "{\"AlarmName\":\"test\",\"AlarmDescription\":\"test\",\"AWSAccountId\":\"xxxxxxxxxxxxx\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 out of the last 1 datapoints [2.6260535333900545 (13/01/18 19:13:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).\",\"StateChangeTime\":\"2018-01-13T19:18:44.312+0000\",\"Region\":\"US East (N. Virginia)\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"CPUUtilization\",\"Namespace\":\"AWS/RDS\",\"StatisticType\":\"Statistic\",\"Statistic\":\"AVERAGE\",\"Unit\":null,\"Dimensions\":[{\"name\":\"DBInstanceIdentifier\",\"value\":\"myrds\"}],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":1.0,\"TreatMissingData\":\"\",\"EvaluateLowSampleCountPercentile\":\"\"}}",  
"MessageAttributes": 
{} 
,  
"Type": "Notification",  
"UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?xcsgagrgrwgwrg",  
"TopicArn": "arn:aws:sns:us-east-1:xxxxxxxxxxxxx:bhuvi",  
"Subject": "ALARM: \"test\" in US East (N. Virginia)" 
} 
} 
] 
} 

我的提取命令(Upto message)及其结果:

message = event['Records'][0]['Sns']['Message'] 
        print(message) 

结果

{ 
    "AlarmName": "test", 
    "AlarmDescription": "test", 
    "AWSAccountId": "xxxxxxxxxxxxx", 
    "NewStateValue": "ALARM", 
    "NewStateReason": "Threshold Crossed: 1 out of the last 1 datapoints [2.6260535333900545 (13/01/18 19:13:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).", 
    "StateChangeTime": "2018-01-13T19:18:44.312+0000", 
    "Region": "US East (N. Virginia)", 
    "OldStateValue": "OK", 
    "Trigger": { 
        "MetricName": "CPUUtilization", 
        "Namespace": "AWS/RDS", 
        "StatisticType": "Statistic", 
        "Statistic": "AVERAGE", 
        "Unit": null, 
        "Dimensions": [ 
            { 
                "name": "DBInstanceIdentifier", 
                "value": "myrds" 
            } 
        ], 
        "Period": 300, 
        "EvaluationPeriods": 1, 
        "ComparisonOperator": "GreaterThanOrEqualToThreshold", 
        "Threshold": 1, 
        "TreatMissingData": "", 
        "EvaluateLowSampleCountPercentile": "" 
    } 

我想从此消息 Pane 中提取一些值。

例如:我想提取名称。所以我尝试了下面的命令,但不幸的是它不起作用。谁可以帮我这个事?

我的代码:

message = event['Records'][0]['Sns']['Message']['Trigger']['Dimensions']['name'] 
    print(message) 

错误:

{ 
  "stackTrace": [ 
    [ 
      "/var/task/lambda_function.py", 
      14, 
      "lambda_handler", 
      "message = event['Records'][0]['Sns']['Message']['Trigger']['Dimensions']['name']" 
    ] 
  ], 
  "errorType": "TypeError", 
  "errorMessage": "string indices must be integers" 
} 

请您参考如下方法:

所以有3个问题:

问题 1:在您的示例事件中,['Records'][0]['Sns']['Message'] 是一个 str JSON 格式。这意味着您需要像这样解析一个字典:

 message = event['Records'][0]['Sns']['Message'] 
 message = json.loads(message) 

问题 2:message['Trigger']['Dimensions'] 是一个 list 但您正在尝试访问它,就像这是一个 dict。所以你只需要将代码更改为:

message = message['Trigger']['Dimensions'][0]['name'] 

问题 3: Message 是一个 str,这意味着您需要验证它是一个普通的 str或 json str(否则您将遇到多种结构和类型的问题)。为此,您的代码可能如下所示:

 message = event['Records'][0]['Sns']['Message'] 
    if isinstance(message, str): 
        try: 
            message = json.loads(message) 
        except Exception as e: 
            print(e) # Or do nothing, this is just to log the error 
    elif isinstance(message, list): 
        message = message[0] 
    # Maybe evaluate bool, tuple, etc other types 
 
    print('RESPONSE', message['Trigger']['Dimensions'][0]['name'] if isinstance(message, dict) else message) 

不过,我还建议让它更可扩展地迭代您知道的元素 list。出于安全原因(尽量避免空指针异常),请使用具有默认值的 get() 函数。 http://www.tutorialspoint.com/python/dictionary_get.htm .尝试创建一个函数来解析结构并使其可重用。

祝你好运!