

# 将日志发送到 Amazon CloudWatch
<a name="container-insights-eks-otel-logs"></a>

OTel Container Insights 可收集容器日志并使用 OpenTelemetry Collector 的日志管道将其并发送至 Amazon CloudWatch Logs。Amazon CloudWatch Observability EKS 附加组件将 OpenTelemetry Collector 部署为 DaemonSet，该 DaemonSet 使用文件日志接收器跟踪容器日志文件，使用 Kubernetes 元数据丰富这些文件，然后通过 CloudWatch Logs 导出器将其导出到 CloudWatch Logs 中。

基本日志收集无需额外设置。当您遵循 [快速入门：Amazon EKS 上的 OTel Container Insights](container-insights-eks-otel-quickstart.md) 时，默认情况下会启用日志收集。

## 先决条件
<a name="container-insights-eks-otel-logs-prereqs"></a>

在配置日志收集之前，请核实您是否满足下列要求，然后再继续操作。
+ OTel Container Insights 已安装并且您的集群上已激活 `amazon-cloudwatch-observability` 附加组件
+ IAM 权限：`logs:CreateLogGroup`、`logs:CreateLogStream`、`logs:PutLogEvents`、`logs:DescribeLogGroups` 和 `logs:DescribeLogStreams`（包含在 `CloudWatchAgentServerPolicy` 托管策略中）
+ 节点访问权限：收集器在每个节点上需要对 `/var/log/pods` 的访问权限

## 日志组和来源
<a name="container-insights-eks-otel-logs-groups"></a>

下表描述了 OTel Container Insights 创建的日志组及其从中收集的来源。


| 日志组 | 来源 | 内容 | 
| --- | --- | --- | 
| /aws/containerinsights/{{cluster-name}}/application | /var/log/pods/\*\*/\*.log | 所有容器 stdout 和 stderr 日志 | 

**注意**  
主机和数据面板日志将在未来版本中提供。

## OTel 日志管道的工作原理
<a name="container-insights-eks-otel-logs-pipeline"></a>

该附加组件的 OpenTelemetry Collector 运行一个包含以下组件的日志管道。
+ **接收器**：`filelog` 接收器会从 `/var/log/pods/` 中删除容器日志文件。
+ **处理器**：`k8sattributes` 处理器使用 Kubernetes 元数据充实日志。`batch` 处理器在导出之前对日志记录进行批处理。`resource` 处理器附加资源属性。
+ **导出器**：`awscloudwatchlogs` 导出器向 CloudWatch Logs 发送日志记录。

### 日志扩充
<a name="container-insights-eks-otel-logs-enrichment"></a>

该管道使用以下属性充实每条日志记录。
+ **Kubernetes 资源属性**：`k8s.pod.name`、`k8s.namespace.name`、`k8s.container.name`、`k8s.node.name` 和 `k8s.deployment.name`
+ **容器组（pod）标签**：所有容器组（pod） 标签均为`k8s.pod.label.*` 属性
+ **云属性**：`cloud.region`、`cloud.account.id` 和 `cloud.platform`
+ **集群属性**：`k8s.cluster.name`

## 自定义日志收集
<a name="container-insights-eks-otel-logs-customize"></a>

您可以通过更新附加组件配置值来自定义日志收集。以下各节介绍了常见的自定义选项。

### 禁用日志收集
<a name="container-insights-eks-otel-logs-disable"></a>

要完全禁用日志收集，请在禁用容器日志的情况下更新附加组件配置。

**禁用日志收集**
+ 运行如下命令。将 {{cluster-name}} 替换为 Amazon EKS 集群的名称。

  ```
  aws eks update-addon \
    --cluster-name {{cluster-name}} \
    --addon-name amazon-cloudwatch-observability \
    --configuration-values '{"containerLogs":{"enabled":false}}' \
    --resolve-conflicts OVERWRITE
  ```

### 设置日志保留
<a name="container-insights-eks-otel-logs-retention"></a>

默认情况下，CloudWatch Logs 将无限期存储日志数据。要控制存储成本，您可以对日志组设置保留策略。

**设置日志保留**
+ 运行如下命令。将 {{cluster-name}} 替换为 Amazon EKS 集群的名称。将 {{30}} 替换为要保留日志的天数。

  ```
  aws logs put-retention-policy \
    --log-group-name "/aws/containerinsights/{{cluster-name}}/application" \
    --retention-in-days {{30}}
  ```

## 验证
<a name="container-insights-eks-otel-logs-verify"></a>

要验证日志收集是否正常工作，请检查预期的日志组是否存在并包含数据。

**验证日志收集**
+ 运行如下命令。将 {{cluster-name}} 替换为 Amazon EKS 集群的名称。

  ```
  aws logs describe-log-groups \
    --log-group-name-prefix "/aws/containerinsights/{{cluster-name}}" \
    --query "logGroups[].{Name:logGroupName,StoredBytes:storedBytes}" \
    --output table
  ```

  输出显示日志组名称和存储的字节数。`StoredBytes` 为非零值时确认管道正在传输日志。

## 问题排查
<a name="container-insights-eks-otel-logs-troubleshoot"></a>

使用以下指导来解决常见的日志收集问题。

### 5 分钟后未创建日志组
<a name="container-insights-eks-otel-logs-ts-no-loggroup"></a>

**症状：**5 分钟后，`/aws/containerinsights/{{cluster-name}}/application` 日志组未出现在 CloudWatch Logs 中。

**原因：**收集器没有创建日志组和日志流所需的 IAM 权限。

**解决方案：**验证与收集器关联的 IAM 角色是否已附加 `CloudWatchAgentServerPolicy` 托管策略。此策略包括 `logs:CreateLogGroup` 和 `logs:CreateLogStream` 权限。

### 应用程序日志组存在但为空
<a name="container-insights-eks-otel-logs-ts-empty"></a>

**症状：**应用程序日志组存在于 CloudWatch Logs 中，但它不包含任何日志流或日志事件。

**原因：**当容器未写入 stdout 或 stderr，或者文件日志接收器无法在节点上访问 `/var/log/pods/` 时，就会出现此问题。

**解决方案：**要解决这个问题，请完成以下步骤。

1. 验证您的应用程序容器是否将日志写入 stdout 或 stderr。

1. 检查收集器 DaemonSet 容器组（pod）是否有用于 `/var/log/pods` 的卷挂载。

   ```
   kubectl get daemonset -n amazon-cloudwatch -o yaml | grep -A 5 "var/log/pods"
   ```

1. 检查收集器日志中是否存在文件访问错误。

   ```
   kubectl logs -n amazon-cloudwatch -l app.kubernetes.io/name=cloudwatch-agent --tail=50 | grep -i "error\|permission"
   ```

### CloudWatch Logs 成本较高
<a name="container-insights-eks-otel-logs-ts-costs"></a>

**症状：**CloudWatch Logs 的摄取或存储成本高于预期。

**原因：**大容量命名空间（例如负载测试或监控命名空间）会生成大量日志。

**解决方案：**在日志组上设置保留策略以自动删除较旧的日志。有关说明，请参阅[设置日志保留](#container-insights-eks-otel-logs-retention)。