Repository: open-telemetry/opentelemetry-python

Issue:
Implement Drop aggregation
See [Drop aggregation](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#drop-aggregation)

> The Drop Aggregation informs the SDK to ignore/drop all Instrument Measurements for this Aggregation.

This is a bit of a special case. The implementation should probably avoid creating a `ViewInstrumentMatch` altogether when we encounter this aggregation to save memory.


Discussion:

Resolving patch:
diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py b/opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py
--- 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()


Test patch:
diff --git a/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py b/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py
--- 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
--- 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"