-
Notifications
You must be signed in to change notification settings - Fork 767
Implement "named" meters + Remove "Batcher" from Meter constructor #431
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
Changes from 3 commits
bba1fea
712ccd3
b50c269
fd3d175
08b1117
c92f837
7b8b67d
63824f3
16e728b
7733a87
b436c62
d6c97f0
a2f2e0f
32cf2c1
ec9c673
7ebd438
27d75ba
08095b6
6a743c7
e226eda
c7432ef
60b2f38
bd53f84
6f6a37d
4770ec4
0f36b31
4f4632b
e591a39
0878f5d
584d996
f854923
4df2553
40ee67b
0b93285
3735d88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -223,9 +223,49 @@ def record(self, value: ValueT, label_set: LabelSet) -> None: | |
| label_set: `LabelSet` to associate with the returned handle. | ||
| """ | ||
|
|
||
| class MeterSource(abc.ABC): | ||
|
|
||
| MetricT = TypeVar("MetricT", Counter, Gauge, Measure) | ||
| @abc.abstractmethod | ||
| def get_meter( | ||
| self, | ||
| instrumenting_module_name: str, | ||
| instrumenting_library_version: str = "", | ||
| ) -> "Meter": | ||
| """Returns a `Meter` for use by the given instrumentation library. | ||
|
|
||
| This function may return different `Meter` types (e.g. a no-op meter | ||
| vs. a functional meter). | ||
|
|
||
| Args: | ||
| instrumenting_module_name: The name of the instrumenting module | ||
| (usually just ``__name__``). | ||
|
|
||
| This should *not* be the name of the module that is | ||
| instrumented but the name of the module doing the instrumentation. | ||
| E.g., instead of ``"requests"``, use | ||
| ``"opentelemetry.ext.http_requests"``. | ||
|
|
||
| instrumenting_library_version: Optional. The version string of the | ||
| instrumenting library. Usually this should be the same as | ||
| ``pkg_resources.get_distribution(instrumenting_library_name).version``. | ||
| """ | ||
|
|
||
| class DefaultMeterSource(MeterSource): | ||
| """The default MeterSource, used when no implementation is available. | ||
|
|
||
| All operations are no-op. | ||
| """ | ||
|
|
||
| def get_meter( | ||
| self, | ||
| instrumenting_module_name: str, | ||
| instrumenting_library_version: str = "", | ||
| ) -> "Meter": | ||
| # pylint:disable=no-self-use,unused-argument | ||
| return DefaultMeter() | ||
|
|
||
|
|
||
| MetricT = TypeVar("MetricT", Counter, Gauge, Measure) | ||
|
|
||
| # pylint: disable=unused-argument | ||
| class Meter(abc.ABC): | ||
|
|
@@ -322,45 +362,49 @@ def get_label_set(self, labels: Dict[str, str]) -> "LabelSet": | |
| # Once https://github.com/python/mypy/issues/7092 is resolved, | ||
| # the following type definition should be replaced with | ||
| # from opentelemetry.util.loader import ImplementationFactory | ||
| ImplementationFactory = Callable[[Type[Meter]], Optional[Meter]] | ||
| ImplementationFactory = Callable[[Type[MeterSource]], Optional[MeterSource]] | ||
|
|
||
| _METER = None | ||
| _METER_FACTORY = None | ||
| _METER_SOURCE = None | ||
| _METER_SOURCE_FACTORY = None | ||
|
|
||
|
|
||
| def meter() -> Meter: | ||
| """Gets the current global :class:`~.Meter` object. | ||
| def meter_source() -> MeterSource: | ||
| """Gets the current global :class:`~.MeterSource` object. | ||
|
|
||
| If there isn't one set yet, a default will be loaded. | ||
| """ | ||
| global _METER, _METER_FACTORY # pylint:disable=global-statement | ||
| global _METER_SOURCE, _METER_SOURCE_FACTORY # pylint:disable=global-statement | ||
|
|
||
| if _METER is None: | ||
| if _METER_SOURCE is None: | ||
| # pylint:disable=protected-access | ||
| try: | ||
| _METER = loader._load_impl(Meter, _METER_FACTORY) # type: ignore | ||
| _METER_SOURCE = loader._load_impl( | ||
| MeterSource, _METER_SOURCE_FACTORY # type: ignore | ||
| ) | ||
| except TypeError: | ||
lzchen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # if we raised an exception trying to instantiate an | ||
| # abstract class, default to no-op tracer impl | ||
| _METER = DefaultMeter() | ||
| del _METER_FACTORY | ||
| # abstract class, default to no-op meter impl | ||
| _METER_SOURCE = DefaultMeterSource() | ||
| del _METER_SOURCE_FACTORY | ||
|
||
|
|
||
| return _METER | ||
| return _METER_SOURCE | ||
|
|
||
|
|
||
| def set_preferred_meter_implementation(factory: ImplementationFactory) -> None: | ||
| """Set the factory to be used to create the meter. | ||
| def set_preferred_meter_source_implementation( | ||
| factory: ImplementationFactory | ||
| ) -> None: | ||
| """Set the factory to be used to create the meter source. | ||
|
|
||
| See :mod:`opentelemetry.util.loader` for details. | ||
|
|
||
| This function may not be called after a meter is already loaded. | ||
|
|
||
| Args: | ||
| factory: Callback that should create a new :class:`Meter` instance. | ||
| factory: Callback that should create a new :class:`MeterSource` instance. | ||
| """ | ||
| global _METER, _METER_FACTORY # pylint:disable=global-statement | ||
| global _METER_SOURCE_FACTORY # pylint:disable=global-statement | ||
|
|
||
| if _METER: | ||
| raise RuntimeError("Meter already loaded.") | ||
| if _METER_SOURCE: | ||
| raise RuntimeError("MeterSource already loaded.") | ||
|
|
||
| _METER_FACTORY = factory | ||
| _METER_SOURCE_FACTORY = factory | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the same vein as #430, can we add metrics.get_meter()? Would save a lot of boilerplate and an abstraction many app developers will not have to deal with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meter_source().get_meter() takes in an optional
Batchertype in the constructor. How do I do the typing for this in the API without needing a dependency on the SDK where theBatcherclass exists?