From 140cd977887f5228124016099496e266fed44443 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 12:24:23 -0600 Subject: [PATCH 1/8] Add meter to observers Fixes #1424 --- .../tests/test_otlp_metric_exporter.py | 112 +++++++++++---- .../src/opentelemetry/sdk/metrics/__init__.py | 29 +++- .../tests/metrics/test_metrics.py | 132 +++++++++--------- opentelemetry-sdk/tests/metrics/test_view.py | 10 +- 4 files changed, 185 insertions(+), 98 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py index c255d91ec70..96710b86324 100644 --- a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py +++ b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py @@ -15,7 +15,7 @@ import os from collections import OrderedDict from unittest import TestCase -from unittest.mock import patch +from unittest.mock import Mock, patch from grpc import ChannelCredentials @@ -41,7 +41,7 @@ from opentelemetry.proto.resource.v1.resource_pb2 import ( Resource as OTLPResource, ) -from opentelemetry.sdk.metrics import Counter, MeterProvider +from opentelemetry.sdk.metrics import Counter, MeterProvider, SumObserver from opentelemetry.sdk.metrics.export import ExportRecord from opentelemetry.sdk.metrics.export.aggregate import SumAggregator from opentelemetry.sdk.resources import Resource as SDKResource @@ -50,26 +50,12 @@ class TestOTLPMetricExporter(TestCase): - @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") - def setUp(self, mock_time_ns): # pylint: disable=arguments-differ - mock_time_ns.configure_mock(**{"return_value": 1}) + def setUp(self): # pylint: disable=arguments-differ self.exporter = OTLPMetricsExporter(insecure=True) - resource = SDKResource(OrderedDict([("a", 1), ("b", False)])) - - self.counter_export_record = ExportRecord( - Counter( - "c", - "d", - "e", - int, - MeterProvider(resource=resource,).get_meter("name", "version"), - ("f",), - ), - [("g", "h")], - SumAggregator(), - resource, + self.resource = SDKResource(OrderedDict([("a", 1), ("b", False)])) + self.meter = MeterProvider(resource=self.resource,).get_meter( + "name", "version" ) - Configuration._reset() # pylint: disable=protected-access def tearDown(self): @@ -102,12 +88,86 @@ def test_no_credentials_error(self): with self.assertRaises(ValueError): OTLPMetricsExporter() - def test_translate_metrics(self): - # pylint: disable=no-member + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_counter_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + + counter_export_record = ExportRecord( + Counter("c", "d", "e", int, self.meter, ("f",),), + [("g", "h")], + SumAggregator(), + self.resource, + ) + + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 + + expected = ExportMetricsServiceRequest( + resource_metrics=[ + ResourceMetrics( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_metrics=[ + InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), + metrics=[ + OTLPMetric( + name="c", + description="d", + unit="e", + int_sum=IntSum( + data_points=[ + IntDataPoint( + labels=[ + StringKeyValue( + key="g", value="h" + ) + ], + value=1, + time_unix_nano=1, + start_time_unix_nano=1, + ) + ], + aggregation_temporality=( + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE + ), + is_monotonic=True, + ), + ) + ], + ) + ], + ) + ] + ) + + # pylint: disable=protected-access + actual = self.exporter._translate_data([counter_export_record]) + + self.assertEqual(expected, actual) + + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_sum_observer_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + counter_export_record = ExportRecord( + SumObserver(Mock(), "c", "d", "e", int, self.meter, ("f",),), + [("g", "h")], + SumAggregator(), + self.resource, + ) - self.counter_export_record.aggregator.checkpoint = 1 - self.counter_export_record.aggregator.initial_checkpoint_timestamp = 1 - self.counter_export_record.aggregator.last_update_timestamp = 1 + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 expected = ExportMetricsServiceRequest( resource_metrics=[ @@ -157,6 +217,6 @@ def test_translate_metrics(self): ) # pylint: disable=protected-access - actual = self.exporter._translate_data([self.counter_export_record]) + actual = self.exporter._translate_data([counter_export_record]) self.assertEqual(expected, actual) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py index a2d16719a82..a09047e5231 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py @@ -241,6 +241,7 @@ def __init__( description: str, unit: str, value_type: Type[metrics_api.ValueT], + meter: "Accumulator", label_keys: Sequence[str] = (), enabled: bool = True, ): @@ -249,6 +250,7 @@ def __init__( self.description = description self.unit = unit self.value_type = value_type + self.meter = meter self.label_keys = label_keys self.enabled = enabled @@ -477,7 +479,14 @@ def register_sumobserver( enabled: bool = True, ) -> metrics_api.SumObserver: ob = SumObserver( - callback, name, description, unit, value_type, label_keys, enabled + callback, + name, + description, + unit, + value_type, + self, + label_keys, + enabled, ) with self.observers_lock: self.observers.add(ob) @@ -494,7 +503,14 @@ def register_updownsumobserver( enabled: bool = True, ) -> metrics_api.UpDownSumObserver: ob = UpDownSumObserver( - callback, name, description, unit, value_type, label_keys, enabled + callback, + name, + description, + unit, + value_type, + self, + label_keys, + enabled, ) with self.observers_lock: self.observers.add(ob) @@ -511,7 +527,14 @@ def register_valueobserver( enabled: bool = True, ) -> metrics_api.ValueObserver: ob = ValueObserver( - callback, name, description, unit, value_type, label_keys, enabled + callback, + name, + description, + unit, + value_type, + self, + label_keys, + enabled, ) with self.observers_lock: self.observers.add(ob) diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 58cc195cdfa..37d95c08c5c 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -13,7 +13,7 @@ # limitations under the License. import unittest -from unittest import mock +from unittest.mock import Mock, patch from opentelemetry import metrics as metrics_api from opentelemetry.sdk import metrics, resources @@ -41,7 +41,7 @@ def test_resource_empty(self): self.assertEqual(meter_provider.resource, resources._DEFAULT_RESOURCE) def test_start_pipeline(self): - exporter = mock.Mock() + exporter = Mock() meter_provider = metrics.MeterProvider() meter = meter_provider.get_meter(__name__) # pylint: disable=protected-access @@ -53,8 +53,8 @@ def test_start_pipeline(self): meter_provider.shutdown() def test_shutdown(self): - controller = mock.Mock() - exporter = mock.Mock() + controller = Mock() + exporter = Mock() meter_provider = metrics.MeterProvider() # pylint: disable=protected-access meter_provider._controllers = [controller] @@ -72,7 +72,7 @@ def test_extends_api(self): def test_collect_metrics(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock counter = meter.create_counter("name", "desc", "unit", float,) labels = {"key1": "value1"} @@ -83,14 +83,14 @@ def test_collect_metrics(self): def test_collect_no_metrics(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock meter.collect() self.assertFalse(processor_mock.process.called) def test_collect_not_registered(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock counter = metrics.Counter("name", "desc", "unit", float, meter) labels = {"key1": "value1"} @@ -100,7 +100,7 @@ def test_collect_not_registered(self): def test_collect_disabled_metric(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock counter = metrics.Counter("name", "desc", "unit", float, meter, False) labels = {"key1": "value1"} @@ -111,7 +111,7 @@ def test_collect_disabled_metric(self): def test_collect_observers(self): meter = metrics.MeterProvider().get_meter(__name__) - processor_mock = mock.Mock() + processor_mock = Mock() meter.processor = processor_mock def callback(observer): @@ -154,7 +154,7 @@ def test_record_batch(self): ) def test_create_counter(self): - resource = mock.Mock(spec=resources.Resource) + resource = Mock(spec=resources.Resource) meter_provider = metrics.MeterProvider(resource=resource) meter = meter_provider.get_meter(__name__) counter = meter.create_counter("name", "desc", "unit", int,) @@ -186,7 +186,7 @@ def test_create_valuerecorder(self): def test_register_sumobserver(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_sumobserver( callback, "name", "desc", "unit", int, @@ -206,7 +206,7 @@ def test_register_sumobserver(self): def test_register_updownsumobserver(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_updownsumobserver( callback, "name", "desc", "unit", int, @@ -226,7 +226,7 @@ def test_register_updownsumobserver(self): def test_register_valueobserver(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_valueobserver( callback, "name", "desc", "unit", int, @@ -246,7 +246,7 @@ def test_register_valueobserver(self): def test_unregister_observer(self): meter = metrics.MeterProvider().get_meter(__name__) - callback = mock.Mock() + callback = Mock() observer = meter.register_valueobserver( callback, "name", "desc", "unit", int, metrics.ValueObserver @@ -286,7 +286,7 @@ def test_add(self): metric.add(2, labels) self.assertEqual(bound_mock.view_datas.pop().aggregator.current, 5) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_add_non_decreasing_int_error(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Counter("name", "desc", "unit", int, meter) @@ -300,7 +300,7 @@ def test_add_non_decreasing_int_error(self, logger_mock): self.assertEqual(bound_counter.view_datas.pop().aggregator.current, 3) self.assertEqual(logger_mock.warning.call_count, 1) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_add_non_decreasing_float_error(self, logger_mock): meter = metrics.MeterProvider().get_meter(__name__) metric = metrics.Counter("name", "desc", "unit", float, meter) @@ -351,7 +351,7 @@ def test_record(self): class TestSumObserver(unittest.TestCase): def test_observe(self): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) @@ -363,26 +363,26 @@ def test_observe(self): def test_observe_disabled(self): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), False + None, "name", "desc", "unit", int, Mock(), ("key",), False ) labels = {"key": "value"} observer.observe(37, labels) self.assertEqual(len(observer.aggregators), 0) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_incorrect_type(self, logger_mock): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37.0, labels) self.assertEqual(len(observer.aggregators), 0) self.assertTrue(logger_mock.warning.called) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_non_decreasing_error(self, logger_mock): observer = metrics.SumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37, labels) @@ -391,21 +391,21 @@ def test_observe_non_decreasing_error(self, logger_mock): self.assertTrue(logger_mock.warning.called) def test_run(self): - callback = mock.Mock() + callback = Mock() observer = metrics.SumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), True ) self.assertTrue(observer.run()) callback.assert_called_once_with(observer) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_run_exception(self, logger_mock): - callback = mock.Mock() + callback = Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.SumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), True ) self.assertFalse(observer.run()) @@ -415,7 +415,7 @@ def test_run_exception(self, logger_mock): class TestUpDownSumObserver(unittest.TestCase): def test_observe(self): observer = metrics.UpDownSumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) @@ -427,16 +427,16 @@ def test_observe(self): def test_observe_disabled(self): observer = metrics.UpDownSumObserver( - None, "name", "desc", "unit", int, ("key",), False + None, "name", "desc", "unit", int, Mock(), ("key",), False ) labels = {"key": "value"} observer.observe(37, labels) self.assertEqual(len(observer.aggregators), 0) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_incorrect_type(self, logger_mock): observer = metrics.UpDownSumObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37.0, labels) @@ -444,21 +444,21 @@ def test_observe_incorrect_type(self, logger_mock): self.assertTrue(logger_mock.warning.called) def test_run(self): - callback = mock.Mock() + callback = Mock() observer = metrics.UpDownSumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), True ) self.assertTrue(observer.run()) callback.assert_called_once_with(observer) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_run_exception(self, logger_mock): - callback = mock.Mock() + callback = Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.UpDownSumObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), True ) self.assertFalse(observer.run()) @@ -468,7 +468,7 @@ def test_run_exception(self, logger_mock): class TestValueObserver(unittest.TestCase): def test_observe(self): observer = metrics.ValueObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} key_labels = metrics.get_dict_as_key(labels) @@ -484,16 +484,16 @@ def test_observe(self): def test_observe_disabled(self): observer = metrics.ValueObserver( - None, "name", "desc", "unit", int, ("key",), False + None, "name", "desc", "unit", int, Mock(), ("key",), False ) labels = {"key": "value"} observer.observe(37, labels) self.assertEqual(len(observer.aggregators), 0) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_observe_incorrect_type(self, logger_mock): observer = metrics.ValueObserver( - None, "name", "desc", "unit", int, ("key",), True + None, "name", "desc", "unit", int, Mock(), ("key",), True ) labels = {"key": "value"} observer.observe(37.0, labels) @@ -501,21 +501,21 @@ def test_observe_incorrect_type(self, logger_mock): self.assertTrue(logger_mock.warning.called) def test_run(self): - callback = mock.Mock() + callback = Mock() observer = metrics.ValueObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), True ) self.assertTrue(observer.run()) callback.assert_called_once_with(observer) - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_run_exception(self, logger_mock): - callback = mock.Mock() + callback = Mock() callback.side_effect = Exception("We have a problem!") observer = metrics.ValueObserver( - callback, "name", "desc", "unit", int, (), True + callback, "name", "desc", "unit", int, Mock(), True ) self.assertFalse(observer.run()) @@ -525,40 +525,40 @@ def test_run_exception(self, logger_mock): # pylint: disable=no-self-use class TestBoundCounter(unittest.TestCase): def test_add(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = int metric_mock.meter = meter_mock bound_metric = metrics.BoundCounter((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_metric.view_datas = [view_datas_mock] bound_metric.add(3) view_datas_mock.record.assert_called_once_with(3) def test_add_disabled(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = False metric_mock.value_type = int metric_mock.meter = meter_mock bound_metric = metrics.BoundCounter((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_metric.view_datas = [view_datas_mock] bound_metric.add(3) view_datas_mock.record.update_view.assert_not_called() - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_add_incorrect_type(self, logger_mock): - meter_mock = mock.Mock() - viewm_mock = mock.Mock() + meter_mock = Mock() + viewm_mock = Mock() meter_mock.view_manager = viewm_mock - metric_mock = mock.Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = float metric_mock.meter = meter_mock bound_metric = metrics.BoundCounter((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_metric.view_datas = [view_datas_mock] bound_metric.add(3) view_datas_mock.record.update_view.assert_not_called() @@ -567,38 +567,38 @@ def test_add_incorrect_type(self, logger_mock): class TestBoundValueRecorder(unittest.TestCase): def test_record(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = int metric_mock.meter = meter_mock bound_valuerecorder = metrics.BoundValueRecorder((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_valuerecorder.view_datas = [view_datas_mock] bound_valuerecorder.record(3) view_datas_mock.record.assert_called_once_with(3) def test_record_disabled(self): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = False metric_mock.value_type = int metric_mock.meter = meter_mock bound_valuerecorder = metrics.BoundValueRecorder((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_valuerecorder.view_datas = [view_datas_mock] bound_valuerecorder.record(3) view_datas_mock.record.update_view.assert_not_called() - @mock.patch("opentelemetry.sdk.metrics.logger") + @patch("opentelemetry.sdk.metrics.logger") def test_record_incorrect_type(self, logger_mock): - meter_mock = mock.Mock() - metric_mock = mock.Mock() + meter_mock = Mock() + metric_mock = Mock() metric_mock.enabled = True metric_mock.value_type = float metric_mock.meter = meter_mock bound_valuerecorder = metrics.BoundValueRecorder((), metric_mock) - view_datas_mock = mock.Mock() + view_datas_mock = Mock() bound_valuerecorder.view_datas = [view_datas_mock] bound_valuerecorder.record(3) view_datas_mock.record.update_view.assert_not_called() diff --git a/opentelemetry-sdk/tests/metrics/test_view.py b/opentelemetry-sdk/tests/metrics/test_view.py index 102db6da255..c20d6ed3c48 100644 --- a/opentelemetry-sdk/tests/metrics/test_view.py +++ b/opentelemetry-sdk/tests/metrics/test_view.py @@ -43,12 +43,14 @@ def test_default_aggregator(self, logger_mock): self.assertEqual( view.get_default_aggregator(ud_counter), aggregate.SumAggregator ) - observer = metrics.SumObserver(lambda: None, "", "", "1", int) + observer = metrics.SumObserver(lambda: None, "", "", "1", int, meter) self.assertEqual( view.get_default_aggregator(observer), aggregate.LastValueAggregator, ) - ud_observer = metrics.SumObserver(lambda: None, "", "", "1", int) + ud_observer = metrics.SumObserver( + lambda: None, "", "", "1", int, meter + ) self.assertEqual( view.get_default_aggregator(ud_observer), aggregate.LastValueAggregator, @@ -58,7 +60,9 @@ def test_default_aggregator(self, logger_mock): view.get_default_aggregator(recorder), aggregate.MinMaxSumCountAggregator, ) - v_observer = metrics.ValueObserver(lambda: None, "", "", "1", int) + v_observer = metrics.ValueObserver( + lambda: None, "", "", "1", int, meter + ) self.assertEqual( view.get_default_aggregator(v_observer), aggregate.ValueObserverAggregator, From f28a5f288952a9dc5bd51f45424205bbd0f7d1f3 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 13:23:33 -0600 Subject: [PATCH 2/8] Add missing parameters --- opentelemetry-sdk/tests/metrics/test_metrics.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 37d95c08c5c..1697d8e6c85 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -393,7 +393,7 @@ def test_observe_non_decreasing_error(self, logger_mock): def test_run(self): callback = Mock() observer = metrics.SumObserver( - callback, "name", "desc", "unit", int, Mock(), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertTrue(observer.run()) @@ -405,7 +405,7 @@ def test_run_exception(self, logger_mock): callback.side_effect = Exception("We have a problem!") observer = metrics.SumObserver( - callback, "name", "desc", "unit", int, Mock(), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertFalse(observer.run()) @@ -446,7 +446,7 @@ def test_observe_incorrect_type(self, logger_mock): def test_run(self): callback = Mock() observer = metrics.UpDownSumObserver( - callback, "name", "desc", "unit", int, Mock(), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertTrue(observer.run()) @@ -458,7 +458,7 @@ def test_run_exception(self, logger_mock): callback.side_effect = Exception("We have a problem!") observer = metrics.UpDownSumObserver( - callback, "name", "desc", "unit", int, Mock(), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertFalse(observer.run()) @@ -503,7 +503,7 @@ def test_observe_incorrect_type(self, logger_mock): def test_run(self): callback = Mock() observer = metrics.ValueObserver( - callback, "name", "desc", "unit", int, Mock(), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertTrue(observer.run()) @@ -515,7 +515,7 @@ def test_run_exception(self, logger_mock): callback.side_effect = Exception("We have a problem!") observer = metrics.ValueObserver( - callback, "name", "desc", "unit", int, Mock(), True + callback, "name", "desc", "unit", int, Mock(), (), True ) self.assertFalse(observer.run()) From 4433ddb05ebe34f5fa3fbda014f612f0e8f378ae Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 15:01:28 -0600 Subject: [PATCH 3/8] Add UpDownCounter test --- .../tests/test_otlp_metric_exporter.py | 77 ++++++++++++++++++- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py index 96710b86324..69fd5ac0afc 100644 --- a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py +++ b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py @@ -41,7 +41,9 @@ from opentelemetry.proto.resource.v1.resource_pb2 import ( Resource as OTLPResource, ) -from opentelemetry.sdk.metrics import Counter, MeterProvider, SumObserver +from opentelemetry.sdk.metrics import ( + Counter, MeterProvider, SumObserver, UpDownCounter +) from opentelemetry.sdk.metrics.export import ExportRecord from opentelemetry.sdk.metrics.export.aggregate import SumAggregator from opentelemetry.sdk.resources import Resource as SDKResource @@ -138,7 +140,8 @@ def test_translate_counter_export_record(self, mock_time_ns): ) ], aggregation_temporality=( - AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE + AggregationTemporality. + AGGREGATION_TEMPORALITY_CUMULATIVE ), is_monotonic=True, ), @@ -204,7 +207,8 @@ def test_translate_sum_observer_export_record(self, mock_time_ns): ) ], aggregation_temporality=( - AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE + AggregationTemporality. + AGGREGATION_TEMPORALITY_CUMULATIVE ), is_monotonic=True, ), @@ -220,3 +224,70 @@ def test_translate_sum_observer_export_record(self, mock_time_ns): actual = self.exporter._translate_data([counter_export_record]) self.assertEqual(expected, actual) + + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_updowncounter_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + + counter_export_record = ExportRecord( + UpDownCounter("c", "d", "e", int, self.meter, ("f",),), + [("g", "h")], + SumAggregator(), + self.resource, + ) + + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 + + expected = ExportMetricsServiceRequest( + resource_metrics=[ + ResourceMetrics( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_metrics=[ + InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), + metrics=[ + OTLPMetric( + name="c", + description="d", + unit="e", + int_sum=IntSum( + data_points=[ + IntDataPoint( + labels=[ + StringKeyValue( + key="g", value="h" + ) + ], + value=1, + time_unix_nano=1, + start_time_unix_nano=1, + ) + ], + aggregation_temporality=( + AggregationTemporality. + AGGREGATION_TEMPORALITY_CUMULATIVE + ), + ), + ) + ], + ) + ], + ) + ] + ) + + # pylint: disable=protected-access + actual = self.exporter._translate_data([counter_export_record]) + + self.assertEqual(expected, actual) From cf653f8f3344583adb5b69c0b00a2c8a9f5493f7 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 16:06:45 -0600 Subject: [PATCH 4/8] Add more tests --- .../tests/test_otlp_metric_exporter.py | 79 ++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py index 69fd5ac0afc..3e9679b8ca6 100644 --- a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py +++ b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py @@ -42,10 +42,17 @@ Resource as OTLPResource, ) from opentelemetry.sdk.metrics import ( - Counter, MeterProvider, SumObserver, UpDownCounter + Counter, + MeterProvider, + SumObserver, + UpDownCounter, + UpDownSumObserver, + ValueRecorder ) from opentelemetry.sdk.metrics.export import ExportRecord -from opentelemetry.sdk.metrics.export.aggregate import SumAggregator +from opentelemetry.sdk.metrics.export.aggregate import ( + SumAggregator, MinMaxSumCountAggregator +) from opentelemetry.sdk.resources import Resource as SDKResource THIS_DIR = os.path.dirname(__file__) @@ -230,7 +237,73 @@ def test_translate_updowncounter_export_record(self, mock_time_ns): mock_time_ns.configure_mock(**{"return_value": 1}) counter_export_record = ExportRecord( - UpDownCounter("c", "d", "e", int, self.meter, ("f",),), + UpDownCounter("c", "d", "e", int, self.meter), + [("g", "h")], + SumAggregator(), + self.resource, + ) + + counter_export_record.aggregator.checkpoint = 1 + counter_export_record.aggregator.initial_checkpoint_timestamp = 1 + counter_export_record.aggregator.last_update_timestamp = 1 + + expected = ExportMetricsServiceRequest( + resource_metrics=[ + ResourceMetrics( + resource=OTLPResource( + attributes=[ + KeyValue(key="a", value=AnyValue(int_value=1)), + KeyValue( + key="b", value=AnyValue(bool_value=False) + ), + ] + ), + instrumentation_library_metrics=[ + InstrumentationLibraryMetrics( + instrumentation_library=InstrumentationLibrary( + name="name", version="version", + ), + metrics=[ + OTLPMetric( + name="c", + description="d", + unit="e", + int_sum=IntSum( + data_points=[ + IntDataPoint( + labels=[ + StringKeyValue( + key="g", value="h" + ) + ], + value=1, + time_unix_nano=1, + start_time_unix_nano=1, + ) + ], + aggregation_temporality=( + AggregationTemporality. + AGGREGATION_TEMPORALITY_CUMULATIVE + ), + ), + ) + ], + ) + ], + ) + ] + ) + + # pylint: disable=protected-access + actual = self.exporter._translate_data([counter_export_record]) + + self.assertEqual(expected, actual) + + @patch("opentelemetry.sdk.metrics.export.aggregate.time_ns") + def test_translate_updownsum_observer_export_record(self, mock_time_ns): + mock_time_ns.configure_mock(**{"return_value": 1}) + counter_export_record = ExportRecord( + UpDownSumObserver(Mock(), "c", "d", "e", int, self.meter, ("f",),), [("g", "h")], SumAggregator(), self.resource, From 5d9aa3a8addb7f2f979e99b4e1901bbfd5745048 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 16:13:49 -0600 Subject: [PATCH 5/8] Fix lint --- .../tests/test_otlp_metric_exporter.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py index 3e9679b8ca6..6d45e30d440 100644 --- a/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py +++ b/exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py @@ -47,12 +47,9 @@ SumObserver, UpDownCounter, UpDownSumObserver, - ValueRecorder ) from opentelemetry.sdk.metrics.export import ExportRecord -from opentelemetry.sdk.metrics.export.aggregate import ( - SumAggregator, MinMaxSumCountAggregator -) +from opentelemetry.sdk.metrics.export.aggregate import SumAggregator from opentelemetry.sdk.resources import Resource as SDKResource THIS_DIR = os.path.dirname(__file__) @@ -147,8 +144,7 @@ def test_translate_counter_export_record(self, mock_time_ns): ) ], aggregation_temporality=( - AggregationTemporality. - AGGREGATION_TEMPORALITY_CUMULATIVE + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE ), is_monotonic=True, ), @@ -214,8 +210,7 @@ def test_translate_sum_observer_export_record(self, mock_time_ns): ) ], aggregation_temporality=( - AggregationTemporality. - AGGREGATION_TEMPORALITY_CUMULATIVE + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE ), is_monotonic=True, ), @@ -282,8 +277,7 @@ def test_translate_updowncounter_export_record(self, mock_time_ns): ) ], aggregation_temporality=( - AggregationTemporality. - AGGREGATION_TEMPORALITY_CUMULATIVE + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE ), ), ) @@ -348,8 +342,7 @@ def test_translate_updownsum_observer_export_record(self, mock_time_ns): ) ], aggregation_temporality=( - AggregationTemporality. - AGGREGATION_TEMPORALITY_CUMULATIVE + AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE ), ), ) From b6e0f4431f625e9d59a6e6315a91c19c8dd19abc Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 16:17:04 -0600 Subject: [PATCH 6/8] Fix CHANGELOGs --- exporter/opentelemetry-exporter-otlp/CHANGELOG.md | 3 +++ opentelemetry-sdk/CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md index 6f45b4413ca..bbb3b3d3831 100644 --- a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md +++ b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Add meter to observers + ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) + ## Version 0.16b0 Released 2020-11-25 diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 3b5e72131e4..88cd94f4689 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Add meter to observers + ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) + ## Version 0.16b0 Released 2020-11-25 From 52acc9fbbb494e1b82bdd62b83e4ac258e604ade Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 16:27:03 -0600 Subject: [PATCH 7/8] Update exporter/opentelemetry-exporter-otlp/CHANGELOG.md Co-authored-by: Leighton Chen --- exporter/opentelemetry-exporter-otlp/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md index bbb3b3d3831..4528c215345 100644 --- a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md +++ b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -- Add meter to observers +- Add meter reference to observers ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) ## Version 0.16b0 From 5998084515bfa05955a70af9179b74725a61dd10 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Thu, 26 Nov 2020 16:27:13 -0600 Subject: [PATCH 8/8] Update opentelemetry-sdk/CHANGELOG.md Co-authored-by: Leighton Chen --- opentelemetry-sdk/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 88cd94f4689..0e0b0f550f9 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -- Add meter to observers +- Add meter reference to observers ([#1425](https://github.com/open-telemetry/opentelemetry-python/pull/1425)) ## Version 0.16b0