Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename Measurement to Observation #2617

Merged
merged 5 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [1.11.0-0.30b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.11.0-0.30b0) - 2022-04-18

- Rename API Measurement for async instruments to Observation
([#2617](https://github.com/open-telemetry/opentelemetry-python/pull/2617))
- Add support for zero or more callbacks
([#2602](https://github.com/open-telemetry/opentelemetry-python/pull/2602))
- Fix parsing of trace flags when extracting traceparent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
opentelemetry._metrics.measurement
opentelemetry._metrics.observation
==================================

.. automodule:: opentelemetry._metrics.measurement
.. automodule:: opentelemetry._metrics.observation
:members:
:undoc-members:
:show-inheritance:
2 changes: 1 addition & 1 deletion docs/api/metrics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Submodules
.. toctree::

metrics.instrument
metrics.measurement
metrics.observation

Module contents
---------------
Expand Down
14 changes: 7 additions & 7 deletions docs/examples/metrics/example.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Iterable

from opentelemetry._metrics import get_meter_provider, set_meter_provider
from opentelemetry._metrics.measurement import Measurement
from opentelemetry._metrics.observation import Observation
from opentelemetry.exporter.otlp.proto.grpc._metric_exporter import (
OTLPMetricExporter,
)
Expand All @@ -14,16 +14,16 @@
set_meter_provider(provider)


def observable_counter_func() -> Iterable[Measurement]:
yield Measurement(1, {})
def observable_counter_func() -> Iterable[Observation]:
yield Observation(1, {})


def observable_up_down_counter_func() -> Iterable[Measurement]:
yield Measurement(-10, {})
def observable_up_down_counter_func() -> Iterable[Observation]:
yield Observation(-10, {})


def observable_gauge_func() -> Iterable[Measurement]:
yield Measurement(9, {})
def observable_gauge_func() -> Iterable[Observation]:
yield Observation(9, {})


meter = get_meter_provider().get_meter("getting-started", "0.1.2")
Expand Down
14 changes: 7 additions & 7 deletions docs/getting_started/metrics_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from typing import Iterable

from opentelemetry._metrics import get_meter_provider, set_meter_provider
from opentelemetry._metrics.measurement import Measurement
from opentelemetry._metrics.observation import Observation
from opentelemetry.sdk._metrics import MeterProvider
from opentelemetry.sdk._metrics.export import (
ConsoleMetricExporter,
Expand All @@ -31,16 +31,16 @@
set_meter_provider(provider)


def observable_counter_func() -> Iterable[Measurement]:
yield Measurement(1, {})
def observable_counter_func() -> Iterable[Observation]:
yield Observation(1, {})


def observable_up_down_counter_func() -> Iterable[Measurement]:
yield Measurement(-10, {})
def observable_up_down_counter_func() -> Iterable[Observation]:
yield Observation(-10, {})


def observable_gauge_func() -> Iterable[Measurement]:
yield Measurement(9, {})
def observable_gauge_func() -> Iterable[Observation]:
yield Observation(9, {})


meter = get_meter_provider().get_meter("getting-started", "0.1.2")
Expand Down
56 changes: 28 additions & 28 deletions opentelemetry-api/src/opentelemetry/_metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def create_counter(

Args:
name: The name of the instrument to be created
unit: The unit for measurements this instrument reports. For
unit: The unit for observations this instrument reports. For
example, ``By`` for bytes. UCUM units are recommended.
description: A description for this instrument and what it measures.
"""
Expand All @@ -240,7 +240,7 @@ def create_up_down_counter(

Args:
name: The name of the instrument to be created
unit: The unit for measurements this instrument reports. For
unit: The unit for observations this instrument reports. For
example, ``By`` for bytes. UCUM units are recommended.
description: A description for this instrument and what it measures.
"""
Expand All @@ -253,23 +253,23 @@ def create_observable_counter(

An observable counter observes a monotonically increasing count by
calling provided callbacks which returns multiple
:class:`~opentelemetry._metrics.measurement.Measurement`.
:class:`~opentelemetry._metrics.observation.Observation`.

For example, an observable counter could be used to report system CPU
time periodically. Here is a basic implementation::

def cpu_time_callback() -> Iterable[Measurement]:
measurements = []
def cpu_time_callback() -> Iterable[Observation]:
observations = []
with open("/proc/stat") as procstat:
procstat.readline() # skip the first line
for line in procstat:
if not line.startswith("cpu"): break
cpu, *states = line.split()
measurements.append(Measurement(int(states[0]) // 100, {"cpu": cpu, "state": "user"}))
measurements.append(Measurement(int(states[1]) // 100, {"cpu": cpu, "state": "nice"}))
measurements.append(Measurement(int(states[2]) // 100, {"cpu": cpu, "state": "system"}))
observations.append(Observation(int(states[0]) // 100, {"cpu": cpu, "state": "user"}))
observations.append(Observation(int(states[1]) // 100, {"cpu": cpu, "state": "nice"}))
observations.append(Observation(int(states[2]) // 100, {"cpu": cpu, "state": "system"}))
# ... other states
return measurements
return observations

meter.create_observable_counter(
"system.cpu.time",
Expand All @@ -281,34 +281,34 @@ def cpu_time_callback() -> Iterable[Measurement]:
To reduce memory usage, you can use generator callbacks instead of
building the full list::

def cpu_time_callback() -> Iterable[Measurement]:
def cpu_time_callback() -> Iterable[Observation]:
with open("/proc/stat") as procstat:
procstat.readline() # skip the first line
for line in procstat:
if not line.startswith("cpu"): break
cpu, *states = line.split()
yield Measurement(int(states[0]) // 100, {"cpu": cpu, "state": "user"})
yield Measurement(int(states[1]) // 100, {"cpu": cpu, "state": "nice"})
yield Observation(int(states[0]) // 100, {"cpu": cpu, "state": "user"})
yield Observation(int(states[1]) // 100, {"cpu": cpu, "state": "nice"})
# ... other states

Alternatively, you can pass a sequence of generators directly instead
of a sequence of callbacks, which each should return iterables of
:class:`~opentelemetry._metrics.measurement.Measurement`::
:class:`~opentelemetry._metrics.observation.Observation`::

def cpu_time_callback(states_to_include: set[str]) -> Iterable[Iterable[Measurement]]:
def cpu_time_callback(states_to_include: set[str]) -> Iterable[Iterable[Observation]]:
while True:
measurements = []
observations = []
with open("/proc/stat") as procstat:
procstat.readline() # skip the first line
for line in procstat:
if not line.startswith("cpu"): break
cpu, *states = line.split()
if "user" in states_to_include:
measurements.append(Measurement(int(states[0]) // 100, {"cpu": cpu, "state": "user"}))
observations.append(Observation(int(states[0]) // 100, {"cpu": cpu, "state": "user"}))
if "nice" in states_to_include:
measurements.append(Measurement(int(states[1]) // 100, {"cpu": cpu, "state": "nice"}))
observations.append(Observation(int(states[1]) // 100, {"cpu": cpu, "state": "nice"}))
# ... other states
yield measurements
yield observations

meter.create_observable_counter(
"system.cpu.time",
Expand All @@ -320,11 +320,11 @@ def cpu_time_callback(states_to_include: set[str]) -> Iterable[Iterable[Measurem
Args:
name: The name of the instrument to be created
callbacks: A sequence of callbacks that return an iterable of
:class:`~opentelemetry._metrics.measurement.Measurement`.
:class:`~opentelemetry._metrics.observation.Observation`.
Alternatively, can be a sequence of generators that each yields
iterables of
:class:`~opentelemetry._metrics.measurement.Measurement`.
unit: The unit for measurements this instrument reports. For
:class:`~opentelemetry._metrics.observation.Observation`.
unit: The unit for observations this instrument reports. For
example, ``By`` for bytes. UCUM units are recommended.
description: A description for this instrument and what it measures.
"""
Expand All @@ -335,7 +335,7 @@ def create_histogram(self, name, unit="", description="") -> Histogram:

Args:
name: The name of the instrument to be created
unit: The unit for measurements this instrument reports. For
unit: The unit for observations this instrument reports. For
example, ``By`` for bytes. UCUM units are recommended.
description: A description for this instrument and what it measures.
"""
Expand All @@ -349,10 +349,10 @@ def create_observable_gauge(
Args:
name: The name of the instrument to be created
callbacks: A sequence of callbacks that return an iterable of
:class:`~opentelemetry._metrics.measurement.Measurement`.
:class:`~opentelemetry._metrics.observation.Observation`.
Alternatively, can be a generator that yields iterables of
:class:`~opentelemetry._metrics.measurement.Measurement`.
unit: The unit for measurements this instrument reports. For
:class:`~opentelemetry._metrics.observation.Observation`.
unit: The unit for observations this instrument reports. For
example, ``By`` for bytes. UCUM units are recommended.
description: A description for this instrument and what it measures.
"""
Expand All @@ -366,10 +366,10 @@ def create_observable_up_down_counter(
Args:
name: The name of the instrument to be created
callbacks: A sequence of callbacks that return an iterable of
:class:`~opentelemetry._metrics.measurement.Measurement`.
:class:`~opentelemetry._metrics.observation.Observation`.
Alternatively, can be a generator that yields iterables of
:class:`~opentelemetry._metrics.measurement.Measurement`.
unit: The unit for measurements this instrument reports. For
:class:`~opentelemetry._metrics.observation.Observation`.
unit: The unit for observations this instrument reports. For
example, ``By`` for bytes. UCUM units are recommended.
description: A description for this instrument and what it measures.
"""
Expand Down
6 changes: 3 additions & 3 deletions opentelemetry-api/src/opentelemetry/_metrics/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@

# pylint: disable=unused-import; needed for typing and sphinx
from opentelemetry import _metrics as metrics
from opentelemetry._metrics.measurement import Measurement
from opentelemetry._metrics.observation import Observation

InstrumentT = TypeVar("InstrumentT", bound="Instrument")
CallbackT = Union[
Callable[[], Iterable[Measurement]],
Generator[Iterable[Measurement], None, None],
Callable[[], Iterable[Observation]],
Generator[Iterable[Observation], None, None],
]


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from opentelemetry.util.types import Attributes


class Measurement:
class Observation:
"""A measurement observed in an asynchronous instrument

Return/yield instances of this class from asynchronous instrument callbacks.
Expand All @@ -43,10 +43,10 @@ def attributes(self) -> Attributes:

def __eq__(self, other: object) -> bool:
return (
isinstance(other, Measurement)
isinstance(other, Observation)
and self.value == other.value
and self.attributes == other.attributes
)

def __repr__(self) -> str:
return f"Measurement(value={self.value}, attributes={self.attributes})"
return f"Observation(value={self.value}, attributes={self.attributes})"
22 changes: 11 additions & 11 deletions opentelemetry-api/tests/metrics/test_measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,33 @@

from unittest import TestCase

from opentelemetry._metrics.measurement import Measurement
from opentelemetry._metrics.observation import Observation


class TestMeasurement(TestCase):
class TestObservation(TestCase):
def test_measurement_init(self):
try:
# int
Measurement(321, {"hello": "world"})
Observation(321, {"hello": "world"})

# float
Measurement(321.321, {"hello": "world"})
Observation(321.321, {"hello": "world"})
except Exception: # pylint: disable=broad-except
self.fail(
"Unexpected exception raised when instantiating Measurement"
"Unexpected exception raised when instantiating Observation"
)

def test_measurement_equality(self):
self.assertEqual(
Measurement(321, {"hello": "world"}),
Measurement(321, {"hello": "world"}),
Observation(321, {"hello": "world"}),
Observation(321, {"hello": "world"}),
)

self.assertNotEqual(
Measurement(321, {"hello": "world"}),
Measurement(321.321, {"hello": "world"}),
Observation(321, {"hello": "world"}),
Observation(321.321, {"hello": "world"}),
)
self.assertNotEqual(
Measurement(321, {"baz": "world"}),
Measurement(321, {"hello": "world"}),
Observation(321, {"baz": "world"}),
Observation(321, {"hello": "world"}),
)
Loading