AWS CloudWatch Agent指标错误:MetricDataQueries中Id参数值不唯一
解决CloudWatch GetMetricData接口的Id重复问题
问题场景
在Lambda中通过CloudWatch Agent调用get_metric_data接口获取指标数据,代码如下:
metrics_response = cw.get_metric_data( MetricDataQueries = metrics_data_queries, StartTime = datetime.now()+timedelta(minutes=-60), EndTime=datetime.now() )
对应的metrics_data_queries配置:
[{"Id": "cpu_time_idle", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_idle", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}, {"Name": "cpu", "Value": "cpu0"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_idleResponse", "ReturnData": True}, {"Id": "cpu_time_idle", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_idle", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_idleResponse", "ReturnData": True}, {"Id": "cpu_time_active", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_active", "Dimensions": [{"Name": "InstanceId", "Value": "XXXX"}, {"Name": "cpu", "Value": "cpu0"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_activeResponse", "ReturnData": True}, {"Id": "cpu_time_active", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_active", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_activeResponse", "ReturnData": True}]
触发错误:
[ERROR] ClientError: An error occurred (ValidationError) when calling the GetMetricData operation: **The values for parameter id in MetricDataQueries are not unique.** Traceback (most recent call last): File "/var/task/lambda_function.py", line 27, in lambda_handler metrics_response = get_metrics(metrics_list_response,cw) File "/var/task/lambda_function.py", line 81, in get_metrics metrics_response = cw.get_metric_data( File "/var/runtime/botocore/client.py", line 391, in _api_call return self._make_api_call(operation_name, kwargs) File "/var/runtime/botocore/client.py", line 719, in _make_api_call raise error_class(parsed_response, operation_name)
使用的CWAgent配置config.json:
{ "agent": { "metrics_collection_interval": 60, "run_as_user": "root" }, "metrics": { "aggregation_dimensions": [ [ "InstanceId" ] ], "append_dimensions": { "InstanceId": "${aws:InstanceId}" }, "metrics_collected": { "collectd": { "metrics_aggregation_interval": 60 }, "disk": { "measurement": [ "total", "used", "free", "used_percent" ], "metrics_collection_interval": 60, "resources": [ "/" ] }, "cpu": { "measurement": [ "time_active", "time_idle", "usage_active", "usage_idle", "usage_user", "usage_system" ], "totalcpu": false, "metrics_collection_interval": 60, "resources": [ "*" ] }, "mem": { "measurement": [ "total", "used", "active", "available", "available_percent", "free", "inactive", "used_percent", "cached" ], "metrics_collection_interval": 60 }, "processes": { "measurement": [ "total", "running", "sleeping", "blocked", "dead" ], "metrics_collection_interval": 60 } } } }
问题原因
CloudWatch的GetMetricData接口要求每个MetricDataQuery的Id必须唯一,用于标识每个查询的结果。当前配置中,查询单CPU核心(带cpu: cpu0维度)和实例汇总(仅InstanceId维度)的同名称指标时,使用了相同的Id,导致校验失败。
另外,CWAgent配置中cpu部分设置了totalcpu: false且resources: ["*"],会收集每个CPU核心的独立指标;同时aggregation_dimensions配置了按InstanceId聚合,因此会生成两种维度的指标数据,查询时需要区分但未给Id做唯一标识。
解决方案
1. 为每个查询设置唯一Id
直接修改metrics_data_queries中的Id字段,结合指标名、维度信息生成唯一标识,示例如下:
[{"Id": "cpu_time_idle_cpu0", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_idle", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}, {"Name": "cpu", "Value": "cpu0"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_idle_cpu0_Response", "ReturnData": True}, {"Id": "cpu_time_idle_instance", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_idle", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_idle_instance_Response", "ReturnData": True}, {"Id": "cpu_time_active_cpu0", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_active", "Dimensions": [{"Name": "InstanceId", "Value": "XXXX"}, {"Name": "cpu", "Value": "cpu0"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_active_cpu0_Response", "ReturnData": True}, {"Id": "cpu_time_active_instance", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_active", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_active_instance_Response", "ReturnData": True}]
2. 动态生成查询时确保Id唯一
如果通过代码动态生成metrics_data_queries,可以通过以下方式保证Id唯一:
- 为每个查询添加递增序号(如
cpu_time_idle_1、cpu_time_idle_2) - 拼接维度值到Id中(比如将
cpu维度的cpu0拼接到Id末尾) - 使用UUID生成唯一字符串作为Id
示例代码片段:
import uuid # 动态生成查询项 queries = [] # 单CPU查询 single_cpu_query = { "Id": f"cpu_time_idle_{uuid.uuid4().hex[:8]}", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_idle", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}, {"Name": "cpu", "Value": "cpu0"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_idle_cpu0_Response", "ReturnData": True } queries.append(single_cpu_query) # 实例汇总查询 instance_query = { "Id": f"cpu_time_idle_{uuid.uuid4().hex[:8]}", "MetricStat": {"Metric": {"Namespace": "CWAgent", "MetricName": "cpu_time_idle", "Dimensions": [{"Name": "InstanceId", "Value": "i-XXXX"}]}, "Period": 6000, "Stat": "Average"}, "Label": "cpu_time_idle_instance_Response", "ReturnData": True } queries.append(instance_query)
3. 按需精简查询(可选)
如果不需要同时获取单CPU和实例汇总的指标,可以根据业务需求只保留其中一种查询,既避免重复Id问题,又减少查询开销。
内容的提问来源于stack exchange,提问作者Santosh Kumar Sahoo
相关产品推荐
相关产品推荐

