CloudWatch コンソールのグラフで表示される単位が正しいのかを AWS CLI で確認してみた

コンソールだと「秒」って表示されてるけど実際は「マイクロ秒」だったりしない?と気になったことがあったので確認しました。

コンバンハ、千葉(幸)です。

AWS マネジメントコンソールの CloudWatch 画面でメトリクスをグラフ描画する場合、単位(Unit)を自動的に表示してくれます。

例えば以下のような形です。(ここではSeconds(秒)と表示。グラフの上限は10

CloudWatch_Metrics_graph

ここで、グラフ描画しているメトリクスSuccessfulReadRequestLatencyのUnit はMicrosecondsであるとドキュメントに記載されています。(2024/02/20時点。)

Serverless_cache_metrics_-_Amazon_ElastiCache

10,000,000 マイクロ秒を 10 秒に変換して表示してくれていることを期待しますが、もしかして 10 マイクロ秒を表しているのではないか、という疑問も少しだけ生じます。

AWS CLI を用いてその疑念を払拭してみました。

先にまとめ

  • aws cloudwatch get-metric-dataUnitを指定する場合、異なるUnitを指定すると結果が得られない

今回で言えばUnitSecondsを指定した場合は結果が返ってきて、Microsecondsを指定した場合は結果が返ってきません。そのため、Secondsが単位として正しい(コンソールの表示が正しい)ことが確認できました。

AWS CLI で CloudWatch メトリクスを取得してみる

以下の AWS CLI コマンドを使用します。

Unitについて以下の記述があります。

If you omit Unit in your request, all data that was collected with any unit is returned, along with the corresponding units that were specified when the data was reported to CloudWatch. If you specify a unit, the operation returns only data that was collected with that unit specified. If you specify a unit that does not match the data collected, the results of the operation are null. CloudWatch does not perform unit conversions.

(機械翻訳)

リクエストで単位(Unit)を省略した場合、どのような単位で収集されたデータも全て返され、そのデータがCloudWatchに報告されたときに指定された対応する単位も一緒に返されます。単位を指定した場合、その単位で収集されたデータのみが返されます。収集されたデータと一致しない単位を指定した場合、その操作の結果はnullになります。CloudWatchは単位の変換を行いません。

Unitを指定すると、それが収集されたデータと一致しない場合は結果が null になる、ということです。

Unit として Seconds を指定する

まずはUnitSecondsを指定して実行してみました。

$ aws cloudwatch get-metric-data \
    --metric-data-queries '[
        {
            "Id": "query1",
            "MetricStat": {
                "Metric": {
                    "Namespace": "AWS/ElastiCache",
                    "MetricName": "SuccessfulReadRequestLatency",
                    "Dimensions": [
                        {
                            "Name": "clusterId",
                            "Value": "example-cluster-name"
                        }
                    ]
                },
                "Period": 60,
                "Stat": "Maximum",
                "Unit": "Seconds"
            },
            "ReturnData": true
        }
    ]' \
    --start-time 2024-02-19T04:00:00Z \
    --end-time 2024-02-19T04:30:00Z

以下の結果が得られました。

{
    "MetricDataResults": [
        {
            "Id": "query1",
            "Label": "SuccessfulReadRequestLatency",
            "Timestamps": [
                "2024-02-19T04:29:00+00:00",
                "2024-02-19T04:28:00+00:00",
                "2024-02-19T04:27:00+00:00",
                "2024-02-19T04:26:00+00:00",
                "2024-02-19T04:22:00+00:00",
                "2024-02-19T04:21:00+00:00",
                "2024-02-19T04:20:00+00:00",
                "2024-02-19T04:19:00+00:00"
            ],
            "Values": [
                0.002,
                10.0,
                10.0,
                10.0,
                0.0015,
                10.0,
                10.0,
                10.0
            ],
            "StatusCode": "Complete"
        }
    ],
    "Messages": []
}

10 秒、という理解であっていそうです。

Unit として Microseconds を指定する

続いて、UnitMicrosecondsを指定して実行してみます。Unit以外は先ほどと同一の指定です。

$ aws cloudwatch get-metric-data \
    --metric-data-queries '[
        {
            "Id": "query1",
            "MetricStat": {
                "Metric": {
                    "Namespace": "AWS/ElastiCache",
                    "MetricName": "SuccessfulReadRequestLatency",
                    "Dimensions": [
                        {
                            "Name": "clusterId",
                            "Value": "example-cluster-name"
                        }
                    ]
                },
                "Period": 60,
                "Stat": "Maximum",
                "Unit": "Microseconds"
            },
            "ReturnData": true
        }
    ]' \
    --start-time 2024-02-19T04:00:00Z \
    --end-time 2024-02-19T04:30:00Z

実行結果は以下のとおり。TimestampsValuesの結果が得られませんでした。

{
    "MetricDataResults": [
        {
            "Id": "query1",
            "Label": "SuccessfulReadRequestLatency",
            "Timestamps": [],
            "Values": [],
            "StatusCode": "Complete"
        }
    ],
    "Messages": []
}

念のためMillisecondsも試してみましたが、同様の結果でした。

ちなみに:単位が Bytes のメトリクスでも試した

別のメトリクスBytesUsedForCacheでも試してみます。このメトリクスのUnitBytesです。

コンソール上でも単位はBytesで、数字が M(メガ)に丸められる形で表現されています。

CloudWatch_metrics_elasticache

AWS CLI でUnitを指定しないで実行してみます。

$ aws cloudwatch get-metric-data \
    --metric-data-queries '[
        {
            "Id": "query1",
            "MetricStat": {
                "Metric": {
                    "Namespace": "AWS/ElastiCache",
                    "MetricName": "BytesUsedForCache",
                    "Dimensions": [
                        {
                            "Name": "clusterId",
                            "Value": "example-cluster-name"
                        }
                    ]
                },
                "Period": 300,
                "Stat": "Maximum"
            },
            "ReturnData": true
        }
    ]' \
    --start-time 2024-02-19T03:45:00Z \
    --end-time 2024-02-19T04:05:00Z

コンソールで見えるものと同様の値が得られました。なお、明示的にUnitBytesを指定した場合も同じ結果が得られます。

{
    "MetricDataResults": [
        {
            "Id": "query1",
            "Label": "BytesUsedForCache",
            "Timestamps": [
                "2024-02-19T04:00:00+00:00",
                "2024-02-19T03:55:00+00:00",
                "2024-02-19T03:50:00+00:00",
                "2024-02-19T03:45:00+00:00"
            ],
            "Values": [
                12491899.0,
                12491899.0,
                12491899.0,
                6261895.166666667
            ],
            "StatusCode": "Complete"
        }
    ],
    "Messages": []
}

UnitMegabytesを指定して実行しみます。

$ aws cloudwatch get-metric-data \
    --metric-data-queries '[
        {
            "Id": "query1",
            "MetricStat": {
                "Metric": {
                    "Namespace": "AWS/ElastiCache",
                    "MetricName": "BytesUsedForCache",
                    "Dimensions": [
                        {
                            "Name": "clusterId",
                            "Value": "example-cluster-name"
                        }
                    ]
                },
                "Period": 300,
                "Stat": "Maximum",
                "Unit": "Megabytes"
            },
            "ReturnData": true
        }
    ]' \
    --start-time 2024-02-19T03:45:00Z \
    --end-time 2024-02-19T04:05:00Z

TimestampsValuesの結果が得られませんでした。

{
    "MetricDataResults": [
        {
            "Id": "query1",
            "Label": "BytesUsedForCache",
            "Timestamps": [],
            "Values": [],
            "StatusCode": "Complete"
        }
    ],
    "Messages": []
}

先ほど引用した以下の仕様と一致しています。

リクエストで単位(Unit)を省略した場合、どのような単位で収集されたデータも全て返され、そのデータがCloudWatchに報告されたときに指定された対応する単位も一緒に返されます。単位を指定した場合、その単位で収集されたデータのみが返されます。収集されたデータと一致しない単位を指定した場合、その操作の結果はnullになります。CloudWatchは単位の変換を行いません。

終わりに

CloudWatch コンソールで表示される単位(Unit)が正しいかの裏どりを AWS CLI でやってみた、という話でした。結果としては、コンソールの表記が正しかったです。

諸々の結果を鑑みると、SuccessfulReadRequestLatencyのUnit がMicrosecondsであるというのはドキュメントの記述が誤っているのではないかという気もしています。(あるいは、場合によってはマイクロ秒で記録されることがあるのかも知れません。)

コンソールの単位の記述に迷った場合、確認を取る術として AWS CLI があることを思い出してください。

以上、 チバユキ (@batchicchi) がお送りしました。

参考