@@ -249,11 +249,15 @@ func (me *monitoringExporter) recordToTimeSeriesPb(m otelmetricdata.Metrics) ([]
249249 tss = append (tss , ts )
250250 }
251251 case otelmetricdata.Sum [int64 ]:
252+ kind := googlemetricpb .MetricDescriptor_CUMULATIVE
253+ if ! a .IsMonotonic {
254+ kind = googlemetricpb .MetricDescriptor_GAUGE
255+ }
252256 for _ , point := range a .DataPoints {
253257 metric , mr := me .recordToMetricAndMonitoredResourcePbs (m , point .Attributes )
254258 var ts * monitoringpb.TimeSeries
255259 var err error
256- ts , err = sumToTimeSeries [int64 ](point , m , mr )
260+ ts , err = sumToTimeSeries [int64 ](point , m , mr , kind )
257261 if err != nil {
258262 errs = append (errs , err )
259263 continue
@@ -267,16 +271,16 @@ func (me *monitoringExporter) recordToTimeSeriesPb(m otelmetricdata.Metrics) ([]
267271 return tss , errors .Join (errs ... )
268272}
269273
270- func sumToTimeSeries [N int64 | float64 ](point otelmetricdata.DataPoint [N ], metrics otelmetricdata.Metrics , mr * monitoredrespb.MonitoredResource ) (* monitoringpb.TimeSeries , error ) {
271- interval , err := toNonemptyTimeIntervalpb (point .StartTime , point .Time )
274+ func sumToTimeSeries [N int64 | float64 ](point otelmetricdata.DataPoint [N ], metrics otelmetricdata.Metrics , mr * monitoredrespb.MonitoredResource , kind googlemetricpb. MetricDescriptor_MetricKind ) (* monitoringpb.TimeSeries , error ) {
275+ interval , err := toTimeIntervalPb (point .StartTime , point .Time , kind )
272276 if err != nil {
273277 return nil , err
274278 }
275279 value , valueType := numberDataPointToValue [N ](point )
276280 return & monitoringpb.TimeSeries {
277281 Resource : mr ,
278282 Unit : string (metrics .Unit ),
279- MetricKind : googlemetricpb . MetricDescriptor_CUMULATIVE ,
283+ MetricKind : kind ,
280284 ValueType : valueType ,
281285 Points : []* monitoringpb.Point {{
282286 Interval : interval ,
@@ -286,7 +290,7 @@ func sumToTimeSeries[N int64 | float64](point otelmetricdata.DataPoint[N], metri
286290}
287291
288292func histogramToTimeSeries [N int64 | float64 ](point otelmetricdata.HistogramDataPoint [N ], metrics otelmetricdata.Metrics , mr * monitoredrespb.MonitoredResource ) (* monitoringpb.TimeSeries , error ) {
289- interval , err := toNonemptyTimeIntervalpb (point .StartTime , point .Time )
293+ interval , err := toTimeIntervalPb (point .StartTime , point .Time , googlemetricpb . MetricDescriptor_CUMULATIVE )
290294 if err != nil {
291295 return nil , err
292296 }
@@ -307,13 +311,20 @@ func histogramToTimeSeries[N int64 | float64](point otelmetricdata.HistogramData
307311 }, nil
308312}
309313
310- func toNonemptyTimeIntervalpb (start , end time.Time ) (* monitoringpb.TimeInterval , error ) {
311- // The end time of a new interval must be at least a millisecond after the end time of the
312- // previous interval, for all non-gauge types.
313- // https://cloud.google.com/monitoring/api/ref_v3/rpc/google.monitoring.v3#timeinterval
314- if end .Sub (start ).Milliseconds () <= 1 {
315- end = start .Add (time .Millisecond )
314+ func toTimeIntervalPb (start , end time.Time , kind googlemetricpb.MetricDescriptor_MetricKind ) (* monitoringpb.TimeInterval , error ) {
315+ if kind == googlemetricpb .MetricDescriptor_GAUGE {
316+ // Same as https://github.com/googleapis/java-bigtable/pull/2719
317+ start = end
318+ } else { // CUMULATIVE or other types
319+ // The end time of a new interval must be at least a millisecond after the end time of the
320+ // previous interval for CUMULATIVE types.
321+ // https://cloud.google.com/monitoring/api/ref_v3/rpc/google.monitoring.v3#timeinterval
322+
323+ if end .Sub (start ) < time .Millisecond {
324+ end = start .Add (time .Millisecond )
325+ }
316326 }
327+
317328 startpb := timestamppb .New (start )
318329 endpb := timestamppb .New (end )
319330 err := errors .Join (
0 commit comments