

# 使用 CloudWatch 代理发送嵌入式指标格式日志
<a name="CloudWatch_Embedded_Metric_Format_Generation_CloudWatch_Agent"></a>

 本节介绍如何安装和使用 CloudWatch 代理。本节的第一部分介绍如何安装 CloudWatch 代理。本节的第二部分介绍如何使用 CloudWatch 代理发送嵌入式指标格式日志。如果要使用此方法，您必须为要从中发送嵌入式指标格式日志的 Amazon Web Services 服务安装 CloudWatch 代理。然后，您可以开始发送事件。CloudWatch 代理必须是 1.230621.0 版或更高版本。

**注意**  
您无需安装 CloudWatch 代理即可通过 Lambda 函数发送日志。  
不会自动处理 Lambda 函数超时。这意味着，如果您的函数在指标刷新前超时，则不会捕获该调用的指标。

## 安装 CloudWatch 代理
<a name="CloudWatch_Embedded_Metric_Format_Generation_Install_Agent"></a>

为要将嵌入式指标格式日志发送到的每项服务安装 CloudWatch 代理。

### 在 EC2 上安装 CloudWatch 代理
<a name="CloudWatch_Embedded_Metric_Format_Generation_Install_Agent_EC2"></a>

首先，在实例上安装 CloudWatch 代理。有关更多信息，请参阅 [安装 CloudWatch 代理](install-CloudWatch-Agent-on-EC2-Instance.md)。

安装该代理后，请将它配置为侦听嵌入式指标格式日志的 UDP 或 TCP 端口。以下是侦听默认套接字 `tcp:25888` 的此配置的示例。有关代理配置的更多信息，请参阅[手动创建或编辑 CloudWatch 代理配置文件](CloudWatch-Agent-Configuration-File-Details.md)。

```
{
  "logs": {
    "metrics_collected": {
      "emf": { }
    }
  }
}
```

### 在 Amazon ECS 上安装 CloudWatch 代理
<a name="CloudWatch_Embedded_Metric_Format_Generation_Install_Agent_ECS"></a>

在 Amazon ECS 上部署 CloudWatch 代理的最简单方法是将它作为附加项运行，并在与您的应用程序相同的任务定义中定义它。

**创建代理配置文件**

本地创建 CloudWatch 代理配置文件。在此示例中，相对文件路径将是 `amazon-cloudwatch-agent.json`。

有关代理配置的更多信息，请参阅[手动创建或编辑 CloudWatch 代理配置文件](CloudWatch-Agent-Configuration-File-Details.md)。

```
{
  "logs": {
    "metrics_collected": {
      "emf": { }
    }
  }
}
```

**将配置推送到 SSM Parameter Store**

输入以下命令以将 CloudWatch 代理配置文件推送到 Amazon Systems Manager (SSM) Parameter Store。

```
aws ssm put-parameter \
    --name "cwagentconfig" \
    --type "String" \
    --value "`cat amazon-cloudwatch-agent.json`" \
    --region "{{region}}"
```

**配置任务定义**

配置任务定义以使用 CloudWatch 代理并开放 TCP 或 UDP 端口。应使用的示例任务定义取决于您的联网模式。

请注意，`webapp` 指定了 `AWS_EMF_AGENT_ENDPOINT` 环境变量。它将由库使用，并且应指向代理正在侦听的终端节点。此外，`cwagent` 指定 `CW_CONFIG_CONTENT` 作为“valueFrom”参数，该参数指向您在上一步中创建的 SSM 配置。

本节包含一个桥式模式示例和一个主机或 awsvpc 模式示例。有关如何在 Amazon ECS 上配置 CloudWatch 代理的更多示例，请参阅 [GitHub 示例存储库](https://github.com/aws-samples/amazon-cloudwatch-container-insights/tree/master/ecs-task-definition-templates/deployment-mode/sidecar)

以下是桥接模式的示例。在启用桥式模式联网后，需要使用 `links` 参数将代理链接到您的应用程序，并且必须使用容器名称进行寻址。

```
{
  "containerDefinitions": [
          {
              "name": "webapp",
              "links": [ "cwagent" ],
              "image": "my-org/web-app:latest",
              "memory": 256,
              "cpu": 256,
              "environment": [{
                "name": "AWS_EMF_AGENT_ENDPOINT",
                "value": "tcp://cwagent:25888"
              }],
          },
          {
              "name": "cwagent",
              "mountPoints": [],
              "image": "public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest",
              "memory": 256,
              "cpu": 256,
              "portMappings": [{
                  "protocol": "tcp",
                  "containerPort": 25888
              }],
              "environment": [{
                "name": "CW_CONFIG_CONTENT",
                "valueFrom": "cwagentconfig"
              }],
          }
      ],
}
```

以下是主机模式或 awsvpc 模式的示例。在这些网络模式上运行时，可以通过 `localhost` 对代理进行寻址。

```
{
  "containerDefinitions": [
          {
              "name": "webapp",
              "image": "my-org/web-app:latest",
              "memory": 256,
              "cpu": 256,
              "environment": [{
                "name": "AWS_EMF_AGENT_ENDPOINT",
                "value": "tcp://127.0.0.1:25888"
              }],
          },
          {
              "name": "cwagent",
              "mountPoints": [],
              "image": "public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest",
              "memory": 256,
              "cpu": 256,
              "portMappings": [{
                  "protocol": "tcp",
                  "containerPort": 25888
              }],
              "environment": [{
                "name": "CW_CONFIG_CONTENT",
                "valueFrom": "cwagentconfig"
              }],
          }
      ],
}
```

**注意**  
在 awsvpc 模式中，您必须为 VPC 提供公有 IP 地址（仅限 Fargate）、设置 NAT 网关或设置 CloudWatch Logs VPC 终端节点。有关设置 NAT 的更多信息，请参阅 [NAT 网关](https://docs.amazonaws.cn/vpc/latest/userguide/vpc-nat-gateway.html)。有关设置 CloudWatch Logs VPC 终端节点的更多信息，请参阅[将 CloudWatch Logs 与接口 VPC 终端节点结合使用](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/cloudwatch-logs-and-interface-VPC.html)。  
以下是如何将公有 IP 地址分配给使用 Fargate 启动类型的任务的示例。  

```
aws ecs run-task \ 
--cluster {{cluster-name}} \
--task-definition cwagent-fargate \
--region {{region}} \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[{{subnetId}}],securityGroups=[{{sgId}}],assignPublicIp=ENABLED}"
```

**确保权限**

确保执行任务的 IAM 角色具有从 SSM Parameter Store 中进行读取的权限。您可以通过附加 **AmazonSSMReadOnlyAccess** 策略来添加此权限。为此，请输入以下命令。

```
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess \
--role-name CWAgentECSExecutionRole
```

### 在 Amazon EKS 上安装 CloudWatch 代理
<a name="CloudWatch_Embedded_Metric_Format_Generation_Install_Agent_EKS"></a>

如果您已在此集群上安装 CloudWatch Container Insights，则可以跳过此过程的某些部分。

权限

如果您尚未安装 Container Insights，请先确保您的 Amazon EKS 节点具有适当的 IAM 权限。它们应已附加 **CloudWatchAgentServerPolicy**。有关更多信息，请参阅 [在 CloudWatch 中验证 Container Insights 的先决条件](Container-Insights-prerequisites.md)。

**创建 ConfigMap**

为代理创建 ConfigMap。ConfigMap 还将告知代理侦听 TCP 或 UDP 端口。使用以下 ConfigMap。

```
# cwagent-emf-configmap.yaml
apiVersion: v1
data:
  # Any changes here must not break the JSON format
  cwagentconfig.json: |
    {
      "agent": {
        "omit_hostname": true
      },
      "logs": {
        "metrics_collected": {
          "emf": { }
        }
      }
    }
kind: ConfigMap
metadata:
  name: cwagentemfconfig
  namespace: default
```

如果您已安装 Container Insights，请将以下 `"emf": { }` 行添加到现有 ConfigMap。

**应用 ConfigMap**

输入以下命令可应用 ConfigMap。

```
kubectl apply -f cwagent-emf-configmap.yaml
```

**部署代理**

要将 CloudWatch 代理部署为附加项，请将代理添加到 pod 定义中，如以下示例所示。

```
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: default
spec:
  containers:
    # Your container definitions go here
    - name: web-app
      image: my-org/web-app:latest
    # CloudWatch Agent configuration
    - name: cloudwatch-agent
      image: public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest
      imagePullPolicy: Always
      resources:
        limits:
          cpu: 200m
          memory: 100Mi
        requests:
          cpu: 200m
          memory: 100Mi
      volumeMounts:
        - name: cwagentconfig
          mountPath: /etc/cwagentconfig
      ports:
  # this should match the port configured in the ConfigMap
        - protocol: TCP
          hostPort: 25888
          containerPort: 25888
  volumes:
    - name: cwagentconfig
      configMap:
        name: cwagentemfconfig
```

## 使用 CloudWatch 代理发送嵌入式指标格式日志
<a name="CloudWatch_Embedded_Metric_Format_Generation_CloudWatch_Agent_Send_Logs"></a>

在安装并运行 CloudWatch 代理后，您可以通过 TCP 或 UDP 发送嵌入式指标格式日志。在通过代理发送日志时有两个要求：
+ 日志必须包含一个 `LogGroupName` 键，该键告知代理要使用的日志组。
+ 每个日志事件必须位于单个行上。换句话说，日志事件不能包含换行符 (\$1n)。

日志事件还必须遵循嵌入式指标格式规范。有关更多信息，请参阅 [规范：嵌入式指标格式](CloudWatch_Embedded_Metric_Format_Specification.md)。

如果您计划为使用嵌入式指标格式创建的指标创建告警，请参阅 [为使用嵌入式指标格式创建的指标设置警报](CloudWatch_Embedded_Metric_Format_Alarms.md) 获取相关建议。

以下是手动从 Linux Bash Shell 发送日志事件的示例。您可以改用所选编程语言提供的 UDP 套接字接口。

```
echo '{"_aws":{"Timestamp":1574109732004,"LogGroupName":"Foo","CloudWatchMetrics":[{"Namespace":"MyApp","Dimensions":[["Operation"]],"Metrics":[{"Name":"ProcessingLatency","Unit":"Milliseconds","StorageResolution":60}]}]},"Operation":"Aggregator","ProcessingLatency":100}' \
> /dev/udp/0.0.0.0/25888
```

**注意**  
 通过嵌入式指标格式，您可以按指标跟踪发布在您账户的 `Amazon/Logs` 命名空间中的 EMF 日志的处理。可通过这些日志跟踪 EMF 中指标生成失败的情况，以及失败的原因是解析还是验证。有关更多详细信息，请参阅[使用 CloudWatch 指标监控](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Monitoring-CloudWatch-Metrics.html)。