Repository: open-telemetry/opentelemetry-python

Issue:
Sum not being reset on `AggreagationTempoarlity.DELTA` Histograms
**Describe your environment** 

- Python 3.8.10
- Ubuntu 20.04
- OTel Python Metrics SDK v0.29b0

**Steps to reproduce**

Here's an example that exports to the console:

```
from opentelemetry import _metrics
from opentelemetry.sdk._metrics import MeterProvider
from opentelemetry.sdk._metrics.export import PeriodicExportingMetricReader, ConsoleMetricExporter
from opentelemetry.sdk._metrics.point import AggregationTemporality


class DeltaConsoleMetricExporter(ConsoleMetricExporter):
    @property
    def preferred_temporality(self) -> AggregationTemporality:
        return AggregationTemporality.DELTA

if __name__ == '__main__':
    reader = PeriodicExportingMetricReader(
            export_interval_millis=3600000,
            exporter=DeltaConsoleMetricExporter())

    _metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))

    meter = _metrics.get_meter("my.meter")

    my_instrument = meter.create_histogram(
        name="my.instrument",
    )

    my_instrument.record(10)
    reader.collect()
    my_instrument.record(10)
    reader.collect()
    my_instrument.record(10)
    reader.collect()
```

**What is the expected behavior?**

`sum` should not carry over from the last collection cycle to the next, should be `10` on every export.

**What is the actual behavior?**

`sum` carries over from the previous collection cycle to the next.

Console Output from the example above:
```
{"attributes": "", "description": "", "instrumentation_info": "InstrumentationInfo(my.meter, , None)", "name": "my.instrument", "resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.10.0', 'service.name': 'unknown_service'}, maxlen=None)", "unit": "", "point": {"start_time_unix_nano": 1647361426978696864, "time_unix_nano": 1647361426978710755, "bucket_counts": [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], "explicit_bounds": [0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0], "sum": 10, "aggregation_temporality": 1}}
{"attributes": "", "description": "", "instrumentation_info": "InstrumentationInfo(my.meter, , None)", "name": "my.instrument", "resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.10.0', 'service.name': 'unknown_service'}, maxlen=None)", "unit": "", "point": {"start_time_unix_nano": 1647361426978710756, "time_unix_nano": 1647361427004077424, "bucket_counts": [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], "explicit_bounds": [0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0], "sum": 20, "aggregation_temporality": 1}}
{"attributes": "", "description": "", "instrumentation_info": "InstrumentationInfo(my.meter, , None)", "name": "my.instrument", "resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.10.0', 'service.name': 'unknown_service'}, maxlen=None)", "unit": "", "point": {"start_time_unix_nano": 1647361427004077425, "time_unix_nano": 1647361427004196751, "bucket_counts": [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], "explicit_bounds": [0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0], "sum": 30, "aggregation_temporality": 1}}
{"attributes": "", "description": "", "instrumentation_info": "InstrumentationInfo(my.meter, , None)", "name": "my.instrument", "resource": "BoundedAttributes({'telemetry.sdk.language': 'python', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.10.0', 'service.name': 'unknown_service'}, maxlen=None)", "unit": "", "point": {"start_time_unix_nano": 1647361427004196752, "time_unix_nano": 1647361427004373526, "bucket_counts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "explicit_bounds": [0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0], "sum": 30, "aggregation_temporality": 1}}
```

`sum` is kept over multiple collection cycles while bucket count is being reset.



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
@@ -191,9 +191,11 @@ def collect(self) -> Histogram:
         with self._lock:
             value = self._bucket_counts
             start_time_unix_nano = self._start_time_unix_nano
+            histogram_sum = self._sum
 
             self._bucket_counts = self._get_empty_bucket_counts()
             self._start_time_unix_nano = now + 1
+            self._sum = 0
 
         return Histogram(
             start_time_unix_nano=start_time_unix_nano,
@@ -201,7 +203,7 @@ def collect(self) -> Histogram:
             bucket_counts=tuple(value),
             explicit_bounds=self._boundaries,
             aggregation_temporality=AggregationTemporality.DELTA,
-            sum=self._sum,
+            sum=histogram_sum,
         )
 
 


Test patch:
diff --git a/opentelemetry-sdk/tests/metrics/test_aggregation.py b/opentelemetry-sdk/tests/metrics/test_aggregation.py
--- a/opentelemetry-sdk/tests/metrics/test_aggregation.py
+++ b/opentelemetry-sdk/tests/metrics/test_aggregation.py
@@ -286,6 +286,7 @@ def test_collect(self):
         first_histogram = explicit_bucket_histogram_aggregation.collect()
 
         self.assertEqual(first_histogram.bucket_counts, (0, 1, 0, 0))
+        self.assertEqual(first_histogram.sum, 1)
 
         # CI fails the last assertion without this
         sleep(0.1)
@@ -294,6 +295,7 @@ def test_collect(self):
         second_histogram = explicit_bucket_histogram_aggregation.collect()
 
         self.assertEqual(second_histogram.bucket_counts, (0, 1, 0, 0))
+        self.assertEqual(second_histogram.sum, 1)
 
         self.assertGreater(
             second_histogram.time_unix_nano, first_histogram.time_unix_nano