You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:08:28