AWS Lambda无法接收SNS负载报错:KeyError 'alertname'
问题分析:SNS触发Lambda时出现KeyError 'alertname'错误
问题场景
配置Amazon Prometheus通过AWS SNS+Lambda向Microsoft Teams发送告警,直接在Lambda中测试负载时正常,但通过SNS发送相同负载时,Lambda触发KeyError: 'alertname'错误,已确认SNS订阅Lambda的配置正确。
报错信息
[ERROR] KeyError: 'alertname' Traceback (most recent call last): File "/var/task/teams-alerting-lambda.py", line 18, in lambda_handler alertname = message['alertname']
Lambda接收的Event结构
{ 'Records': [ { 'EventSource': 'aws:sns', 'EventVersion': '1.0', 'EventSubscriptionArn': 'ARN', 'Sns': { 'Type': 'Notification', 'MessageId': '', 'TopicArn': 'ARN', 'Subject': None, 'Message': '{ "Records": [ { "Sns": { "Message": "{\"alertname\": \"CPU_ALERT_333\", \"status\": \"firing\", \"host_name\": \"host1\", \"cloud_account_id\": \"1234567890\", \"cloud_region\": \"eu-west-1\", \"summary\": \"High CPU Load\", \"severity\": \"warning\"}" } } ] }', 'Timestamp': 'TIME', 'SignatureVersion': '1', 'Signature': '...', 'SigningCertUrl': 'URL', 'UnsubscribeUrl': 'URL', 'MessageAttributes': {} } } ] }
问题根源
问题出在Lambda代码的解析逻辑,与SNS、测试负载无关:
- 直接测试Lambda时,传入的是最内层包含
alertname的告警JSON,代码能直接取值。 - 通过SNS触发时,告警JSON被多层嵌套:最外层是SNS的Event结构,
Sns.Message是字符串化的JSON,该JSON中又嵌套了一层SNS Records结构,真正的告警内容在最内层的Message字段(仍是字符串化格式)。 - 现有代码直接尝试从
message['alertname']取值,但此时的message是外层SNS消息内容,根本不存在alertname字段。
修复方案
修改Lambda代码,正确解析多层嵌套结构:
import json def lambda_handler(event, context): # 1. 取出外层SNS的Message字符串并解析为JSON sns_outer_msg = event['Records'][0]['Sns']['Message'] sns_outer_json = json.loads(sns_outer_msg) # 2. 取出内层嵌套的告警消息字符串并解析为JSON alert_msg_str = sns_outer_json['Records'][0]['Sns']['Message'] alert_payload = json.loads(alert_msg_str) # 3. 正常获取alertname及其他字段 alertname = alert_payload['alertname'] status = alert_payload['status'] # 后续Teams消息构建及发送逻辑...
额外说明
这种多层嵌套通常是因为告警链路中多了一次SNS转发,导致消息被重复封装。如果是Prometheus直接推送到SNS,正常的SNS Message应该就是最内层的告警JSON,不会有额外的Records嵌套。可检查Prometheus告警规则或Alertmanager配置,确认是否误配置了多层SNS转发。
内容的提问来源于stack exchange,提问作者Epic555
相关产品推荐
相关产品推荐

