From b7f91579abc218b95c4219fd5cca9f3056d7527a Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 24 Mar 2022 12:28:46 -0600 Subject: [PATCH] Add drop aggregation (#2544) --- .../opentelemetry/sdk/_metrics/aggregation.py | 15 +++++++++++ .../metrics/test_metric_reader_storage.py | 24 +++++++++++++++++ .../metrics/test_view_instrument_match.py | 26 +++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py b/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py index 23596112fd4..420385c69ca 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py @@ -54,6 +54,14 @@ def collect(self) -> Optional[_PointVarT]: pass +class _DropAggregation(_Aggregation): + def aggregate(self, measurement: Measurement) -> None: + pass + + def collect(self) -> Optional[_PointVarT]: + pass + + class _SumAggregation(_Aggregation[Sum]): def __init__( self, @@ -378,3 +386,10 @@ def _create_aggregation(self, instrument: Instrument) -> _Aggregation: class LastValueAggregation(_AggregationFactory): def _create_aggregation(self, instrument: Instrument) -> _Aggregation: return _LastValueAggregation() + + +class DropAggregation(_AggregationFactory): + """Using this aggregation will make all measurements be ignored.""" + + def _create_aggregation(self, instrument: Instrument) -> _Aggregation: + return _DropAggregation() diff --git a/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py b/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py index 936aa0433f7..d73cf893a99 100644 --- a/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py +++ b/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py @@ -14,12 +14,15 @@ from unittest.mock import Mock, patch +from opentelemetry.sdk._metrics.aggregation import DropAggregation +from opentelemetry.sdk._metrics.instrument import Counter from opentelemetry.sdk._metrics.measurement import Measurement from opentelemetry.sdk._metrics.metric_reader_storage import ( MetricReaderStorage, ) from opentelemetry.sdk._metrics.point import AggregationTemporality from opentelemetry.sdk._metrics.sdk_configuration import SdkConfiguration +from opentelemetry.sdk._metrics.view import View from opentelemetry.test.concurrency_test import ConcurrencyTestBase, MockFunc @@ -217,3 +220,24 @@ def test_default_view_disabled(self, MockViewInstrumentMatch: Mock): MockViewInstrumentMatch.call_args_list.clear() storage.consume_measurement(Measurement(1, instrument2)) self.assertEqual(len(MockViewInstrumentMatch.call_args_list), 0) + + def test_drop_aggregation(self): + + counter = Counter("name", Mock(), Mock()) + metric_reader_storage = MetricReaderStorage( + SdkConfiguration( + resource=Mock(), + metric_readers=(), + views=( + View( + instrument_name="name", aggregation=DropAggregation() + ), + ), + enable_default_view=False, + ) + ) + metric_reader_storage.consume_measurement(Measurement(1, counter)) + + self.assertEqual( + [], metric_reader_storage.collect(AggregationTemporality.DELTA) + ) diff --git a/opentelemetry-sdk/tests/metrics/test_view_instrument_match.py b/opentelemetry-sdk/tests/metrics/test_view_instrument_match.py index c366309b415..210963d5471 100644 --- a/opentelemetry-sdk/tests/metrics/test_view_instrument_match.py +++ b/opentelemetry-sdk/tests/metrics/test_view_instrument_match.py @@ -18,6 +18,10 @@ from opentelemetry.sdk._metrics._view_instrument_match import ( _ViewInstrumentMatch, ) +from opentelemetry.sdk._metrics.aggregation import ( + DropAggregation, + _DropAggregation, +) from opentelemetry.sdk._metrics.measurement import Measurement from opentelemetry.sdk._metrics.point import AggregationTemporality, Metric from opentelemetry.sdk._metrics.sdk_configuration import SdkConfiguration @@ -129,6 +133,28 @@ def test_consume_measurement(self): {frozenset({}): self.mock_created_aggregation}, ) + # Test that a drop aggregation is handled in the same way as any + # other aggregation. + drop_aggregation = DropAggregation() + + view_instrument_match = _ViewInstrumentMatch( + view=View( + instrument_name="instrument1", + name="name", + aggregation=drop_aggregation, + attribute_keys={}, + ), + instrument=instrument1, + sdk_config=sdk_config, + ) + view_instrument_match.consume_measurement( + Measurement(value=0, instrument=instrument1, attributes=None) + ) + self.assertIsInstance( + view_instrument_match._attributes_aggregation[frozenset({})], + _DropAggregation, + ) + def test_collect(self): instrument1 = Mock( name="instrument1", description="description", unit="unit"