AWS 电子邮件错误是否可以通过多个 Lambda 函数记录到 CloudWatch?
Can AWS email errors logged to CloudWatch by multiple Lambda functions?
我在 AWS Lambda 中有许多函数,由 CloudWatch Rules 在各种定期计划中调用。如果他们的节点 JavaScript 遇到错误,则会记录到 CloudWatch 日志组。
- 根据 this doc,我可以创建一个 CloudWatch 简单通知服务 (SNS) 来给我发电子邮件。
- 根据 this doc,我可以创建一个 CloudWatch 指标来计算单词
ERROR
在单个日志组中的出现次数。
- 根据 this doc,我可以创建一个 CloudWatch 警报,它在观察到单个指标时使用 SNS 向我发送电子邮件。
这两个投诉中的一个或两个可以通过这些工具解决,还是应该使用其他工具?
- 收到的电子邮件是通用的。它可以包含错误消息吗?
- 这仅适用于一个 Lambda 函数的一个日志组。它可以配置为适用于多个 Lambda 函数的日志组吗?我的多个 Lambda 函数是否可以配置为记录到一个共享的日志组?或者我是否需要为每个 Lambda 函数创建一对指标和警报?
TL;DR this 是您可能正在寻找的解决方案架构。
(来源:亚马逊)
Can my multiple Lambda functions be configured to log to a single, shared Log Group?
没有。然而,即使您可以将所有 lambda 日志记录到一个日志组,这也是非常不可取的。
但是,您可以将多个日志组流式传输到一个目标中。例如,这通常用于 centralized logging 解决方案。
would I need to create a pair of Metrics and Alarms for each Lambda function?
这可能是最直接的方法。使用 CloudFormation(或相关工具、AWS CDK、Terraform 等),您可以通过创建 lambda 函数来自动执行此设置。
The received email is generic. Can it include the error message?
不容易。 CloudWatch 警报事件源不会包含对导致计数指标进入警报的日志的任何引用,因此这不会起作用。通常,当您收到此类警报时,您会使用其他服务来查找错误(例如 xray、cloudwatch 日志等)。例如,您的消息可能只包含一个 link 到 CloudWatch metric/alarm。在 CloudWatch 中,应该有一个 'view logs' 按钮提供指标时间范围的日志。请参阅:从指标转向日志
如果您确实需要将错误包含在通知中,则需要不同的解决方案架构。例如,您可以 stream 您的 CloudWatch 事件到 Lambda 函数,该函数将处理事件并发送通知,包括来自流的错误消息。
参见:使用订阅实时处理日志数据
和 如何使用 CloudWatch 获得有关特定 Lambda 函数错误模式的通知
其中包含有关在通知中获取错误消息的完整指南。
this answer 部分告知了一个类似的问题,以及 trial/error 和谁知道其他谷歌搜索,我最终放弃了 AWS Metrics 和 AWS Alarms,而是使用了一个新的 Lambda由任意数量的 select 日志组触发的函数。我保留了 SNS 功能,如果您拥有自己的电子邮件域,这将非常容易设置。
创建新的 Lambda 函数后,会显示搜索蓝图的选项,搜索 log
会产生(以及其他选项)cloudwatch-logs-process-data
蓝图。它也可以从头开始创建,因为它的代码只是这样:
const zlib = require('zlib');
exports.handler = async (event, context) => {
const payload = Buffer.from(event.awslogs.data, 'base64');
const parsed = JSON.parse(zlib.gunzipSync(payload).toString('utf8'));
console.log('Decoded payload:', JSON.stringify(parsed));
return `Successfully processed ${parsed.logEvents.length} log events.`;
};
然后我选择它作为多个触发器我希望监视的日志组,将它们的过滤器模式设置为单词 ERROR
,并将它们的过滤器名称设置为我想要的电子邮件主题。
使用蓝图中的控制台日志,我创建了一个这种格式的测试事件:
{
"awslogs": {
"data": "LONG_STRING_OF_ENCODED_CHARACTERS_FROM_ABOVE_CONSOLE_LOG_HERE"
}
}
我根据自己的喜好修改了蓝图代码:
const zlib = require('zlib');
const aws = require('aws-sdk');
const ses = new aws.SES({ region: '<some-region-1>' });
exports.handler = async function (event) {
const payload = Buffer.from(event.awslogs.data, 'base64');
const parsed = JSON.parse(zlib.gunzipSync(payload).toString('utf8'));
const bodyText = JSON.stringify(parsed, null, 2).replace(/\n/g, ' \\n ').replace(/\t/g, '\\n ');
console.log('bodyText:', bodyText);
var params = {
Source: '<some_email@example.com>',
Destination: {
ToAddresses: ['<some_email@example.com>'],
},
Message: {
Subject: { Data: parsed.subscriptionFilters[0] },
Body: {
Text: { Data: bodyText },
},
},
};
return ses.sendEmail(params).promise();
};
它有效,如果 Lambda 函数记录错误,我会立即收到一封电子邮件(我的每月 AWS 账单也没有明显增加)。
更新后的通过 ses 发送电子邮件的 lambda 将运行良好。但是,必须使用必要的权限更新 Lambda 角色。见文章:
https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/
我已添加到默认 lambda 角色以使其正常工作的策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail",
"logs:CreateLogGroup"
],
"Resource": [
"arn:aws:logs:your-region-1:xxxaccountidxxxx:*",
"arn:aws:ses:*:xxxaccountidxxxx:configuration-set/*",
"arn:aws:ses:your-region-1:xxxaccountidxxxx:identity/your@email.com"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:ses:your-region-1:xxxaccountidxxxx:identity/your@email.com",
"arn:aws:logs:your-region-1:xxxaccountidxxxx:log-group:/aws/lambda/yourlambdaname:*"
]
}
]
}
否则报错:
code": "AccessDenied",
"message": "User `arn:aws:sts::xxxx:assumed-role/zzz/yyyy' is not authorized to perform `ses:SendEmail' on resource `arn:aws:ses:us-east-1:xxxxx:identity/<your@email.com>'"
我在 AWS Lambda 中有许多函数,由 CloudWatch Rules 在各种定期计划中调用。如果他们的节点 JavaScript 遇到错误,则会记录到 CloudWatch 日志组。
- 根据 this doc,我可以创建一个 CloudWatch 简单通知服务 (SNS) 来给我发电子邮件。
- 根据 this doc,我可以创建一个 CloudWatch 指标来计算单词
ERROR
在单个日志组中的出现次数。 - 根据 this doc,我可以创建一个 CloudWatch 警报,它在观察到单个指标时使用 SNS 向我发送电子邮件。
这两个投诉中的一个或两个可以通过这些工具解决,还是应该使用其他工具?
- 收到的电子邮件是通用的。它可以包含错误消息吗?
- 这仅适用于一个 Lambda 函数的一个日志组。它可以配置为适用于多个 Lambda 函数的日志组吗?我的多个 Lambda 函数是否可以配置为记录到一个共享的日志组?或者我是否需要为每个 Lambda 函数创建一对指标和警报?
TL;DR this 是您可能正在寻找的解决方案架构。
(来源:亚马逊)
Can my multiple Lambda functions be configured to log to a single, shared Log Group?
没有。然而,即使您可以将所有 lambda 日志记录到一个日志组,这也是非常不可取的。
但是,您可以将多个日志组流式传输到一个目标中。例如,这通常用于 centralized logging 解决方案。
would I need to create a pair of Metrics and Alarms for each Lambda function?
这可能是最直接的方法。使用 CloudFormation(或相关工具、AWS CDK、Terraform 等),您可以通过创建 lambda 函数来自动执行此设置。
The received email is generic. Can it include the error message?
不容易。 CloudWatch 警报事件源不会包含对导致计数指标进入警报的日志的任何引用,因此这不会起作用。通常,当您收到此类警报时,您会使用其他服务来查找错误(例如 xray、cloudwatch 日志等)。例如,您的消息可能只包含一个 link 到 CloudWatch metric/alarm。在 CloudWatch 中,应该有一个 'view logs' 按钮提供指标时间范围的日志。请参阅:从指标转向日志
如果您确实需要将错误包含在通知中,则需要不同的解决方案架构。例如,您可以 stream 您的 CloudWatch 事件到 Lambda 函数,该函数将处理事件并发送通知,包括来自流的错误消息。
参见:使用订阅实时处理日志数据 和 如何使用 CloudWatch 获得有关特定 Lambda 函数错误模式的通知 其中包含有关在通知中获取错误消息的完整指南。
this answer 部分告知了一个类似的问题,以及 trial/error 和谁知道其他谷歌搜索,我最终放弃了 AWS Metrics 和 AWS Alarms,而是使用了一个新的 Lambda由任意数量的 select 日志组触发的函数。我保留了 SNS 功能,如果您拥有自己的电子邮件域,这将非常容易设置。
创建新的 Lambda 函数后,会显示搜索蓝图的选项,搜索 log
会产生(以及其他选项)cloudwatch-logs-process-data
蓝图。它也可以从头开始创建,因为它的代码只是这样:
const zlib = require('zlib');
exports.handler = async (event, context) => {
const payload = Buffer.from(event.awslogs.data, 'base64');
const parsed = JSON.parse(zlib.gunzipSync(payload).toString('utf8'));
console.log('Decoded payload:', JSON.stringify(parsed));
return `Successfully processed ${parsed.logEvents.length} log events.`;
};
然后我选择它作为多个触发器我希望监视的日志组,将它们的过滤器模式设置为单词 ERROR
,并将它们的过滤器名称设置为我想要的电子邮件主题。
使用蓝图中的控制台日志,我创建了一个这种格式的测试事件:
{
"awslogs": {
"data": "LONG_STRING_OF_ENCODED_CHARACTERS_FROM_ABOVE_CONSOLE_LOG_HERE"
}
}
我根据自己的喜好修改了蓝图代码:
const zlib = require('zlib');
const aws = require('aws-sdk');
const ses = new aws.SES({ region: '<some-region-1>' });
exports.handler = async function (event) {
const payload = Buffer.from(event.awslogs.data, 'base64');
const parsed = JSON.parse(zlib.gunzipSync(payload).toString('utf8'));
const bodyText = JSON.stringify(parsed, null, 2).replace(/\n/g, ' \\n ').replace(/\t/g, '\\n ');
console.log('bodyText:', bodyText);
var params = {
Source: '<some_email@example.com>',
Destination: {
ToAddresses: ['<some_email@example.com>'],
},
Message: {
Subject: { Data: parsed.subscriptionFilters[0] },
Body: {
Text: { Data: bodyText },
},
},
};
return ses.sendEmail(params).promise();
};
它有效,如果 Lambda 函数记录错误,我会立即收到一封电子邮件(我的每月 AWS 账单也没有明显增加)。
更新后的通过 ses 发送电子邮件的 lambda 将运行良好。但是,必须使用必要的权限更新 Lambda 角色。见文章: https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/
我已添加到默认 lambda 角色以使其正常工作的策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail",
"logs:CreateLogGroup"
],
"Resource": [
"arn:aws:logs:your-region-1:xxxaccountidxxxx:*",
"arn:aws:ses:*:xxxaccountidxxxx:configuration-set/*",
"arn:aws:ses:your-region-1:xxxaccountidxxxx:identity/your@email.com"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:ses:your-region-1:xxxaccountidxxxx:identity/your@email.com",
"arn:aws:logs:your-region-1:xxxaccountidxxxx:log-group:/aws/lambda/yourlambdaname:*"
]
}
]
}
否则报错:
code": "AccessDenied",
"message": "User `arn:aws:sts::xxxx:assumed-role/zzz/yyyy' is not authorized to perform `ses:SendEmail' on resource `arn:aws:ses:us-east-1:xxxxx:identity/<your@email.com>'"