Lambda@Edge 未登录云端请求
Lambda@Edge not logging on cloudfront request
如 Docs 中所述,我为 Viewer Response
的云端触发器设置了 Lambda@edge。
lambda 函数代码:
'use strict';
exports.handler = (event, context, callback) => {
console.log('----EXECUTED------');
const response = event.Records[0].cf.response;
console.log(event.Records[0].cf_response);
callback(null, response);
};
我已经为 Viewer Response
事件适当地设置了触发器。
现在我通过cloudfront发出请求时,必须在cloudwatch中登录,但是没有。
如果我做一个简单的 Test Lambda Function
(使用 Button),它会被正确记录。
这可能是什么问题?
当您部署 Lambda@Edge 函数时,它会部署到世界各地的所有边缘缓存区域,其版本是 Lambda Edge 函数的副本。 Regional edge caches 是主要 AWS 区域和边缘站点的子集。
当用户向最近的 pop/edge 请求时,将调用与边缘缓存区域 关联的 lambda。与这些区域关联的所有 Lambda 日志都将在其 边缘缓存区域 CloudWatch 日志中。
例如:
如果用户访问 us-east-1
区域,则其关联的日志将位于 us-east-1
。
要准确了解您的函数记录的位置(在哪个区域),您可以运行这个 AWS CLI 脚本:
FUNCTION_NAME=function_name_without_qualifiers
for region in $(aws --output text ec2 describe-regions | cut -f 3)
do
for loggroup in $(aws --output text logs describe-log-groups --log-group-name "/aws/lambda/us-east-1.$FUNCTION_NAME" --region $region --query 'logGroups[].logGroupName')
do
echo $region $loggroup
done
done
你必须用你的 lambda@edge 的名称替换“function_name_without_qualifiers”。 Link
希望对您有所帮助。
根据 AWS Documentation 对于 Lambda@Edge 函数:
When you check for the log files, be aware that log files are stored in the Region closest to the location where the function is executed. So if you visit a website from, for example, London, you must change the Region to view the CloudWatch Logs for the London Region.
对于那些也搜索过日志但无法使用@Kannaiyan 提供的脚本找到它们的人。
TL;DR
将此 IAM 角色用于您的 Lambda 函数
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:*:*:log-group:*:*"
]
}
]
}
====
确保您拥有正确的 IAM 角色。如果您先创建 Lambda,然后将其部署到 Lambda@Edge,自动生成的 IAM 角色将仅具有足够的权限将单个区域中的数据记录到以 Lambda 函数命名的日志组中,而使用 Lambda@Edge 意味着它将尝试将不同区域的数据记录到“/aws/lambda/”中。日志组。因此,有必要更改 IAM 角色以允许在不同区域创建日志组和写入访问权限。在 TL;DR 部分,我提供了示例 IAM 角色,但请确保缩小对生产中特定日志组列表的访问范围
根据@yevhenii-hordashnyk 的回答,如果您使用“无服务器”框架,默认情况下它会创建一个仅对执行区域具有日志记录权限的 IAM 用户,并且它被锁定到应用程序名称(不适用于 Edge 函数,因为它们以已安装函数的区域为前缀,因此需要不同的权限。
您必须指定自定义角色,并根据 https://www.serverless.com/framework/docs/providers/aws/guide/iam
将该角色应用于您的函数
请注意以下代码段使用 *
而不是 - Ref: 'AWS::Region'
,以及信任关系中的附加 edgelambda.amazonaws.com
服务。
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- edgelambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: myPolicyName
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow # note that these rights are given in the default policy and are required if you want logs out of your lambda(s)
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- 'Fn::Join':
- ':'
-
- 'arn:aws:logs'
- '*'
- Ref: 'AWS::AccountId'
- 'log-group:/aws/lambda/*:*:*'
By default it does add the `AWSLambdaVPCAccessExecutionRole` policy to the lambda role, but I do not know why it does not create the Log Stream. Maybe I've missed something, but after doing the above, it works now.
如 Docs 中所述,我为 Viewer Response
的云端触发器设置了 Lambda@edge。
lambda 函数代码:
'use strict';
exports.handler = (event, context, callback) => {
console.log('----EXECUTED------');
const response = event.Records[0].cf.response;
console.log(event.Records[0].cf_response);
callback(null, response);
};
我已经为 Viewer Response
事件适当地设置了触发器。
现在我通过cloudfront发出请求时,必须在cloudwatch中登录,但是没有。
如果我做一个简单的 Test Lambda Function
(使用 Button),它会被正确记录。
这可能是什么问题?
当您部署 Lambda@Edge 函数时,它会部署到世界各地的所有边缘缓存区域,其版本是 Lambda Edge 函数的副本。 Regional edge caches 是主要 AWS 区域和边缘站点的子集。
当用户向最近的 pop/edge 请求时,将调用与边缘缓存区域 关联的 lambda。与这些区域关联的所有 Lambda 日志都将在其 边缘缓存区域 CloudWatch 日志中。
例如:
如果用户访问 us-east-1
区域,则其关联的日志将位于 us-east-1
。
要准确了解您的函数记录的位置(在哪个区域),您可以运行这个 AWS CLI 脚本:
FUNCTION_NAME=function_name_without_qualifiers
for region in $(aws --output text ec2 describe-regions | cut -f 3)
do
for loggroup in $(aws --output text logs describe-log-groups --log-group-name "/aws/lambda/us-east-1.$FUNCTION_NAME" --region $region --query 'logGroups[].logGroupName')
do
echo $region $loggroup
done
done
你必须用你的 lambda@edge 的名称替换“function_name_without_qualifiers”。 Link
希望对您有所帮助。
根据 AWS Documentation 对于 Lambda@Edge 函数:
When you check for the log files, be aware that log files are stored in the Region closest to the location where the function is executed. So if you visit a website from, for example, London, you must change the Region to view the CloudWatch Logs for the London Region.
对于那些也搜索过日志但无法使用@Kannaiyan 提供的脚本找到它们的人。
TL;DR
将此 IAM 角色用于您的 Lambda 函数
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:*:*:log-group:*:*"
]
}
]
}
====
确保您拥有正确的 IAM 角色。如果您先创建 Lambda,然后将其部署到 Lambda@Edge,自动生成的 IAM 角色将仅具有足够的权限将单个区域中的数据记录到以 Lambda 函数命名的日志组中,而使用 Lambda@Edge 意味着它将尝试将不同区域的数据记录到“/aws/lambda/”中。日志组。因此,有必要更改 IAM 角色以允许在不同区域创建日志组和写入访问权限。在 TL;DR 部分,我提供了示例 IAM 角色,但请确保缩小对生产中特定日志组列表的访问范围
根据@yevhenii-hordashnyk 的回答,如果您使用“无服务器”框架,默认情况下它会创建一个仅对执行区域具有日志记录权限的 IAM 用户,并且它被锁定到应用程序名称(不适用于 Edge 函数,因为它们以已安装函数的区域为前缀,因此需要不同的权限。
您必须指定自定义角色,并根据 https://www.serverless.com/framework/docs/providers/aws/guide/iam
将该角色应用于您的函数请注意以下代码段使用 *
而不是 - Ref: 'AWS::Region'
,以及信任关系中的附加 edgelambda.amazonaws.com
服务。
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- edgelambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: myPolicyName
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow # note that these rights are given in the default policy and are required if you want logs out of your lambda(s)
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- 'Fn::Join':
- ':'
-
- 'arn:aws:logs'
- '*'
- Ref: 'AWS::AccountId'
- 'log-group:/aws/lambda/*:*:*'
By default it does add the `AWSLambdaVPCAccessExecutionRole` policy to the lambda role, but I do not know why it does not create the Log Stream. Maybe I've missed something, but after doing the above, it works now.