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 作为目标