

# 发布自定义指标（PutMetricData/EMF）
<a name="publishingMetrics"></a>

您可使用 `PutMetricData` API 或 AWS CLI 将自己的自定义指标发送到 CloudWatch。此方法使用 CloudWatch 命名空间、指标名称和维度。

**注意**  
新建监控方案时，推荐采用 OpenTelemetry 发送自定义指标。有关更多信息，请参阅 [使用 OpenTelemetry 发送指标](metrics-otel-send.md)。

**Topics**
+ [高精度指标](#high-resolution-metrics)
+ [使用维度](#usingDimensions)
+ [发布单一数据点](#publishingDataPoints)
+ [发布统计数据集](#publishingDataPoints1)
+ [发布零值](#publishingZero)
+ [停止发布指标](#CloudWatch-Stop-Publishing-Metrics)

## 高精度指标
<a name="high-resolution-metrics"></a>

每个指标均为以下类型之一：
+ 标准精度，数据粒度为一分钟
+ 高精度，数据粒度为一秒

AWS 服务生成的指标在默认情况下为标准精度。在发布自定义指标时，您可以将其定义为标准精度或高精度。发布高精度指标时，CloudWatch 使用 1 秒的精度来存储指标，您可以按照 1 秒、5 秒、10 秒、30 秒或 60 秒的任意倍数的时间段读取和检索。

高精度指标让您对应用程序的亚分钟级活动有着更详细的直观认识。请记住，每次对自定义指标的 `PutMetricData` 调用都会收取费用，因此对高精度指标频繁调用 `PutMetricData` 会导致较高的费用。有关 CloudWatch 定价的信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/)。

如果对高精度指标设置警报，您可以指定 10 秒或 30 秒时间段的高精度警报，也可以设置 60 秒的任意倍数时间段的定期警报。10 秒或 30 秒时间段的高精度警报会产生较高的费用。

## 使用维度
<a name="usingDimensions"></a>

在自定义指标中，`--dimensions` 参数很常见。维度进一步阐明了指标是什么以及指标存储什么数据。您可以将最多 30 个维度分配给一个指标，每个维度通过一个名称和值对进行定义。

当使用不同的命令时，指定维度的方式也不同。使用 [put-metric-data](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/put-metric-data.html) 时，将每个维度指定为 {{MyName}}={{MyValue}} 格式，使用 [get-metric-statistics](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html) 或 [put-metric-alarm](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/put-metric-alarm.html) 时，将使用格式 `Name=`{{MyName}}、`Value=`{{MyValue}}。例如，以下命令将发布包含 2 个维度（分别名为 `InstanceId` 和 `InstanceType`）的 `Buffers` 指标。

```
aws cloudwatch put-metric-data --metric-name Buffers --namespace MyNameSpace --unit Bytes --value 231434333 --dimensions InstanceId=1-23456789,InstanceType=m1.small
```

此命令检索同一指标的统计数据。使用逗号分隔单一维度的名称部分和值部分，但如果有多个维度，应在不同维度之间使用空格分隔。

```
aws cloudwatch get-metric-statistics --metric-name Buffers --namespace MyNameSpace --dimensions Name=InstanceId,Value=1-23456789 Name=InstanceType,Value=m1.small --start-time 2016-10-15T04:00:00Z --end-time 2016-10-19T07:00:00Z --statistics Average --period 60
```

如果单个指标包含多个维度，则在使用 [get-metric-statistics](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html) 时必须为每个已定义的维度指定一个值。例如，Amazon S3 指标 `BucketSizeBytes` 包含维度 `BucketName` 和 `StorageType`，因此必须使用 [get-metric-statistics](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html) 指定这两个维度。

```
aws cloudwatch get-metric-statistics --metric-name BucketSizeBytes --start-time 2017-01-23T14:23:00Z --end-time 2017-01-26T19:30:00Z --period 3600 --namespace AWS/S3 --statistics Maximum --dimensions Name=BucketName,Value={{amzn-s3-demo-bucket}} Name=StorageType,Value=StandardStorage --output table
```

要查看为指标定义的维度，请使用 [list-metrics](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/list-metrics.html) 命令。

## 发布单一数据点
<a name="publishingDataPoints"></a>

要发布新指标或现有指标的单一数据点，请使用带有一个值和时间戳的 [put-metric-data](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/put-metric-data.html) 命令。例如，下列每项操作会发布一个数据点。

```
aws cloudwatch put-metric-data --metric-name {{PageViewCount}} --namespace {{MyService}} --value 2 --timestamp {{2016-10-20T12:00:00.000Z}}
aws cloudwatch put-metric-data --metric-name {{PageViewCount}} --namespace {{MyService}} --value 4 --timestamp {{2016-10-20T12:00:01.000Z}}
aws cloudwatch put-metric-data --metric-name {{PageViewCount}} --namespace {{MyService}} --value 5 --timestamp {{2016-10-20T12:00:02.000Z}}
```

如果使用新的指标名称调用此命令，CloudWatch 会为您创建一个指标。否则，CloudWatch 会将您的数据与您指定的现有指标进行关联。

**注意**  
当您创建指标时，可能需要 2 分钟时间，然后才能使用 [get-metric-statistics](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/get-metric-statistics.html) 命令检索新指标的统计数据。但是，这可能需要最多 15 分钟时间，然后新指标才会出现在使用 [list-metrics](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/list-metrics.html) 命令检索的指标列表中。

尽管可以以千分之一秒粒度的时间戳发布数据点，但是 CloudWatch 会将数据聚合到一秒钟的最低粒度。CloudWatch 记录每个时间段内收到的值的平均值（所有项之和除以项数）以及同一个时间段内的样本数、最大值和最小值。例如，之前示例中的 `PageViewCount` 指标包含 3 个数据点，这些数据点的时间戳相差仅数秒。如果将时间段设置为 1 分钟，则 CloudWatch 会聚合这 3 个数据点，因为时间戳均处于同一个 1 分钟时间段内。

您可以使用 **get-metric-statistics** 命令，基于您发布的数据点来检索统计数据。

```
aws cloudwatch get-metric-statistics --namespace {{MyService}} --metric-name {{PageViewCount}} \
--statistics "Sum" "Maximum" "Minimum" "Average" "SampleCount" \
--start-time {{2016-10-20T12:00:00.000Z}} --end-time {{2016-10-20T12:05:00.000Z}} --period 60
```

下面是示例输出。

```
{
    "Datapoints": [
        {
            "SampleCount": 3.0,
            "Timestamp": "2016-10-20T12:00:00Z",
            "Average": 3.6666666666666665,
            "Maximum": 5.0,
            "Minimum": 2.0,
            "Sum": 11.0,
            "Unit": "None"
        }
    ],
    "Label": "PageViewCount"
}
```

## 发布统计数据集
<a name="publishingDataPoints1"></a>

您可在将数据发布到 CloudWatch 之前对数据进行聚合。如果您每分钟拥有多个数据点，则数据聚合会将调用 **put-metric-data** 的数目减到最少。例如，对于彼此相差不超过 3 秒的 3 个数据点，无需多次调用 **put-metric-data**，而是可以使用 `--statistic-values` 参数将数据聚合到统计信息集中，然后通过一次调用发布。

```
aws cloudwatch put-metric-data --metric-name PageViewCount --namespace {{MyService}} --statistic-values Sum=11,Minimum=2,Maximum=5,SampleCount=3 --timestamp {{2016-10-14T12:00:00.000Z}}
```

CloudWatch 需要原始数据点来计算百分位数。如果您改用统计数据集发布数据，则无法检索此数据的百分位数统计数据，除非满足以下条件之一：
+ 统计数据集的 `SampleCount` 为 1。
+ 统计数据集的 `Minimum` 和 `Maximum` 相等

## 发布零值
<a name="publishingZero"></a>

 如果数据比较分散并有一些包含无关联数据的时间段，则可以选择为该时间段发布值零 (`0`) 或者无任何值。如果您通过定期调用 `PutMetricData` 来监控应用程序的运行状况，则可能需要发布零值来代替无值。例如，可以设置一个当应用程序发布指标失败时每隔五分钟向您发送通知的 CloudWatch 警报。您想让这样的应用程序为不含任何关联数据的时间段发布零值。

 如果想要追踪数据点的总数或需要最小和平均等统计数据包含 0 值数据点，也可以发布零值。

## 停止发布指标
<a name="CloudWatch-Stop-Publishing-Metrics"></a>

要停止向 CloudWatch 发布自定义指标，请更改应用程序或服务的代码以停止使用 **PutMetricData**。CloudWatch 不会从应用程序中提取指标，它只会接收推送的内容，因此要停止发布指标，您必须在源头停止这些指标。