pyfect metrics as OpenTelemetry metrics (Effect's OtelMetrics).
layer(lambda: reader) hands the current metric registry to an SDK
MetricReader (a PeriodicExportingMetricReader exporting over OTLP,
say), which collects it whenever it reads::
metrics = otel.metrics.layer(lambda: PeriodicExportingMetricReader(exporter))
program.pipe(fx.provide(metrics.pipe(layer.provide(otel.resource.layer_empty))))Readers are bound to pyfect's producer instead of a MeterProvider; a
reader can be bound once. Counters, frequencies and summaries become sums,
gauges gauges, histograms explicit-bucket histograms.
Classes#
Functions#
make_producer#
make_producer(temporality='cumulative') -> Effect[MetricProducer, Never, OtelResource]A producer of the current metric registry, with the OtelResource.
| Parameter | Type | Description |
|---|---|---|
temporality | TemporalityPreference = 'cumulative' |
Returns Effect[MetricProducer, Never, OtelResource]
def make_producer(
temporality: TemporalityPreference = "cumulative",
) -> Effect[MetricProducer, Never, OtelResource]:
"""A producer of the current metric registry, with the ``OtelResource``."""
@gen
def make():
resource = yield from OtelResource()
services = yield from context()
return MetricProducer(resource, services, temporality)
return makeregister_producer#
register_producer(producer, readers, *, shutdown_timeout=DEFAULT_SHUTDOWN_TIMEOUT) -> Effect[list[MetricReader], Never, Scope]Bind each reader to its own fork of producer, and shut them down
when the scope closes. If a reader cannot be bound (it is bound
already), the readers bound so far are shut down and the effect dies.
| Parameter | Type | Description |
|---|---|---|
producer | MetricProducer | |
readers | Readers | |
shutdown_timeout | Duration = DEFAULT_SHUTDOWN_TIMEOUT |
Returns Effect[list[MetricReader], Never, Scope]
def register_producer(
producer: MetricProducer,
readers: Readers,
*,
shutdown_timeout: Duration = DEFAULT_SHUTDOWN_TIMEOUT,
) -> Effect[list[MetricReader], Never, Scope]:
"""Bind each reader to its own fork of ``producer``, and shut them down
when the scope closes. If a reader cannot be bound (it is bound
already), the readers bound so far are shut down and the effect dies."""
def acquire() -> Effect[list[MetricReader]]:
made = readers()
given = [made] if isinstance(made, MetricReader) else list(made)
bound: list[MetricReader] = []
try:
for reader in given:
_bind(reader, producer.fork())
bound.append(reader)
except Exception as error:
failure = error
return _shut_down(bound, shutdown_timeout).flat_map(lambda _: die(failure))
return sync(lambda: bound)
return acquire_release(
suspend(acquire), lambda bound, _exit: _shut_down(bound, shutdown_timeout)
)layer#
layer(readers, *, temporality='cumulative', shutdown_timeout=DEFAULT_SHUTDOWN_TIMEOUT) -> Layer[Never, Never, OtelResource]Bind the readers readers() makes to a producer of the current
registry while the layer is in use.
| Parameter | Type | Description |
|---|---|---|
readers | Readers | |
temporality | TemporalityPreference = 'cumulative' | |
shutdown_timeout | Duration = DEFAULT_SHUTDOWN_TIMEOUT |
Returns Layer[Never, Never, OtelResource]
def layer(
readers: Readers,
*,
temporality: TemporalityPreference = "cumulative",
shutdown_timeout: Duration = DEFAULT_SHUTDOWN_TIMEOUT,
) -> Layer[Never, Never, OtelResource]:
"""Bind the readers ``readers()`` makes to a producer of the current
registry while the layer is in use."""
registered: Effect[Any, Never, OtelResource | Scope] = make_producer(temporality).flat_map(
lambda producer: register_producer(producer, readers, shutdown_timeout=shutdown_timeout)
)
return _layer.effect_discard(registered)