Lambda@Edge 未登录云端请求
Posted
技术标签:
【中文标题】Lambda@Edge 未登录云端请求【英文标题】:Lambda@Edge not logging on cloudfront request 【发布时间】:2018-03-12 04:50:59 【问题描述】:正如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
(使用按钮),它会被正确记录。
这里可能是什么问题?
【问题讨论】:
您应该会发现它正在记录在您当前访问的 CloudFront 边缘站点所在的 AWS 区域,该区域应该是您所在位置附近的区域。测试总是记录到 us-east-1 而不是真实的流量。您还可以将response.headers['x-lambda-region'] = [ key: 'X-Lambda-Region', value: process.env.AWS_REGION ];
添加到您的代码中(在回调之前),如果您的触发器成功运行,您将看到一个X-Lambda-Region
标头已添加到响应中,告诉您处理您的请求涉及哪个区域.你的想法?
【参考方案1】:
当您部署 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
您必须将“function_name_without_qualifiers”替换为您的 lambda@edge 的名称。 Link
希望对你有帮助。
【讨论】:
谢谢...实际上在配置 cloudfront 时我设置了Price Class Use Only US, Canada and Europe
,我最近的 Edge 是 Asia Pacific (Mumbai)
但它实际上是在 EU (Frankfurt)
上。谢谢
哇,花了半天时间寻找那些日志......只是发现这个 SO 帖子作为第一个谷歌搜索结果。谢谢!
只是在这上面浪费了一天时间。谢谢!!!另一个重要的问题是您只能在 us-east-1 区域中定义 lambda@edge 函数,但它们可以在任何云端发行版上触发。
我进行了 2 次编辑以使其今天能够正常工作。一种是将cut -3
更改为cut -4
,另一种是将硬编码的us-east-1 从日志组名称中删除。它不是我的日志组名称的一部分。所有这些都完成了,我仍然没有得到任何日志。我看到了我的测试运行日志,但 CloudFront 没有做任何事情。【参考方案2】:
对于那些也搜索过日志但使用@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 角色,但请确保缩小对生产中特定日志组列表的访问范围
【讨论】:
救了我一整天!谢谢! 如果您的角色承担 AWSLambdaBasicExecutionRole,您应该获得这些权限。【参考方案3】:根据 AWS Documentation 的 Lambda@Edge 函数:
当您检查日志文件时,请注意日志文件存储在距离函数执行位置最近的区域中。因此,如果您从伦敦等地访问网站,则必须更改区域以查看伦敦区域的 CloudWatch 日志。
【讨论】:
【参考方案4】:根据@yevhenii-hordashnyk 的回答,如果您使用“无服务器”框架,默认情况下它会创建一个仅对执行区域具有日志记录权限的 IAM 用户,并且它被锁定为应用程序名称(这不会适用于 Edge 函数,因为它们以已安装函数的区域为前缀,因此需要不同的权限。
您必须指定一个自定义角色,并根据https://www.serverless.com/framework/docs/providers/aws/guide/iam将该角色应用于您的函数
请注意,以下 sn-p 使用 *
而不是 - 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.
【讨论】:
以上是关于Lambda@Edge 未登录云端请求的主要内容,如果未能解决你的问题,请参考以下文章