diff --git a/docs/examples/basic_meter/basic_metrics.py b/docs/examples/basic_meter/basic_metrics.py index 5d137bf01e4..6e8a5c040f3 100644 --- a/docs/examples/basic_meter/basic_metrics.py +++ b/docs/examples/basic_meter/basic_metrics.py @@ -24,7 +24,7 @@ import time from opentelemetry import metrics -from opentelemetry.sdk.metrics import Counter, Measure, MeterProvider +from opentelemetry.sdk.metrics import Counter, MeterProvider, ValueRecorder from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter from opentelemetry.sdk.metrics.export.controller import PushController @@ -80,7 +80,7 @@ def usage(argv): description="size of requests", unit="1", value_type=int, - metric_type=Measure, + metric_type=ValueRecorder, label_keys=("environment",), ) diff --git a/docs/examples/basic_meter/calling_conventions.py b/docs/examples/basic_meter/calling_conventions.py index 15b57fdafcb..f8cc3dddbb1 100644 --- a/docs/examples/basic_meter/calling_conventions.py +++ b/docs/examples/basic_meter/calling_conventions.py @@ -19,7 +19,7 @@ import time from opentelemetry import metrics -from opentelemetry.sdk.metrics import Counter, Measure, MeterProvider +from opentelemetry.sdk.metrics import Counter, MeterProvider, ValueRecorder from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter from opentelemetry.sdk.metrics.export.controller import PushController @@ -43,7 +43,7 @@ description="size of requests", unit="1", value_type=int, - metric_type=Measure, + metric_type=ValueRecorder, label_keys=("environment",), ) diff --git a/ext/opentelemetry-ext-opencensusexporter/tests/test_otcollector_metrics_exporter.py b/ext/opentelemetry-ext-opencensusexporter/tests/test_otcollector_metrics_exporter.py index 63ea28cd935..18b4a328067 100644 --- a/ext/opentelemetry-ext-opencensusexporter/tests/test_otcollector_metrics_exporter.py +++ b/ext/opentelemetry-ext-opencensusexporter/tests/test_otcollector_metrics_exporter.py @@ -23,8 +23,8 @@ from opentelemetry.ext.opencensusexporter import metrics_exporter from opentelemetry.sdk.metrics import ( Counter, - Measure, MeterProvider, + ValueRecorder, get_labels_as_key, ) from opentelemetry.sdk.metrics.export import ( @@ -76,7 +76,7 @@ def test_get_collector_metric_type(self): ) self.assertIs(result, metrics_pb2.MetricDescriptor.CUMULATIVE_DOUBLE) result = metrics_exporter.get_collector_metric_type( - Measure("testName", "testDescription", "unit", None, None) + ValueRecorder("testName", "testDescription", "unit", None, None) ) self.assertIs(result, metrics_pb2.MetricDescriptor.UNSPECIFIED) @@ -88,8 +88,8 @@ def test_get_collector_point(self): float_counter = self._meter.create_metric( "testName", "testDescription", "unit", float, Counter ) - measure = self._meter.create_metric( - "testName", "testDescription", "unit", float, Measure + valuerecorder = self._meter.create_metric( + "testName", "testDescription", "unit", float, ValueRecorder ) result = metrics_exporter.get_collector_point( MetricRecord(aggregator, self._key_labels, int_counter) @@ -106,7 +106,7 @@ def test_get_collector_point(self): self.assertRaises( TypeError, metrics_exporter.get_collector_point( - MetricRecord(aggregator, self._key_labels, measure) + MetricRecord(aggregator, self._key_labels, valuerecorder) ), ) diff --git a/ext/opentelemetry-ext-prometheus/src/opentelemetry/ext/prometheus/__init__.py b/ext/opentelemetry-ext-prometheus/src/opentelemetry/ext/prometheus/__init__.py index f6f91fc5868..cc44621ac48 100644 --- a/ext/opentelemetry-ext-prometheus/src/opentelemetry/ext/prometheus/__init__.py +++ b/ext/opentelemetry-ext-prometheus/src/opentelemetry/ext/prometheus/__init__.py @@ -79,7 +79,7 @@ UnknownMetricFamily, ) -from opentelemetry.metrics import Counter, Measure, Metric +from opentelemetry.metrics import Counter, Metric, ValueRecorder from opentelemetry.sdk.metrics.export import ( MetricRecord, MetricsExporter, @@ -164,7 +164,7 @@ def _translate_to_prometheus(self, metric_record: MetricRecord): labels=label_values, value=metric_record.aggregator.checkpoint ) # TODO: Add support for histograms when supported in OT - elif isinstance(metric_record.metric, Measure): + elif isinstance(metric_record.metric, ValueRecorder): prometheus_metric = UnknownMetricFamily( name=metric_name, documentation=metric_record.metric.description, diff --git a/opentelemetry-api/CHANGELOG.md b/opentelemetry-api/CHANGELOG.md index 386bd75d470..4b678cd4226 100644 --- a/opentelemetry-api/CHANGELOG.md +++ b/opentelemetry-api/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Rename Measure to ValueRecorder in metrics + ([#761](https://github.com/open-telemetry/opentelemetry-python/pull/761)) + ## 0.8b0 Released 2020-05-27 diff --git a/opentelemetry-api/src/opentelemetry/metrics/__init__.py b/opentelemetry-api/src/opentelemetry/metrics/__init__.py index b7ad62adb2e..a91a4ce7b76 100644 --- a/opentelemetry-api/src/opentelemetry/metrics/__init__.py +++ b/opentelemetry-api/src/opentelemetry/metrics/__init__.py @@ -19,16 +19,13 @@ The `Meter` class is used to construct `Metric` s to record raw statistics as well as metrics with predefined aggregation. +`Meter` s can be obtained via the `MeterProvider`, corresponding to the name +of the instrumenting library and (optionally) a version. + See the `metrics api`_ spec for terminology and context clarification. .. _metrics api: - https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-metrics.md - -.. versionadded:: 0.1.0 -.. versionchanged:: 0.5.0 - ``meter_provider`` was replaced by `get_meter_provider`, - ``set_preferred_meter_provider_implementation`` was replaced by - `set_meter_provider`. + https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/metrics/api.md """ import abc from logging import getLogger @@ -54,7 +51,7 @@ def add(self, value: ValueT) -> None: """ def record(self, value: ValueT) -> None: - """No-op implementation of `BoundMeasure` record. + """No-op implementation of `BoundValueRecorder` record. Args: value: The value to record to the bound metric instrument. @@ -73,12 +70,12 @@ def add(self, value: ValueT) -> None: """ -class BoundMeasure: +class BoundValueRecorder: def record(self, value: ValueT) -> None: - """Records the given ``value`` to this bound measure. + """Records the given ``value`` to this bound valuerecorder. Args: - value: The value to record to the bound measure. + value: The value to record to the bound valuerecorder. """ @@ -94,12 +91,7 @@ def bind(self, labels: Dict[str, str]) -> "object": """Gets a bound metric instrument. Bound metric instruments are useful to reduce the cost of repeatedly - recording a metric with a pre-defined set of label values. All metric - kinds (counter, measure) support declaring a set of required label - keys. The values corresponding to these keys should be specified in - every bound metric instrument. "Unspecified" label values, in cases - where a bound metric instrument is requested but a value was not - provided are permitted. + recording a metric with a pre-defined set of label values. Args: labels: Labels to associate with the bound instrument. @@ -126,10 +118,10 @@ def add(self, value: ValueT, labels: Dict[str, str]) -> None: """ def record(self, value: ValueT, labels: Dict[str, str]) -> None: - """No-op implementation of `Measure` record. + """No-op implementation of `ValueRecorder` record. Args: - value: The value to record to this measure metric. + value: The value to record to this valuerecorder metric. labels: Labels to associate with the bound instrument. """ @@ -150,21 +142,18 @@ def add(self, value: ValueT, labels: Dict[str, str]) -> None: """ -class Measure(Metric): - """A measure type metric that represent raw stats that are recorded. - - Measure metrics represent raw statistics that are recorded. - """ +class ValueRecorder(Metric): + """A valuerecorder type metric that represent raw stats.""" - def bind(self, labels: Dict[str, str]) -> "BoundMeasure": - """Gets a `BoundMeasure`.""" - return BoundMeasure() + def bind(self, labels: Dict[str, str]) -> "BoundValueRecorder": + """Gets a `BoundValueRecorder`.""" + return BoundValueRecorder() def record(self, value: ValueT, labels: Dict[str, str]) -> None: - """Records the ``value`` to the measure. + """Records the ``value`` to the valuerecorder. Args: - value: The value to record to this measure metric. + value: The value to record to this valuerecorder metric. labels: Labels to associate with the bound instrument. """ @@ -251,7 +240,7 @@ def get_meter( return DefaultMeter() -MetricT = TypeVar("MetricT", Counter, Measure, Observer) +MetricT = TypeVar("MetricT", Counter, ValueRecorder, Observer) ObserverCallbackT = Callable[[Observer], None] @@ -259,9 +248,9 @@ def get_meter( class Meter(abc.ABC): """An interface to allow the recording of metrics. - `Metric` s are used for recording pre-defined aggregation (counter), - or raw values (measure) in which the aggregation and labels - for the exported metric are deferred. + `Metric` s or metric instruments, are devices used for capturing raw + measurements. Each metric instrument supports a single method, each with + fixed interpretation to capture measurements. """ @abc.abstractmethod diff --git a/opentelemetry-api/tests/metrics/test_metrics.py b/opentelemetry-api/tests/metrics/test_metrics.py index 3e760d3d98b..897c7492e42 100644 --- a/opentelemetry-api/tests/metrics/test_metrics.py +++ b/opentelemetry-api/tests/metrics/test_metrics.py @@ -35,14 +35,14 @@ def test_counter_add(self): counter = metrics.Counter() counter.add(1, {}) - def test_measure(self): - measure = metrics.Measure() - bound_measure = measure.bind({}) - self.assertIsInstance(bound_measure, metrics.BoundMeasure) + def test_valuerecorder(self): + valuerecorder = metrics.ValueRecorder() + bound_valuerecorder = valuerecorder.bind({}) + self.assertIsInstance(bound_valuerecorder, metrics.BoundValueRecorder) - def test_measure_record(self): - measure = metrics.Measure() - measure.record(1, {}) + def test_valuerecorder_record(self): + valuerecorder = metrics.ValueRecorder() + valuerecorder.record(1, {}) def test_default_bound_metric(self): bound_instrument = metrics.DefaultBoundInstrument() @@ -52,9 +52,9 @@ def test_bound_counter(self): bound_counter = metrics.BoundCounter() bound_counter.add(1) - def test_bound_measure(self): - bound_measure = metrics.BoundMeasure() - bound_measure.record(1) + def test_bound_valuerecorder(self): + bound_valuerecorder = metrics.BoundValueRecorder() + bound_valuerecorder.record(1) def test_observer(self): observer = metrics.DefaultObserver() diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 50ea751e15d..29aaed01dcc 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Rename Measure to ValueRecorder in metrics + ([#761](https://github.com/open-telemetry/opentelemetry-python/pull/761)) + ## 0.8b0 Released 2020-05-27 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py index 1d35648fd35..b9284bae9fe 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py @@ -97,9 +97,9 @@ def add(self, value: metrics_api.ValueT) -> None: self.update(value) -class BoundMeasure(metrics_api.BoundMeasure, BaseBoundInstrument): +class BoundValueRecorder(metrics_api.BoundValueRecorder, BaseBoundInstrument): def record(self, value: metrics_api.ValueT) -> None: - """See `opentelemetry.metrics.BoundMeasure.record`.""" + """See `opentelemetry.metrics.BoundValueRecorder.record`.""" if self._validate_update(value): self.update(value) @@ -174,15 +174,15 @@ def add(self, value: metrics_api.ValueT, labels: Dict[str, str]) -> None: UPDATE_FUNCTION = add -class Measure(Metric, metrics_api.Measure): - """See `opentelemetry.metrics.Measure`.""" +class ValueRecorder(Metric, metrics_api.ValueRecorder): + """See `opentelemetry.metrics.ValueRecorder`.""" - BOUND_INSTR_TYPE = BoundMeasure + BOUND_INSTR_TYPE = BoundValueRecorder def record( self, value: metrics_api.ValueT, labels: Dict[str, str] ) -> None: - """See `opentelemetry.metrics.Measure.record`.""" + """See `opentelemetry.metrics.ValueRecorder.record`.""" bound_intrument = self.bind(labels) bound_intrument.record(value) bound_intrument.release() diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/aggregate.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/aggregate.py index ea8c40a7e72..7e1baba2c77 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/aggregate.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/aggregate.py @@ -72,7 +72,7 @@ def merge(self, other): class MinMaxSumCountAggregator(Aggregator): - """Agregator for Measure metrics that keeps min, max, sum and count.""" + """Aggregator for ValueRecorder metrics that keeps min, max, sum, count.""" _TYPE = namedtuple("minmaxsumcount", "min max sum count") _EMPTY = _TYPE(None, None, None, 0) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/batcher.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/batcher.py index 7b599f4c7da..eda504d5684 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/batcher.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/batcher.py @@ -15,7 +15,7 @@ import abc from typing import Sequence, Type -from opentelemetry.metrics import Counter, Measure, MetricT, Observer +from opentelemetry.metrics import Counter, MetricT, Observer, ValueRecorder from opentelemetry.sdk.metrics.export import MetricRecord from opentelemetry.sdk.metrics.export.aggregate import ( Aggregator, @@ -49,7 +49,7 @@ def aggregator_for(self, metric_type: Type[MetricT]) -> Aggregator: # pylint:disable=R0201 if issubclass(metric_type, Counter): return CounterAggregator() - if issubclass(metric_type, Measure): + if issubclass(metric_type, ValueRecorder): return MinMaxSumCountAggregator() if issubclass(metric_type, Observer): return ObserverAggregator() diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 32980647055..a3c0f4294d9 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -109,14 +109,14 @@ def test_record_batch_multiple(self): counter = metrics.Counter( "name", "desc", "unit", float, meter, label_keys ) - measure = metrics.Measure( + valuerecorder = metrics.ValueRecorder( "name", "desc", "unit", float, meter, label_keys ) - record_tuples = [(counter, 1.0), (measure, 3.0)] + record_tuples = [(counter, 1.0), (valuerecorder, 3.0)] meter.record_batch(labels, record_tuples) self.assertEqual(counter.bind(labels).aggregator.current, 1.0) self.assertEqual( - measure.bind(labels).aggregator.current, (3.0, 3.0, 3.0, 1) + valuerecorder.bind(labels).aggregator.current, (3.0, 3.0, 3.0, 1) ) def test_record_batch_exists(self): @@ -145,14 +145,14 @@ def test_create_metric(self): self.assertEqual(counter.name, "name") self.assertIs(counter.meter.resource, resource) - def test_create_measure(self): + def test_create_valuerecorder(self): meter = metrics.MeterProvider().get_meter(__name__) - measure = meter.create_metric( - "name", "desc", "unit", float, metrics.Measure, () + valuerecorder = meter.create_metric( + "name", "desc", "unit", float, metrics.ValueRecorder, () ) - self.assertIsInstance(measure, metrics.Measure) - self.assertEqual(measure.value_type, float) - self.assertEqual(measure.name, "name") + self.assertIsInstance(valuerecorder, metrics.ValueRecorder) + self.assertEqual(valuerecorder.value_type, float) + self.assertEqual(valuerecorder.name, "name") def test_register_observer(self): meter = metrics.MeterProvider().get_meter(__name__) @@ -197,19 +197,19 @@ def test_direct_call_release_bound_instrument(self): meter.metrics.add(counter) counter.add(4.0, labels) - measure = metrics.Measure( + valuerecorder = metrics.ValueRecorder( "name", "desc", "unit", float, meter, label_keys ) - meter.metrics.add(measure) - measure.record(42.0, labels) + meter.metrics.add(valuerecorder) + valuerecorder.record(42.0, labels) self.assertEqual(len(counter.bound_instruments), 1) - self.assertEqual(len(measure.bound_instruments), 1) + self.assertEqual(len(valuerecorder.bound_instruments), 1) meter.collect() self.assertEqual(len(counter.bound_instruments), 0) - self.assertEqual(len(measure.bound_instruments), 0) + self.assertEqual(len(valuerecorder.bound_instruments), 0) def test_release_bound_instrument(self): meter = metrics.MeterProvider().get_meter(__name__) @@ -223,30 +223,30 @@ def test_release_bound_instrument(self): bound_counter = counter.bind(labels) bound_counter.add(4.0) - measure = metrics.Measure( + valuerecorder = metrics.ValueRecorder( "name", "desc", "unit", float, meter, label_keys ) - meter.metrics.add(measure) - bound_measure = measure.bind(labels) - bound_measure.record(42) + meter.metrics.add(valuerecorder) + bound_valuerecorder = valuerecorder.bind(labels) + bound_valuerecorder.record(42) bound_counter.release() - bound_measure.release() + bound_valuerecorder.release() # be sure that bound instruments are only released after collection self.assertEqual(len(counter.bound_instruments), 1) - self.assertEqual(len(measure.bound_instruments), 1) + self.assertEqual(len(valuerecorder.bound_instruments), 1) meter.collect() self.assertEqual(len(counter.bound_instruments), 0) - self.assertEqual(len(measure.bound_instruments), 0) + self.assertEqual(len(valuerecorder.bound_instruments), 0) class TestMetric(unittest.TestCase): def test_bind(self): meter = metrics.MeterProvider().get_meter(__name__) - metric_types = [metrics.Counter, metrics.Measure] + metric_types = [metrics.Counter, metrics.ValueRecorder] labels = {"key": "value"} key_labels = tuple(sorted(labels.items())) for _type in metric_types: @@ -268,17 +268,19 @@ def test_add(self): self.assertEqual(bound_counter.aggregator.current, 5) -class TestMeasure(unittest.TestCase): +class TestValueRecorder(unittest.TestCase): def test_record(self): meter = metrics.MeterProvider().get_meter(__name__) - metric = metrics.Measure("name", "desc", "unit", int, meter, ("key",)) + metric = metrics.ValueRecorder( + "name", "desc", "unit", int, meter, ("key",) + ) labels = {"key": "value"} - bound_measure = metric.bind(labels) + bound_valuerecorder = metric.bind(labels) values = (37, 42, 7) for val in values: metric.record(val, labels) self.assertEqual( - bound_measure.aggregator.current, + bound_valuerecorder.aggregator.current, (min(values), max(values), sum(values), len(values)), ) @@ -375,33 +377,37 @@ def test_update(self): self.assertEqual(bound_counter.aggregator.current, 4.0) -class TestBoundMeasure(unittest.TestCase): +class TestBoundValueRecorder(unittest.TestCase): def test_record(self): aggregator = export.aggregate.MinMaxSumCountAggregator() - bound_measure = metrics.BoundMeasure(int, True, aggregator) - bound_measure.record(3) - self.assertEqual(bound_measure.aggregator.current, (3, 3, 3, 1)) + bound_valuerecorder = metrics.BoundValueRecorder(int, True, aggregator) + bound_valuerecorder.record(3) + self.assertEqual(bound_valuerecorder.aggregator.current, (3, 3, 3, 1)) def test_record_disabled(self): aggregator = export.aggregate.MinMaxSumCountAggregator() - bound_measure = metrics.BoundMeasure(int, False, aggregator) - bound_measure.record(3) + bound_valuerecorder = metrics.BoundValueRecorder( + int, False, aggregator + ) + bound_valuerecorder.record(3) self.assertEqual( - bound_measure.aggregator.current, (None, None, None, 0) + bound_valuerecorder.aggregator.current, (None, None, None, 0) ) @mock.patch("opentelemetry.sdk.metrics.logger") def test_record_incorrect_type(self, logger_mock): aggregator = export.aggregate.MinMaxSumCountAggregator() - bound_measure = metrics.BoundMeasure(int, True, aggregator) - bound_measure.record(3.0) + bound_valuerecorder = metrics.BoundValueRecorder(int, True, aggregator) + bound_valuerecorder.record(3.0) self.assertEqual( - bound_measure.aggregator.current, (None, None, None, 0) + bound_valuerecorder.aggregator.current, (None, None, None, 0) ) self.assertTrue(logger_mock.warning.called) def test_update(self): aggregator = export.aggregate.MinMaxSumCountAggregator() - bound_measure = metrics.BoundMeasure(int, True, aggregator) - bound_measure.update(4.0) - self.assertEqual(bound_measure.aggregator.current, (4.0, 4.0, 4.0, 1)) + bound_valuerecorder = metrics.BoundValueRecorder(int, True, aggregator) + bound_valuerecorder.update(4.0) + self.assertEqual( + bound_valuerecorder.aggregator.current, (4.0, 4.0, 4.0, 1) + )