Skip to content

Commit 428fd63

Browse files
committed
Add test for cumulative async series reappearance; clarify DropAggregator epoch
- Test that when a cumulative async series stops reporting for a collection cycle and then reappears, its start time is anchored to the collection immediately preceding its reappearance (not instrument creation time). - Add comment to DropAggregator.HANDLE explaining why creationEpochNanos=0 is safe (the handle never produces data points). Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
1 parent 4301663 commit 428fd63

2 files changed

Lines changed: 70 additions & 1 deletion

File tree

sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DropAggregator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@ public List<? extends ExemplarData> getExemplars() {
5252

5353
public static final Aggregator<PointData> INSTANCE = new DropAggregator();
5454

55+
// creationEpochNanos is 0 because DropAggregator never produces data points, so
56+
// the start timestamp is irrelevant. A single shared HANDLE is safe to use.
5557
private static final AggregatorHandle<PointData> HANDLE =
5658
new AggregatorHandle<PointData>(
57-
0, ExemplarReservoirFactory.noSamples(), /* isDoubleType= */ true) {
59+
/* creationEpochNanos= */ 0, ExemplarReservoirFactory.noSamples(), /* isDoubleType= */ true) {
5860
@Override
5961
protected PointData doAggregateThenMaybeResetDoubles(
6062
long startEpochNanos,

sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/state/AsynchronousMetricStorageTest.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,73 @@ void collect_CumulativeReportsCumulativeObservations(MemoryMode memoryMode) {
335335
.hasAttributes(Attributes.builder().put("key", "value2").build())));
336336
}
337337

338+
@ParameterizedTest
339+
@EnumSource(MemoryMode.class)
340+
void collect_CumulativeSeriesDisappearsAndReappears(MemoryMode memoryMode) {
341+
setup(memoryMode);
342+
343+
Attributes attrA = Attributes.empty();
344+
Attributes attrB = Attributes.builder().put("key", "b").build();
345+
346+
// Collection 1: both series reported. start time = instrument creation time (START_SECOND_NANOS)
347+
testClock.advance(Duration.ofSeconds(10));
348+
longCounterStorage.record(attrA, 1);
349+
longCounterStorage.record(attrB, 2);
350+
assertThat(longCounterStorage.collect(resource, scope, testClock.now()))
351+
.hasLongSumSatisfying(
352+
sum ->
353+
sum.isCumulative()
354+
.hasPointsSatisfying(
355+
point ->
356+
point
357+
.hasStartEpochNanos(START_SECOND_NANOS)
358+
.hasAttributes(attrA)
359+
.hasValue(1),
360+
point ->
361+
point
362+
.hasStartEpochNanos(START_SECOND_NANOS)
363+
.hasAttributes(attrB)
364+
.hasValue(2)));
365+
registeredReader.setLastCollectEpochNanos(testClock.now());
366+
367+
// Collection 2: only attrA reported; attrB disappears and its handle is removed.
368+
testClock.advance(Duration.ofSeconds(10));
369+
longCounterStorage.record(attrA, 3);
370+
assertThat(longCounterStorage.collect(resource, scope, testClock.now()))
371+
.hasLongSumSatisfying(
372+
sum ->
373+
sum.isCumulative()
374+
.hasPointsSatisfying(
375+
point ->
376+
point
377+
.hasStartEpochNanos(START_SECOND_NANOS)
378+
.hasAttributes(attrA)
379+
.hasValue(3)));
380+
registeredReader.setLastCollectEpochNanos(testClock.now());
381+
long collectTime2 = testClock.now();
382+
383+
// Collection 3: attrB reappears. Its start time should be the time of the collection
384+
// immediately preceding its reappearance (collectTime2), not the original creation time.
385+
testClock.advance(Duration.ofSeconds(10));
386+
longCounterStorage.record(attrA, 5);
387+
longCounterStorage.record(attrB, 7);
388+
assertThat(longCounterStorage.collect(resource, scope, testClock.now()))
389+
.hasLongSumSatisfying(
390+
sum ->
391+
sum.isCumulative()
392+
.hasPointsSatisfying(
393+
point ->
394+
point
395+
.hasStartEpochNanos(START_SECOND_NANOS)
396+
.hasAttributes(attrA)
397+
.hasValue(5),
398+
point ->
399+
point
400+
.hasStartEpochNanos(collectTime2)
401+
.hasAttributes(attrB)
402+
.hasValue(7)));
403+
}
404+
338405
@ParameterizedTest
339406
@EnumSource(MemoryMode.class)
340407
void collect_DeltaComputesDiff(MemoryMode memoryMode) {

0 commit comments

Comments
 (0)