Summary
In the Azure Monitor metricset's batch path, GroupAndStoreMetrics constructs a ResDefGroupingCriteria struct but never populates the Aggregations field (client_batch.go:272-279). The field exists in the struct (client_batch.go:35) but is always left as the zero value ("").
As a result, metrics configured with different aggregations (e.g. one resource configured for Average and another for Maximum) are placed in the same batch group. When GetMetricsInBatch fires, it uses batchMetrics[0].Aggregations for the entire group (client_batch.go:198), silently discarding the aggregation settings of every other metric in the group.
Affected code
x-pack/metricbeat/module/azure/client_batch.go:35 — Aggregations string field exists in ResDefGroupingCriteria
x-pack/metricbeat/module/azure/client_batch.go:272-279 — GroupAndStoreMetrics constructs the struct literal without assigning Aggregations
x-pack/metricbeat/module/azure/client_batch.go:198 — batchMetrics[0].Aggregations used as the aggregation for the whole group
Steps to reproduce
- Configure the azure
monitor metricset with enable_batch_api: true.
- Define two or more
ResourceConfig entries (or resources within the same config) that specify different aggregations for the same metric namespace. For example:
- metricset: monitor
period: 5m
enable_batch_api: true
resources:
- resource_query: "resourceType eq 'Microsoft.Compute/virtualMachines'"
metrics:
- name: ["Percentage CPU"]
namespace: "Microsoft.Compute/virtualMachines"
aggregations: ["Average"]
- name: ["Percentage CPU"]
namespace: "Microsoft.Compute/virtualMachines"
aggregations: ["Maximum"]
- Run Metricbeat and observe the collected events.
Expected behaviour
Events should contain both Average and Maximum values for Percentage CPU, collected in separate batch calls grouped by aggregation type.
Actual behaviour
Both metrics land in the same batch group (because the grouping key has Aggregations: ""). The batch call uses only the first metric's aggregation. The second aggregation is never queried. No error is logged — the data loss is silent.
Fix
Set Aggregations: metric.Aggregations in the ResDefGroupingCriteria struct literal at client_batch.go:272. The field already exists in the struct; it just needs to be populated.
criteria := ResDefGroupingCriteria{
Namespace: metric.Namespace,
SubscriptionID: metric.SubscriptionId,
Location: metric.Location,
Names: strings.Join(metric.Names, ","),
TimeGrain: metric.TimeGrain,
Dimensions: getDimensionKey(metric.Dimensions),
Aggregations: metric.Aggregations, // add this line
}
Note: fixing this will split groups that previously shared a bucket, potentially increasing API call count for configurations that mix aggregations — which is the correct behaviour.
Summary
In the Azure Monitor metricset's batch path,
GroupAndStoreMetricsconstructs aResDefGroupingCriteriastruct but never populates theAggregationsfield (client_batch.go:272-279). The field exists in the struct (client_batch.go:35) but is always left as the zero value ("").As a result, metrics configured with different aggregations (e.g. one resource configured for
Averageand another forMaximum) are placed in the same batch group. WhenGetMetricsInBatchfires, it usesbatchMetrics[0].Aggregationsfor the entire group (client_batch.go:198), silently discarding the aggregation settings of every other metric in the group.Affected code
x-pack/metricbeat/module/azure/client_batch.go:35—Aggregations stringfield exists inResDefGroupingCriteriax-pack/metricbeat/module/azure/client_batch.go:272-279—GroupAndStoreMetricsconstructs the struct literal without assigningAggregationsx-pack/metricbeat/module/azure/client_batch.go:198—batchMetrics[0].Aggregationsused as the aggregation for the whole groupSteps to reproduce
monitormetricset withenable_batch_api: true.ResourceConfigentries (or resources within the same config) that specify different aggregations for the same metric namespace. For example:Expected behaviour
Events should contain both
AverageandMaximumvalues forPercentage CPU, collected in separate batch calls grouped by aggregation type.Actual behaviour
Both metrics land in the same batch group (because the grouping key has
Aggregations: ""). The batch call uses only the first metric's aggregation. The second aggregation is never queried. No error is logged — the data loss is silent.Fix
Set
Aggregations: metric.Aggregationsin theResDefGroupingCriteriastruct literal atclient_batch.go:272. The field already exists in the struct; it just needs to be populated.Note: fixing this will split groups that previously shared a bucket, potentially increasing API call count for configurations that mix aggregations — which is the correct behaviour.