

# 对 Amazon ECS 上的 Prometheus 指标进行故障排除
<a name="ContainerInsights-Prometheus-troubleshooting-ECS"></a>

本节提供有关对 Amazon ECS 集群上的 Prometheus 指标设置进行故障排除的帮助。

## 我没有看到发送到 CloudWatch Logs 的 Prometheus 指标
<a name="ContainerInsights-Prometheus-troubleshooting-ECS-nometrics"></a>

Prometheus 指标在日志组 **/aws/ecs/containerinsights/cluster-name/Prometheus** 中摄取作为日志事件。如果未创建日志组或未将 Prometheus 指标发送到日志组，您需要首先检查 CloudWatch 代理是否已成功发现 Prometheus 目标。然后检查 CloudWatch 代理的安全组和权限设置。以下步骤会指导您进行调试。

**步骤 1：启用 CloudWatch 代理调试模式**

首先，通过将以下粗体行添加到 Amazon CloudFormation 模版文件、`cwagent-ecs-prometheus-metric-for-bridge-host.yaml` 或 `cwagent-ecs-prometheus-metric-for-awsvpc.yaml` 中并保存文件，将 CloudWatch 代理更改为调试模式。然后保存文件。

```
cwagentconfig.json: |
    {
      "agent": {
        "debug": true
      },
      "logs": {
        "metrics_collected": {
```

针对现有堆栈创建一个新的 Amazon CloudFormation 变更集。将变更集中的其他参数设置为与现有 Amazon CloudFormation 堆栈中相同的值。以下示例适用于使用 EC2 启动类型和桥式网络模式安装在 Amazon ECS 集群中的 CloudWatch 代理。

```
ECS_NETWORK_MODE=bridge
 CREATE_IAM_ROLES=True
ECS_TASK_ROLE_NAME=your_selected_ecs_task_role_name
ECS_EXECUTION_ROLE_NAME=your_selected_ecs_execution_role_name
NEW_CHANGESET_NAME=your_selected_ecs_execution_role_name

aws cloudformation create-change-set --stack-name CWAgent-Prometheus-ECS-${ECS_CLUSTER_NAME}-EC2-${ECS_NETWORK_MODE} \
    --template-body file://cwagent-ecs-prometheus-metric-for-bridge-host.yaml \
    --parameters ParameterKey=ECSClusterName,ParameterValue=$ECS_CLUSTER_NAME \
                 ParameterKey=CreateIAMRoles,ParameterValue=$CREATE_IAM_ROLES \
                 ParameterKey=ECSNetworkMode,ParameterValue=$ECS_NETWORK_MODE \
                 ParameterKey=TaskRoleName,ParameterValue=$ECS_TASK_ROLE_NAME \
                 ParameterKey=ExecutionRoleName,ParameterValue=$ECS_EXECUTION_ROLE_NAME \
    --capabilities CAPABILITY_NAMED_IAM \
    --region $AWS_REGION \
    --change-set-name $NEW_CHANGESET_NAME
```

转至 Amazon CloudFormation 控制台查看新的变更集，请参阅 `$NEW_CHANGESET_NAME`。应该对 **CWAgentConfigSSMParameter** 资源应用一项更改。通过输入以下命令执行变更集并重新启动 CloudWatch 代理任务。

```
aws ecs update-service --cluster $ECS_CLUSTER_NAME \
--desired-count 0 \
--service your_service_name_here \
--region $AWS_REGION
```

等待大约 10 秒，然后输入以下命令。

```
aws ecs update-service --cluster $ECS_CLUSTER_NAME \
--desired-count 1 \
--service your_service_name_here \
--region $AWS_REGION
```

**步骤 2：检查 ECS 服务发现日志**

CloudWatch 代理的 ECS 任务定义默认启用以下部分中的日志。日志将发送到 **/ecs/ecs-cwagent-prometheus** 日志组中的 CloudWatch Logs。

```
LogConfiguration:
  LogDriver: awslogs
    Options:
      awslogs-create-group: 'True'
      awslogs-group: "/ecs/ecs-cwagent-prometheus"
      awslogs-region: !Ref AWS::Region
      awslogs-stream-prefix: !Sub 'ecs-${ECSLaunchType}-awsvpc'
```

根据字符串 `ECS_SD_Stats` 筛选日志以获取与 ECS 服务发现相关的指标，如下例所示。

```
2020-09-1T01:53:14Z D! ECS_SD_Stats: AWSCLI_DescribeContainerInstances: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: AWSCLI_DescribeInstancesRequest: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: AWSCLI_DescribeTaskDefinition: 2
2020-09-1T01:53:14Z D! ECS_SD_Stats: AWSCLI_DescribeTasks: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: AWSCLI_ListTasks: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: Exporter_DiscoveredTargetCount: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: LRUCache_Get_EC2MetaData: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: LRUCache_Get_TaskDefinition: 2
2020-09-1T01:53:14Z D! ECS_SD_Stats: LRUCache_Size_ContainerInstance: 1
2020-09-1T01:53:14Z D! ECS_SD_Stats: LRUCache_Size_TaskDefinition: 2
2020-09-1T01:53:14Z D! ECS_SD_Stats: Latency: 43.399783ms
```

特定 ECS 服务发现周期的每个指标的含义如下：
+ **AWSCLI\$1DescribeContainerInstances** – `ECS::DescribeContainerInstances` 进行的 API 调用次数。
+ **AWSCLI\$1DescribeInstancesRequest** – `ECS::DescribeInstancesRequest` 进行的 API 调用次数。
+ **AWSCLI\$1DescribeTaskDefinition** – `ECS::DescribeTaskDefinition` 进行的 API 调用次数。
+ **AWSCLI\$1DescribeTasks** – `ECS::DescribeTasks` 进行的 API 调用次数。
+ **AWSCLI\$1ListTasks** – `ECS::ListTasks` 进行的 API 调用次数。
+ **ExporterDiscoveredTargetCount** – 已发现并成功导出到容器内的目标结果文件中的 Prometheus 目标数量。
+ **LRUCache\$1Get\$1EC2MetaData** – 从缓存中检索容器实例元数据的次数。
+ **LRUCache\$1Get\$1TaskDefinition** – 从缓存中检索 ECS 任务定义元数据的次数。
+ **LRUCache\$1Size\$1ContainerInstance** – 缓存在内存中的唯一容器实例元数据的数量。
+ **LRUCache\$1Size\$1TaskDefinition** – 缓存在内存中的唯一 ECS 任务定义的数量。
+ **延迟** – 服务发现周期所需的时间。

检查 `ExporterDiscoveredTargetCount` 的值以查看发现的 Prometheus 目标是否符合您的预期。如果不符合，可能的原因如下：
+ ECS 服务发现的配置可能与应用程序的设置不匹配。对于基于 docker 标签的服务发现，您的目标容器可能并未在 CloudWatch 代理中配置必要的 docker 标签以将其自动发现。对于 ECS 任务定义 ARN 基于正则表达式的服务发现，CloudWatch 代理中的正则表达式设置可能与应用程序的任务定义不匹配。
+ CloudWatch 代理的 ECS 任务角色可能没有权限检索 ECS 任务的元数据。检查 CloudWatch 代理是否已被授予以下只读权限：
  + `ec2:DescribeInstances`
  + `ecs:ListTasks`
  + `ecs:DescribeContainerInstances`
  + `ecs:DescribeTasks`
  + `ecs:DescribeTaskDefinition`

**步骤 3：检查网络连接以及 ECS 任务角色策略**

如果即使 `Exporter_DiscoveredTargetCount` 的值表明已发现 Prometheus 目标，仍然没有日志事件发送到目标 CloudWatch Logs 日志组，这可能是由以下任一原因引起的：
+ CloudWatch 代理可能无法连接到 Prometheus 目标端口。检查 CloudWatch 代理背后的安全组设置。私有 IP 应允许 CloudWatch 代理连接到 Prometheus 导出器端口。
+ CloudWatch 代理的 ECS 任务角色可能没有 **CloudWatchAgentServerPolicy** 托管策略。CloudWatch 代理的 ECS 任务角色需要具有此策略才能将 Prometheus 指标作为日志事件发送。如果您使用示例 Amazon CloudFormation 模板自动创建 IAM 角色，则 ECS 任务角色和 ECS 执行角色都会被授予执行 Prometheus 监控的最低权限。