AWS Event Bus 无法将来自 AWS Lambda 的自定义日志组上的日志写入 CloudWatch
AWS Event Bus fails to write logs to CloudWatch on a custom log group from AWS Lambda
我有一个 AWS lambda,它的工作是使用来自外部源的日志并将这些日志写入自定义 CloudWatch 日志组。请注意,此 lambda 已将日志写入其自己的日志组,这不是我的问题。我想要的是将外部派生的日志写入另一个 CloudWatch 组。
根据 AWS 文档并使用 CloudFormation,我创建了一个事件总线和一个针对 CloudWatch 的规则:
redacted
为了清楚起见,我省略了大部分 CloudFormation 模板,只留下看起来相关的部分。
我发现 Lambda 接收日志(通过 Kinesis),处理它们并将它们发送到下面代码片段中的事件总线:
redacted
上面最后一行表示事件发送到事件总线:
redacted
但是,我相信事件总线收到事件后,不会将事件发送到 CloudWatch。即使我手动创建日志组:${AWS::StackName}-form-log-batch-function
(我将堆栈引用作为参数保留以保持匿名)。
我已经检查了 CloudFormation 创建并且所有资源都存在(Lambda 确认在尝试发送事件时没有遇到任何异常)。
有人知道我在这里缺少什么吗?
您无法使用您的 WebLogsEventBusLoggingRole
角色将 写入 CloudWatch Logs (CWL)。正如 AWS docs 所解释的那样,您 必须使用基于 CWL 资源的 权限:
When CloudWatch Logs is the target of a rule, EventBridge creates log streams, and CloudWatch Logs stores the text from the triggering events as log entries. To allow EventBridge to create the log stream and log the events, CloudWatch Logs must include a resource-based policy that enables EventBridge to write to CloudWatch Logs.
遗憾的是,您无法从 vanila CloudFormation (CFN) 设置此类权限。这是不支持:
要从 CFN 执行此操作,您必须以 lambda 函数的形式创建 custom resource。该函数将使用 AWS SDK 设置 CWL 权限。
我希望这对仍在寻找答案的其他人有所帮助。
问题#1 我想让 Cloudformation 工作
您可以使用 https://serverlessland.com/patterns/eventbridge-cloudwatch or terraform
中的云形成
问题#2 为什么 EventBridge 通常无法写入 Cloudwatch 日志
就像上面所说的,为了让 aws event bridge 写入 cloudwatch,需要有一个资源策略(在目标上设置的策略,在本例中为 Cloudwatch Logs)。不过请注意
- 如果您在控制台中创建一个 cloudwatch logs Target,系统会自动为您生成一个资源策略,但自动生成的策略有一个 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
我的建议是制定一个对你有意义的政策,而不是依赖于自动政策。
只需创建一个名称为 /aws/events/<yourgroupname>
的 loggroup
,它就可以正常工作并设置 logs:*
我有一个 AWS lambda,它的工作是使用来自外部源的日志并将这些日志写入自定义 CloudWatch 日志组。请注意,此 lambda 已将日志写入其自己的日志组,这不是我的问题。我想要的是将外部派生的日志写入另一个 CloudWatch 组。
根据 AWS 文档并使用 CloudFormation,我创建了一个事件总线和一个针对 CloudWatch 的规则:
redacted
为了清楚起见,我省略了大部分 CloudFormation 模板,只留下看起来相关的部分。
我发现 Lambda 接收日志(通过 Kinesis),处理它们并将它们发送到下面代码片段中的事件总线:
redacted
上面最后一行表示事件发送到事件总线:
redacted
但是,我相信事件总线收到事件后,不会将事件发送到 CloudWatch。即使我手动创建日志组:${AWS::StackName}-form-log-batch-function
(我将堆栈引用作为参数保留以保持匿名)。
我已经检查了 CloudFormation 创建并且所有资源都存在(Lambda 确认在尝试发送事件时没有遇到任何异常)。
有人知道我在这里缺少什么吗?
您无法使用您的 WebLogsEventBusLoggingRole
角色将 写入 CloudWatch Logs (CWL)。正如 AWS docs 所解释的那样,您 必须使用基于 CWL 资源的 权限:
When CloudWatch Logs is the target of a rule, EventBridge creates log streams, and CloudWatch Logs stores the text from the triggering events as log entries. To allow EventBridge to create the log stream and log the events, CloudWatch Logs must include a resource-based policy that enables EventBridge to write to CloudWatch Logs.
遗憾的是,您无法从 vanila CloudFormation (CFN) 设置此类权限。这是不支持:
要从 CFN 执行此操作,您必须以 lambda 函数的形式创建 custom resource。该函数将使用 AWS SDK 设置 CWL 权限。
我希望这对仍在寻找答案的其他人有所帮助。
问题#1 我想让 Cloudformation 工作
您可以使用 https://serverlessland.com/patterns/eventbridge-cloudwatch or terraform
中的云形成问题#2 为什么 EventBridge 通常无法写入 Cloudwatch 日志
就像上面所说的,为了让 aws event bridge 写入 cloudwatch,需要有一个资源策略(在目标上设置的策略,在本例中为 Cloudwatch Logs)。不过请注意
- 如果您在控制台中创建一个 cloudwatch logs Target,系统会自动为您生成一个资源策略,但自动生成的策略有一个 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 |
我的建议是制定一个对你有意义的政策,而不是依赖于自动政策。
只需创建一个名称为 /aws/events/<yourgroupname>
的 loggroup
,它就可以正常工作并设置 logs:*