def collect(self) -> Optional[Sum]: """ Atomically return a point for the current value of the metric and reset the aggregation value. """ now = _time_ns() if self._instrument_temporality is AggregationTemporality.DELTA: with self._lock: value = self._value start_time_unix_nano = self._start_time_unix_nano self._value = 0 self._start_time_unix_nano = now + 1 return Sum( aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=self._instrument_is_monotonic, start_time_unix_nano=start_time_unix_nano, time_unix_nano=now, value=value, ) if self._value is None: return None return Sum( aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=self._instrument_is_monotonic, start_time_unix_nano=self._start_time_unix_nano, time_unix_nano=now, value=self._value, )
def test_current_point_sum_current_point_same_aggregation_temporality( self, ): current_point = Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ) self.assertEqual( _convert_aggregation_temporality( Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=False, ), current_point, AggregationTemporality.DELTA, ), current_point, ) current_point = Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=False, ) self.assertEqual( _convert_aggregation_temporality( Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=False, ), current_point, AggregationTemporality.CUMULATIVE, ), current_point, )
def _generate_sum(name, val) -> Sum: return _generate_metric( name, Sum( aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=True, start_time_unix_nano=1641946015139533244, time_unix_nano=1641946016139533244, value=val, ), )
def test_previous_point_non_cumulative(self): with self.assertRaises(Exception): _convert_aggregation_temporality( Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ), Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ), AggregationTemporality.DELTA, ),
def test_current_point_sum_previous_point_none(self): current_point = Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ) self.assertEqual( _convert_aggregation_temporality( None, current_point, AggregationTemporality.CUMULATIVE), replace( current_point, aggregation_temporality=AggregationTemporality.CUMULATIVE, ), )
def test_mismatched_point_types(self): current_point = Sum( start_time_unix_nano=0, time_unix_nano=0, value=0, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ) with self.assertLogs(level=WARNING): self.assertIs( _convert_aggregation_temporality( Gauge(time_unix_nano=0, value=0), current_point, AggregationTemporality.DELTA, ), current_point, )
def _convert_aggregation_temporality( previous_point: Optional[_PointVarT], current_point: _PointVarT, aggregation_temporality: AggregationTemporality, ) -> _PointVarT: """Converts `current_point` to the requested `aggregation_temporality` given the `previous_point`. `previous_point` must have `CUMULATIVE` temporality. `current_point` may have `DELTA` or `CUMULATIVE` temporality. The output point will have temporality `aggregation_temporality`. Since `GAUGE` points have no temporality, they are returned unchanged. """ current_point_type = type(current_point) if current_point_type is Gauge: return current_point if previous_point is not None and type(previous_point) is not type( current_point): _logger.warning( "convert_aggregation_temporality called with mismatched " "point types: %s and %s", type(previous_point), current_point_type, ) return current_point if current_point_type is Sum: if previous_point is None: # Output CUMULATIVE for a synchronous instrument # There is no previous value, return the delta point as a # cumulative return replace(current_point, aggregation_temporality=aggregation_temporality) if previous_point.aggregation_temporality is not ( AggregationTemporality.CUMULATIVE): raise Exception( "previous_point aggregation temporality must be CUMULATIVE") if current_point.aggregation_temporality is aggregation_temporality: # Output DELTA for a synchronous instrument # Output CUMULATIVE for an asynchronous instrument return current_point if aggregation_temporality is AggregationTemporality.DELTA: # Output temporality DELTA for an asynchronous instrument value = current_point.value - previous_point.value output_start_time_unix_nano = previous_point.time_unix_nano else: # Output CUMULATIVE for a synchronous instrument value = current_point.value + previous_point.value output_start_time_unix_nano = previous_point.start_time_unix_nano is_monotonic = (previous_point.is_monotonic and current_point.is_monotonic) return Sum( start_time_unix_nano=output_start_time_unix_nano, time_unix_nano=current_point.time_unix_nano, value=value, aggregation_temporality=aggregation_temporality, is_monotonic=is_monotonic, ) return None
def test_current_point_sum_aggregation_temporality_cumulative(self): self.assertEqual( _convert_aggregation_temporality( Sum( start_time_unix_nano=1, time_unix_nano=2, value=3, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=False, ), Sum( start_time_unix_nano=4, time_unix_nano=5, value=6, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ), AggregationTemporality.CUMULATIVE, ), Sum( start_time_unix_nano=1, time_unix_nano=5, value=9, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=False, ), ) self.assertEqual( _convert_aggregation_temporality( Sum( start_time_unix_nano=1, time_unix_nano=2, value=3, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=True, ), Sum( start_time_unix_nano=4, time_unix_nano=5, value=6, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=False, ), AggregationTemporality.CUMULATIVE, ), Sum( start_time_unix_nano=1, time_unix_nano=5, value=9, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=False, ), ) self.assertEqual( _convert_aggregation_temporality( Sum( start_time_unix_nano=1, time_unix_nano=2, value=3, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=True, ), Sum( start_time_unix_nano=4, time_unix_nano=5, value=6, aggregation_temporality=AggregationTemporality.DELTA, is_monotonic=True, ), AggregationTemporality.CUMULATIVE, ), Sum( start_time_unix_nano=1, time_unix_nano=5, value=9, aggregation_temporality=AggregationTemporality.CUMULATIVE, is_monotonic=True, ), )
def shutdown(self): self._shutdown = True metrics_list = [ Metric( name="sum_name", attributes={}, description="", instrumentation_info=None, resource=Resource.create(), unit="", point=Sum( start_time_unix_nano=_time_ns(), time_unix_nano=_time_ns(), value=2, aggregation_temporality=1, is_monotonic=True, ), ), Metric( name="gauge_name", attributes={}, description="", instrumentation_info=None, resource=Resource.create(), unit="", point=Gauge( time_unix_nano=_time_ns(), value=2, ),