AWS 事件总线无法将日志写入来自 AWS Lambda 的自定义日志组上的 CloudWatch

Posted

技术标签:

【中文标题】AWS 事件总线无法将日志写入来自 AWS Lambda 的自定义日志组上的 CloudWatch【英文标题】:AWS Event Bus fails to write logs to CloudWatch on a custom log group from AWS Lambda 【发布时间】:2021-06-01 12:10:32 【问题描述】:

我有一个 AWS lambda,它的工作是使用来自外部源的日志并将这些日志写入自定义 CloudWatch 日志组。请注意,这个 lambda 已经将日志写入它自己的日志组,这不是我的问题。我想要的是将外部派生的日志写入另一个 CloudWatch 组。

按照 AWS 文档并使用 CloudFormation,我创建了一个事件总线和一个针对 CloudWatch 的规则:

redacted

为了清楚起见,我省略了大部分 CloudFormation 模板,只留下看起来相关的部分。

我发现 Lambda 接收日志(通过 Kinesis)、处理它们并将它们发送到下面代码 sn-p 中的事件总线:

redacted

上面最后一行表示将事件发送到事件总线:

redacted

但是,我相信事件总线收到了事件,并没有将事件发送到 CloudWatch。即使我手动创建日志组:$AWS::StackName-form-log-batch-function(我将堆栈引用作为参数保留以保持匿名性)。

我检查了 CloudFormation 的创建并且所有资源都存在(由 Lambda 确认,当它尝试发送事件时没有遇到任何异常)。

有人明白我在这里缺少什么吗?

【问题讨论】:

【参考方案1】:

只需创建一个名为/aws/events/<yourgroupname>loggroup,它就可以正常工作并设置logs:*

【讨论】:

【参考方案2】:

我希望这对仍在寻找答案的其他人有所帮助。

问题#1 我希望 Cloudformation 正常工作

您可以使用来自https://serverlessland.com/patterns/eventbridge-cloudwatch 或terraform 的云形成

问题#2 为什么 EventBridge 通常无法写入 Cloudwatch 日志

就像上面所说的,为了让 aws 事件桥写入 cloudwatch,需要有一个资源策略(在目标上设置的策略,在本例中为 Cloudwatch 日志)。不过请注意

如果您在控制台中创建 cloudwatch 日志目标,则会为您自动生成资源策略,但自动生成的策略有一个 Twist
    
        "Version": "2012-10-17",
        "Statement":
        [
            
                "Sid": "TrustEventsToStoreLogEvent",
                "Effect": "Allow",
                "Principal":
                
                    "Service":
                    [
                        "events.amazonaws.com",
                        "delivery.logs.amazonaws.com"
                    ]
                ,
                "Action":
                [
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": "arn:aws:logs:us-east-1:777777777:log-group:/*:*"
            
        ]
    

您会注意到资源采用 /*:* 的形式 这意味着如果您要使用自动生成的日志组,则日志组必须以 / 开头。 因此,如果您的日志组不是 /event/myloggroup/ 格式,那么该策略将无法帮助您。

例如

Target Log Group Name ARN Does it work?
event-bridge-rule2 arn:aws:logs:us-east-1:281458815962:log-group:event-bridge-rule2:* Note the arn is missing starting /
/aws/events/helpme arn:aws:logs:us-east-1:281458815962:log-group:/aws/events/helpme:* Works like a charm

我的建议是制定一项对您有意义的政策,而不是依赖自动政策。

【讨论】:

【参考方案3】:

无法使用您的 WebLogsEventBusLoggingRole 角色写入 CloudWatch Logs (CWL)。正如AWS docs 解释的那样,您必须使用基于 CWL 资源的权限:

当 CloudWatch Logs 是规则的目标时,EventBridge 会创建日志流,而 CloudWatch Logs 将来自触发事件的文本存储为日志条目。要允许 EventBridge 创建日志流并记录事件,CloudWatch Logs 必须包含基于资源的策略,以使 EventBridge 能够写入 CloudWatch Logs。

遗憾的是,您无法从 vanila CloudFormation (CFN) 设置此类权限。这是不支持

AWS::Events::Rule targetting Cloudwatch logs

要从 CFN 执行此操作,您必须以 lambda 函数的形式创建 custom resource。该函数将使用 AWS SDK 设置 CWL 权限。

【讨论】:

非常感谢您的回答。它肯定会澄清事情,我现在将放弃这种方法。我想如果我让它触发一个自定义资源 lambda,正如你所建议的,那么我可能只是让它在其默认的 cloudwatch 日志组下写入日志。这将满足我的要求,因为它将处理它的 lambda 的日志记录与记录原始条目的 lambda 分开。 @MichaelCoxon 没问题。您还可以将 lambda 写入 cloudwatch 日志。因此,不是将日志数据推送到 EventBridge 女巫写入 CWL,您可能有一个 lambda 作为目标,它执行写入 CWL。 是的,问题在于处理事件的日志组和表示事件本身的日志组之间没有区别。否则,我会让原始 lambda 直接记录事件。我想要一个单独的日志组,不要将它与处理器混淆。

以上是关于AWS 事件总线无法将日志写入来自 AWS Lambda 的自定义日志组上的 CloudWatch的主要内容,如果未能解决你的问题,请参考以下文章

如何定义AWS MetricFilter FilterPattern以匹配CloudWatch中的JSON格式的日志事件?

无法将 s3 与来自 aws lambda 的 ec2 文件夹同步

AWS CloudWatch Logs Stream - 如何配置 awslogs 以将每天新的日志流从同一实例写入同一日志组?

使用 AWS SDK 为事件桥规则添加 AWS Lambda 作为目标

AWS 弹性搜索。禁止/8/索引写入 (api)。无法写入索引

AWS CloudWatch 中的指标、日志和事件之间有啥区别? [关闭]