Skip to content

Commit

Permalink
Remove checks and callbacks from API
Browse files Browse the repository at this point in the history
  • Loading branch information
ocelotl committed Sep 29, 2021
1 parent ae757a9 commit b1435df
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 395 deletions.
21 changes: 6 additions & 15 deletions opentelemetry-api/src/opentelemetry/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,17 @@ def version(self):
def schema_url(self):
return self._schema_url

def _secure_instrument_name(self, name):
name = name.lower()

if name in self._instrument_names:
_logger.error("Instrument name %s has been used already", name)

else:
self._instrument_names.add(name)
# FIXME check that the instrument name has not been used already

@abstractmethod
def create_counter(self, name, unit="", description="") -> Counter:
self._secure_instrument_name(name)
pass

@abstractmethod
def create_up_down_counter(
self, name, unit="", description=""
) -> UpDownCounter:
self._secure_instrument_name(name)
pass

@abstractmethod
def create_observable_counter(
Expand Down Expand Up @@ -206,23 +199,21 @@ def cpu_time_callback(states_to_include: set[str]) -> Iterable[Iterable[Measurem
description: A description for this instrument and what it measures.
"""

self._secure_instrument_name(name)

@abstractmethod
def create_histogram(self, name, unit="", description="") -> Histogram:
self._secure_instrument_name(name)
pass

@abstractmethod
def create_observable_gauge(
self, name, callback, unit="", description=""
) -> ObservableGauge:
self._secure_instrument_name(name)
pass

@abstractmethod
def create_observable_up_down_counter(
self, name, callback, unit="", description=""
) -> ObservableUpDownCounter:
self._secure_instrument_name(name)
pass


class ProxyMeter(Meter):
Expand Down
80 changes: 12 additions & 68 deletions opentelemetry-api/src/opentelemetry/metrics/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from abc import ABC, abstractmethod
from collections import abc as collections_abc
from logging import getLogger
from re import compile as compile_
from typing import Callable, Generator, Iterable, Union

from opentelemetry.metrics.measurement import Measurement
Expand All @@ -33,44 +32,13 @@


class Instrument(ABC):

_name_regex = compile_(r"[a-zA-Z][-.\w]{0,62}")

@property
def name(self):
return self._name

@property
def unit(self):
return self._unit

@property
def description(self):
return self._description

@abstractmethod
def __init__(self, name, unit="", description=""):
pass

if name is None or self._name_regex.fullmatch(name) is None:
_logger.error("Invalid instrument name %s", name)

else:
self._name = name

if unit is None:
self._unit = ""
elif len(unit) > 63:
_logger.error("unit must be 63 characters or shorter")

elif any(ord(character) > 127 for character in unit):
_logger.error("unit must only contain ASCII characters")
else:
self._unit = unit

if description is None:
description = ""

self._description = description
# FIXME check that the instrument name is valid
# FIXME check that the unit is 63 characters or shorter
# FIXME check that the unit contains only ASCII characters


class Synchronous(Instrument):
Expand All @@ -96,11 +64,10 @@ def __init__(
self._callback = callback
elif isinstance(callback, collections_abc.Generator):
self._callback = self._wrap_generator_callback(callback)
else:
_logger.error("callback must be a callable or generator")
# FIXME check that callback is a callable or generator

@staticmethod
def _wrap_generator_callback(
self,
generator_callback: _TInstrumentCallbackGenerator,
) -> _TInstrumentCallback:
"""Wraps a generator style callback into a callable one"""
Expand All @@ -115,30 +82,13 @@ def inner() -> Iterable[Measurement]:
return next(generator_callback)
except StopIteration:
has_items = False
_logger.error(
"callback generator for instrument %s ran out of measurements",
self._name,
)
# FIXME handle the situation where the callback generator has
# run out of measurements
return []

return inner

def callback(self):
measurements = self._callback()
if not isinstance(measurements, collections_abc.Iterable):
_logger.error(
"Callback must return an iterable of Measurement, got %s",
type(measurements),
)
return
for measurement in measurements:
if not isinstance(measurement, Measurement):
_logger.error(
"Callback must return an iterable of Measurement, "
"iterable contained type %s",
type(measurement),
)
yield measurement
# FIXME check that callbacks return an iterable of Measurements


class _Adding(Instrument):
Expand All @@ -160,8 +110,8 @@ class _NonMonotonic(_Adding):
class Counter(_Monotonic, Synchronous):
@abstractmethod
def add(self, amount, attributes=None):
if amount < 0:
_logger.error("Amount must be non-negative")
# FIXME check that the amount is non negative
pass


class DefaultCounter(Counter):
Expand All @@ -187,13 +137,7 @@ def add(self, amount, attributes=None):


class ObservableCounter(_Monotonic, Asynchronous):
def callback(self):
measurements = super().callback()

for measurement in measurements:
if measurement.value < 0:
_logger.error("Amount must be non-negative")
yield measurement
pass


class DefaultObservableCounter(ObservableCounter):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def cpu_time_callback() -> Iterable[Measurement]:
unit="s",
description="CPU time",
)
measurements = list(observable_counter.callback())
measurements = list(observable_counter._callback())
self.assertEqual(measurements, self.measurements_expected)

def test_cpu_time_generator(self):
Expand Down Expand Up @@ -182,5 +182,5 @@ def cpu_time_generator() -> Generator[
unit="s",
description="CPU time",
)
measurements = list(observable_counter.callback())
measurements = list(observable_counter._callback())
self.assertEqual(measurements, self.measurements_expected)
Loading

0 comments on commit b1435df

Please sign in to comment.