我正在尝试实现一个函数,该函数将从 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 .尝试创建一个函数来解析结构并使其可重用。
祝你好运!
