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

如何使CloudWatch触发的SNS告警邮件包含具体日志内容?

解决CloudWatch SNS告警邮件缺少实际日志内容的问题

Hey Abdul, 我之前也碰到过一模一样的困扰!默认的CloudWatch Alarm触发SNS后,邮件里只有告警状态变更的干巴巴信息,完全看不到到底是哪条日志触发了告警。下面是几种亲测有效的解决方案,你可以根据自己的场景选:

方法1:EventBridge + Lambda + SNS(最灵活,适配现有Alarm流程)

如果你想保留现有的Metric Filter + Alarm流程,只需要在告警触发后补全日志内容,这个方法最合适:

  • 第一步:创建处理日志的Lambda函数
    写一个简单的Lambda函数,当收到Alarm触发的事件时,去CloudWatch Logs拉取匹配关键词的日志条目,然后把内容组装成邮件格式发送到SNS。这里给你一个Python示例:

    import boto3
    import json
    from datetime import datetime
    
    def lambda_handler(event, context):
        logs_client = boto3.client('logs')
        sns_client = boto3.client('sns')
    
        # 从EventBridge事件中提取告警信息
        alarm_details = event['detail']
        alarm_name = alarm_details['alarmName']
        # 从告警的维度里获取日志组(如果你的Metric Filter关联了日志组维度的话)
        log_group_name = next(dim['value'] for dim in alarm_details['configuration']['metrics'][0]['metricStat']['metric']['dimensions'] if dim['name'] == 'LogGroupName')
    
        # 拉取触发告警前后5分钟的日志(可根据需求调整时间范围)
        end_time = datetime.now().timestamp() * 1000
        start_time = end_time - 300 * 1000  # 5分钟前
    
        # 过滤匹配关键词的日志
        log_events = logs_client.filter_log_events(
            logGroupName=log_group_name,
            startTime=int(start_time),
            endTime=int(end_time),
            filterPattern="你的关键词"  # 和Metric Filter的规则一致
        )
    
        # 组装告警邮件内容
        message = f"🚨 CloudWatch告警触发:{alarm_name}\n\n"
        message += f"告警时间:{datetime.fromtimestamp(end_time/1000).strftime('%Y-%m-%d %H:%M:%S')}\n"
        message += f"匹配到的日志内容:\n\n"
    
        for log in log_events['events']:
            log_time = datetime.fromtimestamp(log['timestamp']/1000).strftime('%Y-%m-%d %H:%M:%S')
            message += f"[{log_time}] {log['message']}\n\n"
    
        # 发送到SNS主题
        sns_client.publish(
            TopicArn='你的SNS主题ARN',
            Subject=f"CloudWatch告警:{alarm_name}(含日志详情)",
            Message=message
        )
    
        return {'statusCode': 200, 'body': json.dumps('告警邮件已发送')}
    
  • 第二步:配置EventBridge规则
    新建一个EventBridge规则,触发源选择「CloudWatch Alarms」,事件类型选「Alarm State Change」,设置当告警状态变为ALARM时触发,目标选择刚才创建的Lambda函数。

  • 第三步:给Lambda配置权限
    别忘了给Lambda角色添加logs:FilterLogEvents和sns:Publish的权限,不然它没法读取日志和发送邮件。

方法2:直接用CloudWatch Logs订阅过滤器跳过Alarm

如果你的需求只是“出现关键词就告警”,不需要Alarm的阈值判断(比如匹配次数超过N次才告警),可以直接跳过Alarm,用订阅过滤器触发Lambda:

  • 打开你的CloudWatch日志组,创建「订阅过滤器」,目标选择Lambda,过滤模式填你的关键词。
  • Lambda函数里直接处理收到的日志事件,组装成邮件发送到SNS。这种方式更直接,延迟更低。

注意事项

  • 如果日志量比较大,要处理好Lambda的分页逻辑(filter_log_events会返回nextToken,需要循环拉取所有匹配的日志)。
  • 可以根据需求调整日志的时间范围,比如拉取告警触发前后10分钟的日志,确保不会遗漏关键信息。
  • 邮件里可以添加更多上下文,比如日志组名称、告警的触发阈值等,让告警信息更完整。

内容的提问来源于stack exchange,提问作者Abdul Salam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:36:56