diff --git a/java/google/registry/monitoring/metrics/StackdriverWriter.java b/java/google/registry/monitoring/metrics/StackdriverWriter.java index 0b3e72fbd..0c715525d 100644 --- a/java/google/registry/monitoring/metrics/StackdriverWriter.java +++ b/java/google/registry/monitoring/metrics/StackdriverWriter.java @@ -51,6 +51,7 @@ import java.util.logging.Logger; import javax.annotation.concurrent.NotThreadSafe; import javax.inject.Inject; import javax.inject.Named; +import org.joda.time.DateTime; import org.joda.time.Interval; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; @@ -264,10 +265,17 @@ public class StackdriverWriter implements MetricWriter { return descriptor; } - private static TimeInterval encodeTimeInterval(Interval nativeInterval) { - return new TimeInterval() - .setEndTime(DATETIME_FORMATTER.print(nativeInterval.getEnd())) - .setStartTime(DATETIME_FORMATTER.print(nativeInterval.getStart())); + private static TimeInterval encodeTimeInterval(Interval nativeInterval, Kind metricKind) { + + TimeInterval encodedInterval = + new TimeInterval().setStartTime(DATETIME_FORMATTER.print(nativeInterval.getStart())); + + DateTime endTimestamp = + nativeInterval.toDurationMillis() == 0 && metricKind != Kind.GAUGE + ? nativeInterval.getEnd().plusMillis(1) + : nativeInterval.getEnd(); + + return encodedInterval.setEndTime(DATETIME_FORMATTER.print(endTimestamp)); } private static BucketOptions encodeBucketOptions(DistributionFitter fitter) { @@ -363,7 +371,9 @@ public class StackdriverWriter implements MetricWriter { } Point encodedPoint = - new Point().setInterval(encodeTimeInterval(point.interval())).setValue(encodedValue); + new Point() + .setInterval(encodeTimeInterval(point.interval(), metric.getMetricSchema().kind())) + .setValue(encodedValue); List encodedLabels = descriptor.getLabels(); // The MetricDescriptors returned by the GCM API have null fields rather than empty lists diff --git a/javatests/google/registry/monitoring/metrics/StackdriverWriterTest.java b/javatests/google/registry/monitoring/metrics/StackdriverWriterTest.java index f71c6e760..66b3b8cc1 100644 --- a/javatests/google/registry/monitoring/metrics/StackdriverWriterTest.java +++ b/javatests/google/registry/monitoring/metrics/StackdriverWriterTest.java @@ -310,12 +310,13 @@ public class StackdriverWriterTest { } @Test - public void getEncodedTimeSeries_simplePoint_encodes() throws Exception { + public void getEncodedTimeSeries_cumulativeMetricPoint_ZeroInterval_encodesGreaterEndTime() + throws Exception { StackdriverWriter writer = new StackdriverWriter(client, PROJECT, MONITORED_RESOURCE, MAX_QPS, MAX_POINTS_PER_REQUEST); MetricPoint nativePoint = MetricPoint.create( - metric, ImmutableList.of("foo"), new Instant(1336), new Instant(1337), 10L); + metric, ImmutableList.of("foo"), new Instant(1337), new Instant(1337), 10L); TimeSeries timeSeries = writer.getEncodedTimeSeries(nativePoint); @@ -325,8 +326,59 @@ public class StackdriverWriterTest { assertThat(points).hasSize(1); Point point = points.get(0); assertThat(point.getValue().getInt64Value()).isEqualTo(10L); + assertThat(point.getInterval().getStartTime()).isEqualTo("1970-01-01T00:00:01.337Z"); + assertThat(point.getInterval().getEndTime()).isEqualTo("1970-01-01T00:00:01.338Z"); + } + + @Test + public void getEncodedTimeSeries_cumulativeMetricPoint_nonZeroInterval_encodesSameInterval() + throws Exception { + StackdriverWriter writer = + new StackdriverWriter(client, PROJECT, MONITORED_RESOURCE, MAX_QPS, MAX_POINTS_PER_REQUEST); + MetricPoint nativePoint = + MetricPoint.create( + metric, ImmutableList.of("foo"), new Instant(1337), new Instant(1339), 10L); + + TimeSeries timeSeries = writer.getEncodedTimeSeries(nativePoint); + + assertThat(timeSeries.getValueType()).isEqualTo("INT64"); + assertThat(timeSeries.getMetricKind()).isEqualTo("CUMULATIVE"); + List points = timeSeries.getPoints(); + assertThat(points).hasSize(1); + Point point = points.get(0); + assertThat(point.getValue().getInt64Value()).isEqualTo(10L); + assertThat(point.getInterval().getStartTime()).isEqualTo("1970-01-01T00:00:01.337Z"); + assertThat(point.getInterval().getEndTime()).isEqualTo("1970-01-01T00:00:01.339Z"); + } + + @Test + public void getEncodedTimeSeries_gaugeMetricPoint_zeroInterval_encodesSameInterval() + throws Exception { + StackdriverWriter writer = + new StackdriverWriter(client, PROJECT, MONITORED_RESOURCE, MAX_QPS, MAX_POINTS_PER_REQUEST); + Metric metric = + new StoredMetric<>( + "/name", + "desc", + "vdn", + ImmutableSet.of(LabelDescriptor.create("label", "description")), + Long.class); + when(metricDescriptorCreate.execute()) + .thenReturn(StackdriverWriter.createMetricDescriptor(metric)); + MetricPoint nativePoint = + MetricPoint.create( + metric, ImmutableList.of("foo"), new Instant(1337), new Instant(1337), 10L); + + TimeSeries timeSeries = writer.getEncodedTimeSeries(nativePoint); + + assertThat(timeSeries.getValueType()).isEqualTo("INT64"); + assertThat(timeSeries.getMetricKind()).isEqualTo("GAUGE"); + List points = timeSeries.getPoints(); + assertThat(points).hasSize(1); + Point point = points.get(0); + assertThat(point.getValue().getInt64Value()).isEqualTo(10L); + assertThat(point.getInterval().getStartTime()).isEqualTo("1970-01-01T00:00:01.337Z"); assertThat(point.getInterval().getEndTime()).isEqualTo("1970-01-01T00:00:01.337Z"); - assertThat(point.getInterval().getStartTime()).isEqualTo("1970-01-01T00:00:01.336Z"); } @Test