本篇博文演示了如何使用 Amazon CloudWatch 日志订阅自动发出针对特定 AWS Lambda 函数错误的警报通知。 CloudWatch Logs 允许您在日志条目与模式匹配时调用 Lambda 函数。 Amazon CloudWatch 警报用于在 Lambda 函数发生错误时发出通知; 此通知不会提供有关错误的任何详细信息。对于您需要具体说明通知中的错误的情况,您可以使用 CloudWatch Logs 订阅。 CloudWatch Logs 订阅可让您可以将日志中的条目与特定错误模式相匹配,并收到这些错误详细信息的通知。 这将为您节省额外的步骤来分析日志并采取必要的操作。您还可以将其用作蓝图,以便在 Lambda 函数中检测到错误模式时构建自动反应式措施。
这篇文章将引导您了解如何配置触发 AWS Lambda 函数来处理日志的 CloudWatch 日志订阅。 Lambda 函数使用 Amazon SNS 发送包含特定错误详细信息和日志位置的电子邮件。
解决方案概述
![](https://s3---cn-north-1.amazonaws.com.rproxy.goskope.com.cn/awschinablog/how-to-get-notified-on-specific-lambda-function-er1.png)
该解决方案的架构相当简单。 您拥有一堆 Lambda 函数,并且希望收到有关其特定严重错误的通知。 CloudWatch Logs 从这些 Lambda 函数中捕获日志。 当日志条目与过滤模式匹配时,它会调用“错误处理”Lambda 函数,例如,ERROR、CRITICAL 或自定义错误。 此错误处理 Lambda 函数反过来将消息发布到 Amazon SNS 主题,当错误发生时可以订阅该主题以获取电子邮件。
出于本文的演示目的,我们将使用以下示例错误生成 Lambda 函数:
import logging
import os
logging.basicConfig(level=logging.DEBUG)
logger=logging.getLogger(__name__)
def lambda_handler(event, context):
logger.setLevel(logging.DEBUG)
logger.debug("This is a sample DEBUG message.. !!")
logger.error("This is a sample ERROR message.... !!")
logger.info("This is a sample INFO message.. !!")
logger.critical("This is a sample 5xx error message.. !!")
部署教程
先决条件
要实施此解决方案,您必须创建:
- SNS 话题
- IAM 角色
- 一个 Lambda 函数
- CloudWatch 日志触发器
步骤 1:创建 SNS 主题
要创建 SNS 主题,请完成以下步骤:
- 打开 Amazon SNS 控制台。
- 在左侧导航窗格中,选择主题。
- 选择创建主题。 对于主题名称,输入名称并选择创建主题。 您现在可以看到 MySNSTopic 页面。 详细信息部分显示主题的名称、ARN、显示名称(可选)和主题所有者的 AWS 账户 ID。
- 在详细信息部分中,将主题 ARN 复制到剪贴板,例如:arn:aws:sns:us-east-1:123456789012:MySNSTopic
- 在左侧导航窗格中,选择订阅和创建订阅。
- 在创建订阅页面上,执行以下操作:
- 输入您之前创建的主题的主题 ARN:arn:aws:sns:us-east-1:123456789012:MySNSTopic
- 在协议中,选择电子邮件。
- 在终端节点中,输入可以接收通知的电子邮件地址。
- 选择创建订阅。
- 请注意,对于电子邮件订阅,您必须通过单击您将通过电子邮件收到的确认订阅链接来确认订阅。 确认订阅后,您就可以接收电子邮件通知了。
步骤 2:创建 IAM 角色
要创建 IAM 角色,请完成以下步骤。 有关更多信息,请参阅创建 IAM 角色。
- 在IAM 控制台中,从左侧导航窗格中选择策略,然后选择创建策略。
- 选择 JSON 选项卡并输入以下 IAM 策略,将主题 ARN 替换为您在上一步中创建的 SNS 主题 ARN:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:<partition>:sns:<region>:<AWS account number>:<name of the SNS topic from previous step>"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:<partition>:logs:<region>:<AWS account number>:log-group:/aws/lambda/<name of the lambda function you are going to create in next step>:*"
}
]
}
JSON
- 选择审查政策。
- 输入此策略的名称 (MyCloudWatchRole),然后选择创建策略。 记下此策略的名称以供后续步骤使用。
- 在左侧导航窗格中,选择角色,然后选择创建角色。
- 在选择角色类型页面上,选择 AWS 服务作为您的受信任实体,然后在常见用例下选择 Lambda。
- 选择下一步:权限。
- 按您刚刚创建的策略名称过滤策略,然后选中该复选框。
- 选择下一步:标签,并给它一个适当的标签。
- 选择下一步:查看。 给这个 IAM 角色一个适当的名称,并记下它以备将来使用。
- 选择创建角色。
步骤 3:创建 Lambda 函数
要创建 Lambda 函数,请完成以下步骤。 有关更多信息,请参阅使用控制台创建 Lambda 函数。
- 在 Lambda 控制台中,选择从头开始创作。
- 对于”函数名称”,请输入函数的名称。
- 对于”运行时”,请选择”Python 3.7″。
- 对于执行角色,选择使用现有角色,然后选择在上一步中创建的 IAM 角色。
- 选择”创建函数”,删除默认函数,然后将以下代码复制到”函数代码”窗口中:
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at## http://aws.amazon.com/apache2.0/
# or in the "license" file accompanying this file.
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions
# and limitations under the License.
# Description: This Lambda function sends an email notification to a given AWS SNS topic when a particular
# pattern is matched in the logs of a selected Lambda function. The email subject is
# Execution error for Lambda-<insert Lambda function name>.
# The JSON message body of the SNS notification contains the full event details.
# Author: Sudhanshu Malhotra
import base64
import boto3
import gzip
import json
import logging
import os
from botocore.exceptions import ClientError
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def logpayload(event):
logger.setLevel(logging.DEBUG)
logger.debug(event['awslogs']['data'])
compressed_payload = base64.b64decode(event['awslogs']['data'])
uncompressed_payload = gzip.decompress(compressed_payload)
log_payload = json.loads(uncompressed_payload)
return log_payload
def error_details(payload):
error_msg = ""
log_events = payload['logEvents']
logger.debug(payload)
loggroup = payload['logGroup']
logstream = payload['logStream']
lambda_func_name = loggroup.split('/')
logger.debug(f'LogGroup: {loggroup}')
logger.debug(f'Logstream: {logstream}')
logger.debug(f'Function name: {lambda_func_name[3]}')
logger.debug(log_events)
for log_event in log_events:
error_msg += log_event['message']
logger.debug('Message: %s' % error_msg.split("\n"))
return loggroup, logstream, error_msg, lambda_func_name
def publish_message(loggroup, logstream, error_msg, lambda_func_name):
sns_arn = os.environ['snsARN'] # Getting the SNS Topic ARN passed in by the environment variables.
snsclient = boto3.client('sns')
try:
message = ""
message += "\nLambda error summary" + "\n\n"
message += "##########################################################\n"
message += "# LogGroup Name:- " + str(loggroup) + "\n"
message += "# LogStream:- " + str(logstream) + "\n"
message += "# Log Message:- " + "\n"
message += "# \t\t" + str(error_msg.split("\n")) + "\n"
message += "##########################################################\n"
# Sending the notification...
snsclient.publish(
TargetArn=sns_arn,
Subject=f'Execution error for Lambda - {lambda_func_name[3]}',
Message=message
)
except ClientError as e:
logger.error("An error occured: %s" % e)
def lambda_handler(event, context):
pload = logpayload(event)
lgroup, lstream, errmessage, lambdaname = error_details(pload)
publish_message(lgroup, lstream, errmessage, lambdaname)
Python
6. 在环境变量部分,输入以下键值对:
-
Key= snsARN
Value= the ARN of the MySNSTopic created earlier
7. 选择保存。
步骤 4. 创建 CloudWatch 日志触发器
- 要添加触发器,请选择添加触发器,然后从下拉列表中选择 CloudWatch 日志。
- 在日志组下,选择您希望从中获得错误通知的 Lambda 函数的 CloudWatch 日志组名称。 在我们的示例中,这将是上面讨论的示例错误生成 Lambda 函数的日志组。
- 为过滤器名称输入适当的值,然后在过滤器模式下,输入您想要通知的日志的过滤器值。 例如 – “?ERROR ?WARN ?5xx” 将过滤日志中的 ERROR、WARN 或 5xx 等术语。 日志过滤器和模式语法文档包含更多其他复杂模式的示例。
![](https://s3---cn-north-1.amazonaws.com.rproxy.goskope.com.cn/awschinablog/how-to-get-notified-on-specific-lambda-function-er2.png)
4. 启用触发器,然后添加。
解决方案验证
为了验证我的解决方案,我将运行示例错误生成 Lambda 函数并过滤“?ERROR ?WARN ?5xx”模式以获取电子邮件通知,如下所示:
![](https://s3---cn-north-1.amazonaws.com.rproxy.goskope.com.cn/awschinablog/how-to-get-notified-on-specific-lambda-function-er3.png)
同样,我可以为任何特定错误创建过滤模式,例如,如图所示的错误 5xx,并仅针对该错误消息获得以下通知:
![](https://s3---cn-north-1.amazonaws.com.rproxy.goskope.com.cn/awschinablog/how-to-get-notified-on-specific-lambda-function-er4.png)
![](https://s3---cn-north-1.amazonaws.com.rproxy.goskope.com.cn/awschinablog/how-to-get-notified-on-specific-lambda-function-er5.png)
清理
为避免持续产生费用,请删除在前面的步骤中创建的资源,包括 CloudWatch Events 规则、Lambda 函数和 SNS 主题。
总结
本篇文章演示了如何使用 CloudWatch Log 过滤器来解析 Lambda 函数的日志并获取有关该特定错误的电子邮件通知。 如需进一步阅读,请参阅:
本篇作者