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 未登录云端请求的主要内容,如果未能解决你的问题,请参考以下文章

无法为Google云端硬盘创建令牌目录

有没有办法让云端发送单个资源和任何路径/路由的默认根对象?

如何添加 CloudFront 作为 lambda 函数的触发器?

避免使用云端未签名图像上传自动上传?

Google云端硬盘未显示目录中的所有文件

未找到 Google 云端硬盘页面 - 抱歉,目前无法打开文件