Lambda@Edge未在Cloudfront请求上记录日志

48

文档 所述,我为Viewer Response的CloudFront触发器设置了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中,但实际上并没有。
如果我使用按钮进行简单的测试Lambda函数,则可以正确记录。

这里可能出了什么问题?


7
你应该会发现日志被记录在当前 CloudFront 边缘位置所在的 AWS 区域,这个区域应该靠近你所在的位置。测试总是记录在 us-east-1,但不是真实的流量。你也可以在代码中(回调之前)添加 response.headers['x-lambda-region'] = [{ key: 'X-Lambda-Region', value: process.env.AWS_REGION }]; ,如果你的触发器成功运行,你会看到一个 X-Lambda-Region 标头已经添加到响应中,告诉你参与处理请求的区域。你有什么想法? - Michael - sqlbot
5个回答

77

当您部署Lambda@Edge函数时,该函数会被部署到全球各个边缘缓存区域,并具有Lambda@Edge函数的版本副本。 区域边缘缓存是主要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”。链接

希望对你有所帮助。


1
谢谢...实际上在配置CloudFront时,我设置了“价格级别仅使用美国、加拿大和欧洲”,而我的最近的边缘位置是“亚太地区(孟买)”,但实际上它却连接到了“欧洲(法兰克福)”。谢谢。 - formatkaka
7
哇,花了半天的时间寻找那些日志......结果发现这个 Stack Overflow 的帖子是谷歌搜索结果的第一个。谢谢! - Paweł Gościcki
2
刚刚在这个问题上浪费了一整天。另一个重要的注意点是,你只能在us-east-1地区定义lambda@edge函数,但它们可以在任何CloudFront分发上触发。谢谢! - Berty
9
今天我进行了两次编辑以使其运作。一次是将 cut -3 改为 cut -4,另一次是移除硬编码的 us-east-1 日志组名称。对于我来说,它不是日志组名称的一部分。虽然这些都已完成,但我仍未收到任何日志。我可以看到我的测试运行的日志,但 CloudFront 没有做任何事情。 - jiggy
1
这让我疯狂了数小时,当我最终找到这篇文章并惊呼“哦我的天”,我仍然在苦苦挣扎,假设我位于瑞典南部,距离斯德哥尔摩500公里,但距离700公里的法兰克福似乎更受欢迎。AWS在调试边缘Lambda时确实可以改善用户体验。 - JHH
显示剩余3条评论

32

对于那些也在搜索日志但无法使用@Kannaiyan提供的脚本找到它们的人。

简而言之,为您的Lambda函数使用此IAM角色。

{
"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角色,但请确保在生产环境中缩小访问范围到特定的日志组列表。


2
如果您的角色假定AWSLambdaBasicExecutionRole,则应获得这些权限。 - Doug
1
这是我的原因。我先创建了一个 Lambda 函数(使用控制台),然后将其添加到 CloudFront 作为 lambda@edge,因此它的区域是 us-east-1,因此在边缘位置没有创建日志组。 - Rajeev
对我来说和Rajeev一样。 - Russell Keane

10
根据AWS Lambda@Edge函数的文档

当您查看日志文件时,请注意日志文件存储在执行函数的位置最接近的区域中。因此,如果您从伦敦等地访问网站,则必须更改区域以查看伦敦区域的CloudWatch日志。


7
Lambda@Edge的日志以及请求执行的区域可以在AWS CloudFront控制台中找到,尽管路径比较复杂,而且AWS在记录步骤方面做得非常糟糕。
以下是本文发布时可行的步骤:
1. 进入AWS CloudFront控制台。 2. 在“遥测”部分下点击“监控”链接(不要点击“日志”,那会带你进入CloudFront日志)。 3. 点击“Lambda@Edge”选项卡。 4. 选择您的Lambda函数,然后单击“查看指标”按钮。
然后,您可以使用“调用”图表来确定特定Lambda函数调用在哪个区域执行。一旦您知道了区域,就可以最终使用“查看函数日志”下拉菜单查看特定区域的Lambda函数日志。
我通过长时间在控制台中挖掘才弄清楚这个问题。关于这个日志记录的“文档”在这里,但似乎没有解释如何实际找到特定区域的Lambda@Edge日志。
如果有人找到了适当的文档,请更新帖子。

2

如果您使用“无服务器”框架,它会默认创建一个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.

谢谢,这终于解决了我的日志问题! - Steffen Abel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接