diff --git a/docs/getting_started/metrics_example.py b/docs/getting_started/metrics_example.py index 66ea57438f..3fc5bbaa5d 100644 --- a/docs/getting_started/metrics_example.py +++ b/docs/getting_started/metrics_example.py @@ -75,7 +75,9 @@ def observable_gauge_func(options: CallbackOptions) -> Iterable[Observation]: histogram.record(99.9) # Async Gauge -observable_gauge = meter.create_observable_gauge("gauge", [observable_gauge_func]) +observable_gauge = meter.create_observable_gauge( + "gauge", [observable_gauge_func] +) # Sync Gauge gauge = meter.create_gauge("gauge") diff --git a/opentelemetry-api/src/opentelemetry/metrics/__init__.py b/opentelemetry-api/src/opentelemetry/metrics/__init__.py index 4d28384cc1..f55f5cd19f 100644 --- a/opentelemetry-api/src/opentelemetry/metrics/__init__.py +++ b/opentelemetry-api/src/opentelemetry/metrics/__init__.py @@ -53,8 +53,8 @@ CallbackOptions, CallbackT, Counter, - Histogram, Gauge, + Histogram, Instrument, NoOpCounter, NoOpHistogram, diff --git a/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py b/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py index ded2166d19..bbb0b988ec 100644 --- a/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py +++ b/opentelemetry-api/src/opentelemetry/metrics/_internal/__init__.py @@ -51,11 +51,11 @@ from opentelemetry.metrics._internal.instrument import ( CallbackT, Counter, - Histogram, Gauge, + Histogram, NoOpCounter, - NoOpHistogram, NoOpGauge, + NoOpHistogram, NoOpObservableCounter, NoOpObservableGauge, NoOpObservableUpDownCounter, @@ -65,8 +65,8 @@ ObservableUpDownCounter, UpDownCounter, _ProxyCounter, - _ProxyHistogram, _ProxyGauge, + _ProxyHistogram, _ProxyObservableCounter, _ProxyObservableGauge, _ProxyObservableUpDownCounter, @@ -531,7 +531,7 @@ def create_histogram( proxy = _ProxyHistogram(name, unit, description) self._instruments.append(proxy) return proxy - + def create_gauge( self, name: str, @@ -611,7 +611,7 @@ def create_counter( description, ) return NoOpCounter(name, unit=unit, description=description) - + def create_gauge( self, name: str, @@ -620,9 +620,9 @@ def create_gauge( ) -> Gauge: """Returns a no-op Gauge.""" super().create_gauge(name, unit=unit, description=description) - if self._is_instrument_registered( - name, NoOpGauge, unit, description - )[0]: + if self._is_instrument_registered(name, NoOpGauge, unit, description)[ + 0 + ]: _logger.warning( "An instrument with name %s, type %s, unit %s and " "description %s has been created already.", diff --git a/opentelemetry-api/src/opentelemetry/metrics/_internal/instrument.py b/opentelemetry-api/src/opentelemetry/metrics/_internal/instrument.py index 685548d57c..3f74218711 100644 --- a/opentelemetry-api/src/opentelemetry/metrics/_internal/instrument.py +++ b/opentelemetry-api/src/opentelemetry/metrics/_internal/instrument.py @@ -397,8 +397,10 @@ def _create_real_instrument( self._name, self._callbacks, self._unit, self._description ) + class Gauge(Synchronous): """A Gauge is a synchronous `Instrument` which can be used to record non-additive values as they occur.""" + @abstractmethod def set( self, @@ -407,6 +409,7 @@ def set( ) -> None: pass + class NoOpGauge(Gauge): """No-op implementation of `Gauge`.""" @@ -425,6 +428,7 @@ def set( ) -> None: return super().set(amount, attributes=attributes) + class _ProxyGauge( _ProxyInstrument[Gauge], Gauge, @@ -437,9 +441,5 @@ def set( if self._real_instrument: self._real_instrument.set(amount, attributes) - def _create_real_instrument( - self, meter: "metrics.Meter" - ) -> Gauge: - return meter.create_gauge( - self._name, self._unit, self._description - ) + def _create_real_instrument(self, meter: "metrics.Meter") -> Gauge: + return meter.create_gauge(self._name, self._unit, self._description) diff --git a/opentelemetry-api/tests/metrics/test_instruments.py b/opentelemetry-api/tests/metrics/test_instruments.py index 8080752076..dc616308e4 100644 --- a/opentelemetry-api/tests/metrics/test_instruments.py +++ b/opentelemetry-api/tests/metrics/test_instruments.py @@ -277,6 +277,7 @@ def test_histogram_record_method(self): self.assertIsNone(NoOpHistogram("name").record(1)) + class TestGauge(TestCase): def test_create_gauge(self): """ @@ -302,44 +303,25 @@ def test_create_gauge_api(self): Test that the API for creating a gauge accepts the description of the instrument """ - create_gauge_signature = signature( - Meter.create_gauge - ) - self.assertIn( - "name", create_gauge_signature.parameters.keys() - ) + create_gauge_signature = signature(Meter.create_gauge) + self.assertIn("name", create_gauge_signature.parameters.keys()) self.assertIs( create_gauge_signature.parameters["name"].default, Signature.empty, ) - create_gauge_signature = signature( - Meter.create_gauge - ) - create_gauge_signature = signature( - Meter.create_gauge - ) - self.assertIn( - "unit", create_gauge_signature.parameters.keys() - ) - self.assertIs( - create_gauge_signature.parameters["unit"].default, "" - ) + create_gauge_signature = signature(Meter.create_gauge) + create_gauge_signature = signature(Meter.create_gauge) + self.assertIn("unit", create_gauge_signature.parameters.keys()) + self.assertIs(create_gauge_signature.parameters["unit"].default, "") - create_gauge_signature = signature( - Meter.create_gauge - ) - self.assertIn( - "description", create_gauge_signature.parameters.keys() - ) + create_gauge_signature = signature(Meter.create_gauge) + self.assertIn("description", create_gauge_signature.parameters.keys()) self.assertIs( - create_gauge_signature.parameters[ - "description" - ].default, + create_gauge_signature.parameters["description"].default, "", ) - class TestObservableGauge(TestCase): def test_create_observable_gauge(self): """ diff --git a/opentelemetry-api/tests/metrics/test_meter_provider.py b/opentelemetry-api/tests/metrics/test_meter_provider.py index e0bea02f2f..559b56205e 100644 --- a/opentelemetry-api/tests/metrics/test_meter_provider.py +++ b/opentelemetry-api/tests/metrics/test_meter_provider.py @@ -30,8 +30,8 @@ from opentelemetry.metrics._internal import _ProxyMeter, _ProxyMeterProvider from opentelemetry.metrics._internal.instrument import ( _ProxyCounter, - _ProxyHistogram, _ProxyGauge, + _ProxyHistogram, _ProxyObservableCounter, _ProxyObservableGauge, _ProxyObservableUpDownCounter, @@ -284,7 +284,6 @@ def test_proxy_meter(self): proxy_gauge.set(amount, attributes=attributes) real_gauge.set.assert_called_once_with(amount, attributes) - def test_proxy_meter_with_real_meter(self) -> None: # Creating new instruments on the _ProxyMeter with a real meter set # should create real instruments instead of proxies diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py index 0dcb09c051..35edafc280 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py @@ -17,8 +17,8 @@ from opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError from opentelemetry.sdk.metrics._internal.instrument import ( Counter, - Histogram, Gauge, + Histogram, ObservableCounter, ObservableGauge, ObservableUpDownCounter, @@ -31,6 +31,7 @@ "MetricsTimeoutError", "Counter", "Histogram", + "Gauge", "ObservableCounter", "ObservableGauge", "ObservableUpDownCounter", diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py index 6d9927e497..38ba31850e 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/__init__.py @@ -21,8 +21,8 @@ # This kind of import is needed to avoid Sphinx errors. import opentelemetry.sdk.metrics from opentelemetry.metrics import Counter as APICounter -from opentelemetry.metrics import Histogram as APIHistogram from opentelemetry.metrics import Gauge as APIGauge +from opentelemetry.metrics import Histogram as APIHistogram from opentelemetry.metrics import Meter as APIMeter from opentelemetry.metrics import MeterProvider as APIMeterProvider from opentelemetry.metrics import NoOpMeter @@ -35,8 +35,8 @@ from opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError from opentelemetry.sdk.metrics._internal.instrument import ( _Counter, - _Histogram, _Gauge, + _Histogram, _ObservableCounter, _ObservableGauge, _ObservableUpDownCounter, @@ -219,7 +219,7 @@ def create_histogram(self, name, unit="", description="") -> APIHistogram: with self._instrument_id_instrument_lock: self._instrument_id_instrument[instrument_id] = instrument return instrument - + def create_gauge(self, name, unit="", description="") -> APIGauge: ( diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py index f6d9e704d2..843d904a3b 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py @@ -25,8 +25,8 @@ from opentelemetry.metrics import ( Asynchronous, Counter, - Histogram, Gauge, + Histogram, Instrument, ObservableCounter, ObservableGauge, @@ -47,8 +47,8 @@ from opentelemetry.sdk.metrics._internal.point import Buckets as BucketsPoint from opentelemetry.sdk.metrics._internal.point import ( ExponentialHistogramDataPoint, - Gauge as GaugePoint, ) +from opentelemetry.sdk.metrics._internal.point import Gauge as GaugePoint from opentelemetry.sdk.metrics._internal.point import ( Histogram as HistogramPoint, ) @@ -1106,7 +1106,7 @@ def _create_aggregation( if isinstance(instrument, ObservableGauge): return _LastValueAggregation(attributes) - + if isinstance(instrument, Gauge): return _LastValueAggregation(attributes) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py index 0f6f084fda..e7099562eb 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py @@ -44,15 +44,15 @@ from opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError from opentelemetry.sdk.metrics._internal.instrument import ( Counter, - Histogram, Gauge, + Histogram, ObservableCounter, ObservableGauge, ObservableUpDownCounter, UpDownCounter, _Counter, - _Histogram, _Gauge, + _Histogram, _ObservableCounter, _ObservableGauge, _ObservableUpDownCounter, @@ -255,9 +255,7 @@ def __init__( _Histogram ] = temporality elif typ is Gauge: - self._instrument_class_temporality[ - _Gauge - ] = temporality + self._instrument_class_temporality[_Gauge] = temporality elif typ is ObservableCounter: self._instrument_class_temporality[ _ObservableCounter @@ -297,9 +295,7 @@ def __init__( _Histogram ] = aggregation elif typ is Gauge: - self._instrument_class_aggregation[ - _Gauge - ] = aggregation + self._instrument_class_aggregation[_Gauge] = aggregation elif typ is ObservableCounter: self._instrument_class_aggregation[ _ObservableCounter diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/instrument.py b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/instrument.py index 8a96d2cad1..88a17c92aa 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/instrument.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/instrument.py @@ -21,8 +21,8 @@ import opentelemetry.sdk.metrics from opentelemetry.metrics import CallbackT from opentelemetry.metrics import Counter as APICounter -from opentelemetry.metrics import Histogram as APIHistogram from opentelemetry.metrics import Gauge as APIGauge +from opentelemetry.metrics import Histogram as APIHistogram from opentelemetry.metrics import ObservableCounter as APIObservableCounter from opentelemetry.metrics import ObservableGauge as APIObservableGauge from opentelemetry.metrics import ( @@ -212,6 +212,7 @@ def record( Measurement(amount, self, attributes) ) + class Gauge(_Synchronous, APIGauge): def __new__(cls, *args, **kwargs): if cls is Gauge: @@ -225,6 +226,7 @@ def set( Measurement(amount, self, attributes) ) + class ObservableGauge(_Asynchronous, APIObservableGauge): def __new__(cls, *args, **kwargs): if cls is ObservableGauge: @@ -254,8 +256,10 @@ class _ObservableUpDownCounter(ObservableUpDownCounter): class _Histogram(Histogram): pass + class _Gauge(Gauge): pass + class _ObservableGauge(ObservableGauge): pass diff --git a/opentelemetry-sdk/tests/metrics/test_aggregation.py b/opentelemetry-sdk/tests/metrics/test_aggregation.py index 99e3dcd826..50561022fb 100644 --- a/opentelemetry-sdk/tests/metrics/test_aggregation.py +++ b/opentelemetry-sdk/tests/metrics/test_aggregation.py @@ -532,7 +532,7 @@ def test_histogram(self): 0, ) self.assertIsInstance(aggregation, _ExplicitBucketHistogramAggregation) - + def test_gauge(self): aggregation = self.default_aggregation._create_aggregation( diff --git a/opentelemetry-sdk/tests/metrics/test_import.py b/opentelemetry-sdk/tests/metrics/test_import.py index 93ff00754b..3f635a466d 100644 --- a/opentelemetry-sdk/tests/metrics/test_import.py +++ b/opentelemetry-sdk/tests/metrics/test_import.py @@ -26,8 +26,8 @@ def test_import_init(self): with self.assertNotRaises(Exception): from opentelemetry.sdk.metrics import ( # noqa: F401 Counter, - Histogram, Gauge, + Histogram, Meter, MeterProvider, ObservableCounter, diff --git a/opentelemetry-sdk/tests/metrics/test_instrument.py b/opentelemetry-sdk/tests/metrics/test_instrument.py index 5243f4ab23..f12d859bba 100644 --- a/opentelemetry-sdk/tests/metrics/test_instrument.py +++ b/opentelemetry-sdk/tests/metrics/test_instrument.py @@ -20,8 +20,8 @@ from opentelemetry.metrics._internal.instrument import CallbackOptions from opentelemetry.sdk.metrics import ( Counter, - Histogram, Gauge, + Histogram, ObservableCounter, ObservableGauge, ObservableUpDownCounter, @@ -29,8 +29,8 @@ ) from opentelemetry.sdk.metrics._internal.instrument import ( _Counter, - _Histogram, _Gauge, + _Histogram, _ObservableCounter, _ObservableGauge, _ObservableUpDownCounter, @@ -294,7 +294,8 @@ def test_disallow_direct_observable_counter_creation(self): # pylint: disable=abstract-class-instantiated ObservableCounter("name", Mock(), Mock()) -class TestCounter(TestCase): + +class TestGauge(TestCase): def testname(self): self.assertEqual(_Gauge("name", Mock(), Mock()).name, "name") self.assertEqual(_Gauge("Name", Mock(), Mock()).name, "name") @@ -310,6 +311,7 @@ def test_disallow_direct_counter_creation(self): # pylint: disable=abstract-class-instantiated Gauge("name", Mock(), Mock()) + class TestObservableUpDownCounter(TestCase): def test_callable_callback_0(self): observable_up_down_counter = _ObservableUpDownCounter( diff --git a/opentelemetry-sdk/tests/metrics/test_metric_reader.py b/opentelemetry-sdk/tests/metrics/test_metric_reader.py index bae2a52523..cb854466cc 100644 --- a/opentelemetry-sdk/tests/metrics/test_metric_reader.py +++ b/opentelemetry-sdk/tests/metrics/test_metric_reader.py @@ -16,11 +16,16 @@ from unittest import TestCase from unittest.mock import patch -from opentelemetry.sdk.metrics import Counter, Histogram, Gauge, ObservableGauge +from opentelemetry.sdk.metrics import ( + Counter, + Gauge, + Histogram, + ObservableGauge, +) from opentelemetry.sdk.metrics._internal.instrument import ( _Counter, - _Histogram, _Gauge, + _Histogram, _ObservableCounter, _ObservableGauge, _ObservableUpDownCounter, @@ -118,9 +123,7 @@ def test_configure_temporality(self): ) self.assertEqual( - dummy_metric_reader._instrument_class_temporality[ - _Gauge - ], + dummy_metric_reader._instrument_class_temporality[_Gauge], AggregationTemporality.DELTA, ) diff --git a/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py b/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py index 70669a7660..5bcf07f6b6 100644 --- a/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py +++ b/opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py @@ -20,8 +20,8 @@ ) from opentelemetry.sdk.metrics._internal.instrument import ( _Counter, - _Histogram, _Gauge, + _Histogram, _ObservableCounter, _UpDownCounter, ) @@ -766,6 +766,12 @@ def test_view_instrument_match_conflict_6(self): Measurement(1, histogram) ) + with self.assertRaises(AssertionError): + with self.assertLogs(level=WARNING): + metric_reader_storage.consume_measurement( + Measurement(1, gauge) + ) + def test_view_instrument_match_conflict_7(self): # There is a conflict between views and instruments because the # description being different does not avoid a conflict. @@ -838,13 +844,6 @@ def test_view_instrument_match_conflict_8(self): unit="unit", description="description", ) - gauge = _Gauge( - "gauge", - Mock(), - [Mock()], - unit="unit", - description="description", - ) metric_reader_storage = MetricReaderStorage( SdkConfiguration( resource=Mock(), @@ -856,7 +855,6 @@ def test_view_instrument_match_conflict_8(self): name="foo", aggregation=SumAggregation(), ), - View(instrument_name="gauge", name="foo"), ), ), MagicMock( diff --git a/opentelemetry-sdk/tests/metrics/test_metrics.py b/opentelemetry-sdk/tests/metrics/test_metrics.py index 512bced06f..3bedcb53c5 100644 --- a/opentelemetry-sdk/tests/metrics/test_metrics.py +++ b/opentelemetry-sdk/tests/metrics/test_metrics.py @@ -21,8 +21,8 @@ from opentelemetry.metrics import NoOpMeter from opentelemetry.sdk.metrics import ( Counter, - Histogram, Gauge, + Histogram, Meter, MeterProvider, ObservableCounter, @@ -348,13 +348,11 @@ def test_consume_measurement_histogram( counter.record(1) sync_consumer_instance.consume_measurement.assert_called() - + @patch( "opentelemetry.sdk.metrics._internal." "SynchronousMeasurementConsumer" ) - def test_consume_measurement_gauge( - self, mock_sync_measurement_consumer - ): + def test_consume_measurement_gauge(self, mock_sync_measurement_consumer): sync_consumer_instance = mock_sync_measurement_consumer() meter_provider = MeterProvider() gauge = meter_provider.get_meter("name").create_gauge("name") @@ -444,7 +442,7 @@ def test_create_observable_gauge(self): self.assertIsInstance(observable_gauge, ObservableGauge) self.assertEqual(observable_gauge.name, "name") - + def test_create_gauge(self): gauge = self.meter.create_gauge( "name", unit="unit", description="description"