如何排查 CloudWatch Logs 的问题,以使其流式传输到我的 Amazon OpenSearch Service 域中?
上次更新日期:2022 年 12 月 13 日
我无法将我的 Amazon CloudWatch Logs 流式传输至我的 Amazon OpenSearch Service 域。如何解决此问题?
解决方法
我无法将多个 CloudWatch 日志组流式传输至相同的 OpenSearch Service 域
在原定设置情况下,Amazon CloudWatch 只会为每个 OpenSearch Service 域创建一个 AWS Lambda 函数。如果您设置多个日志组以通过编列索引将数据传输到您的域,则全部多个日志组均会调用相同的 Lambda 函数。当第一个日志组调用 Lambda 函数时,调用将会在您的域创建一个索引和一个类型字段。
在 Amazon OpenSearch Service 6.0.0 或更高版本中创建的索引只能包含单一映射类型。在 5.x 版本中创建的具有多种映射类型的索引将继续像以前一样在 OpenSearch Service 6.x 版本中运行。如需关于 OpenSearch Service 映射类型弃用的更多信息,请参阅 Elastic 网站上的移除映射类型。
若其他日志组尝试调用相同的 Lambda 函数,调用将会失败,并显示以下错误消息:
"reason": "Rejecting mapping update to [
要解决此问题,请先使用以下语法更新您的 Lambda 函数:
var indexName = [
'cwl-' + payload.logGroup.toLowerCase().split('/').join('-') + '-' + timestamp.getUTCFullYear(),
('0' + (timestamp.getUTCMonth() + 1)).slice(-2),
('0' + timestamp.getUTCDate()).slice(-2)
].join('.');
此语法会为流式传输至您的 OpenSearch Service 域的不同日志组创建多个索引。
然后,保存更新后的 Lambda 函数,以便为流式传输至您的域的多个日志组创建独立的索引。
我无法在相同的 AWS 账户里流式传输至基于 VPC 的 OpenSearch Service 域
重要提示:在将 CloudWatch 日志组流式传输至基于 VPC 的 OpenSearch Service 域之前,确保更新您的 AWS Identity and Access Management (IAM) 角色策略。附加到对应 Lambda 函数的 IAM 角色必须附加有 AWSLambdaVPCAccessExecutionRole 策略。
以下是采用 JSON 格式的 AWSLambdaVPCAccessExecutionRole 策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"
],
"Resource": "*"
}
]
}
注意:此托管策略使 Lambda 函数能够将 CloudWatch 日志组写入 VPC 中的您的集群。
在为 Lambda 函数附加策略以后,您可以开始将日志流式传输至 VPC 中的 OpenSearch Service 域。
当启用精细访问控制时,我无法将我的 CloudWatch 日志组流式传输至 OpenSearch Service 域
如果通过精细访问控制将您的 CloudWatch Logs 流式传输至 OpenSearch Service 域,您可能会遇到以下权限错误:
"{\"statusCode\":403,\"responseBody\":{\"error\":{\"root_cause\":[{\"type\":\"security_exception\",\"reason\":\"no permissions for [indices:data/write/bulk] and User [name=arn:aws:iam::123456789101:role/lambda_opensearch_execution, roles=[arn:aws:iam::123456789101:role/lambda_opensearch_execution], requestedTenant=null]\"}],\"type\":\"security_exception\",\"reason\":\"no permissions for [indices:data/write/bulk] and User [name=arn:aws:iam::123456789101:role/lambda_opensearch_execution, roles=[arn:aws:iam::123456789101:role/lambda_opensearch_execution], requestedTenant=null]\"},\"status\":403}}"
如果您从 Lambda 函数日志收到此错误消息,则表示该 role mapping(角色映射)不完整。
注意:在默认情况下,OpenSearch Service 会为您创建一个 AWS Lambda 函数。
运行 7.9 及更高版本(包括 OpenSearch 版本 1.x)的 OpenSearch Service 域
要解决此错误消息,请按以下步骤操作:
1. 打开 OpenSearch 控制面板。您可以在 OpenSearch Service 控制台的域摘要中找到 OpenSearch 控制面板的链接。
2. 在导航窗格中,选择 Security(安全性)。
3. 选择 Roles(角色)。
4. 选择 all_access 角色。
5. 选择 Mapped users(映射的用户)选项卡。
6. 在 Mapped users(映射的用户)对话框页面上,选择 Manage mapping(管理映射)。
7. 在 Backend roles(后端角色)下,输入 Lambda 函数执行角色 ARN。
8. 选择Map(映射)。您的日志现在应流式传输至您的 OpenSearch Service 域。
如需了解关于角色映射的更多信息,请参阅 Mapping roles to users(将角色映射到用户)。
运行 7.8 及更早版本的 OpenSearch Service 域
要解决此错误消息,请按以下步骤操作:
1. 打开 OpenSearch 控制面板。您可以在 OpenSearch Service 控制台的域摘要中找到 OpenSearch 控制面板的链接。
2. 在左侧导航窗格中,单击锁定图标。
3. 选择角色映射。
4. 选择 all_access 和 security_manager 作为您的角色。
注意:all_access 角色仅提供对您的集群的访问权限。根据您的使用场景,您还可以向集群添加精细访问控制。
5. 为 all_access 编辑映射。
6. 对于后端角色,添加 Lambda 函数的执行角色并选择提交。您的日志现在应流式传输至您的 OpenSearch Service 域。
我的 CloudWatch Logs 没有发送到 OpenSearch Service 域
如果您将 CloudWatch Logs(使用默认的 AWS Lambda 函数)流式传输到 OpenSearch Service 域,则可能会遇到以下索引错误:
"errorMessage": "{\"statusCode\":200,\"responseBody\":{\"took\":42,\"errors\":true}}",
注意:默认情况下,AWS Lambda 错误将作为 200 OK 响应返回。
要排查此错误消息,请按以下步骤操作:
1. 打开原定设置的 AWS Lambda 函数。
2. 找到以下代码行:
"var logFailedResponses = false;"
3. 将 var logFailedResponses 值更新为“true”。 此更新提供了有关使用 AWS Lambda 函数的任何新索引请求的其他信息。您可以使用这些信息来确定索引问题的原因。
我遇到 cluster_block_exception 错误
我的 CloudWatch 订阅筛选器无法通过默认 Lambda 函数向我的集群发送数据(OpenSearch Service 2.0 及更高版本)
如果您让 CloudWatch 订阅筛选器使用默认 Lambda 函数将日志发送到 Amazon OpenSearch Service 2.x,则可能会出现错误。如果订阅筛选器无法提取日志,并且您看到以下错误,则该错误是由停用的参数引起:
"{\"statusCode\":400,\"responseBody\":{\"error\":{\"root_cause\":[{\"type\":\"illegal_argument_exception\",\"reason\":\"Action/metadata line [1] contains an unknown parameter [_type]\"}],\"type\":\"illegal_argument_exception\",\"reason\":\"Action/metadata line [1] contains an unknown parameter [_type]\"},\"status\":400}}"
在 OpenSearch Service 版本 2.0 及更高版本中,_type 参数已从 API 端点中删除。要解决此错误,您还必须从 Lambda 函数的代码中删除该参数。
1. 打开 AWS Lambda 控制台。
2. 为您的订阅筛选器选择默认 Lambda 函数。
3. 在 Code source(代码源)下查看您函数的代码。
4. 找到代码中定义的转换函数。在此函数中,数据转换为 OpenSearch Service 的 JSON 索引格式。这段代码的第一行看起来类似于以下内容:
function transform(payload) {
if (payload.messageType === 'CONTROL_MESSAGE') {
return null;
}
var bulkRequestBody = '';
payload.logEvents.forEach(function(logEvent) {
var timestamp = new Date(1 * logEvent.timestamp);
5. 在转换函数下,找到 _type 参数。在大多数情况下,此参数将位于第 79 行。删除或注释掉添加 _type 参数的代码行。删除后,您的代码如下所示:
var action = {
"index": {}
};
action.index._index = indexName;
//action.index._type = payload.logGroup;
action.index._id = logEvent.id;
bulkRequestBody += [
现在,您就可以成功发送索引请求。