Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class TemporalMetricStorage
// Lock while building metrics
mutable opentelemetry::common::SpinLockMutex lock_;
const AggregationConfig *aggregation_config_;
opentelemetry::common::SystemTimestamp last_delta_collection_ts_;
bool has_last_delta_collection_ts_ = false;
};
} // namespace metrics
} // namespace sdk
Expand Down
8 changes: 7 additions & 1 deletion sdk/src/metrics/state/temporal_metric_storage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector,
// no other reader configured to collect those data.
if (collectors.size() == 1 && aggregation_temporarily == AggregationTemporality::kDelta)
{
if (!has_last_delta_collection_ts_)
{
last_delta_collection_ts_ = sdk_start_ts;
has_last_delta_collection_ts_ = true;
}
// If no metrics, early return
if (delta_metrics->Size() == 0)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the empty-collection path, the function early-returns when delta_metrics->Size() == 0 before updating last_delta_collection_ts_. If a cycle at t2 is empty and the next cycle at t3 has data, the emitted point will carry start_ts = t1 (the last non-empty collection) rather than t2, even though the delta map only contains activity from (t2, t3]. Successive delta windows then overlap instead of abutting, which violates the OTel data model's requirement that start_ts(n) == end_ts(n-1) and causes rate computations (value / (end - start)) to under-report. The slow path doesn't have this issue because last_reported_metrics_[collector].collection_ts is updated on every call, including empty ones.

{
Expand All @@ -63,8 +68,9 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector,
MetricData metric_data;
metric_data.instrument_descriptor = instrument_descriptor_;
metric_data.aggregation_temporality = AggregationTemporality::kDelta;
metric_data.start_ts = sdk_start_ts;
metric_data.start_ts = last_delta_collection_ts_;
metric_data.end_ts = collection_ts;
last_delta_collection_ts_ = collection_ts;

// Direct conversion of delta metrics to point data
delta_metrics->GetAllEntries(
Expand Down
Loading