Skip to content

Meter::Collect could return 1 less aggregated metric than the declared cardinality limit #3638

@ThomsonTan

Description

@ThomsonTan

In TemporalMetricStorage::buildMetrics, the attribute hash map is copied into a dedicated collection hash map through GetAllEntries, but since std::unordered_map provides no deterministic iteration order, the traversal sequence is undefined. As a result, if kOverflowAttributes happens to be visited early, the final attribute in the iteration—which should not be kOverflowAttributes because it has already been processed—may be skipped, since the last bucket is always reserved for kOverflowAttributes. This creates a subtle correctness issue when copying attributes into the collection map.

agg_hashmap->GetAllEnteries(
[&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) {
auto agg = merged_metrics->Get(attributes);
if (agg)
{
merged_metrics->Set(attributes, agg->Merge(aggregation));
}
else
{
merged_metrics->Set(attributes,
DefaultAggregation::CreateAggregation(
aggregation_type_, instrument_descriptor_, aggregation_config_)
->Merge(aggregation));
}
return true;
});

Here is the function which could have issue when copying attribute hash map, IsOverflowAttributes doesn't check the actual attribute is kOverflowAttributes and treat it as a regular attribute. Adding a proper check for kOverflowAttributes in this function would prevent incorrect handling and ensure that all valid attributes are reliably copied during collection.

Aggregation *GetOrSetDefault(
const MetricAttributes &attributes,
nostd::function_ref<std::unique_ptr<Aggregation>()> aggregation_callback)
{
auto it = hash_map_.find(attributes);
if (it != hash_map_.end())
{
return it->second.get();
}
if (IsOverflowAttributes())
{
return GetOrSetOveflowAttributes(aggregation_callback);
}
hash_map_[attributes] = aggregation_callback();
return hash_map_[attributes].get();
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingtriage/acceptedIndicates an issue or PR is ready to be actively worked on.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions