Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

OtelMetrics unstable

OpenTelemetry support for Effect metrics.

This module exposes Effect metrics as an OpenTelemetry MetricProducer. makeProducer creates the producer, registerProducer attaches it to one or more SDK MetricReaders, and layer manages that setup in a scoped layer. The TemporalityPreference type lets callers choose cumulative or delta metric values.

4 exports Since v4.0.0 Source

Constructors

Since v4.0.0

Creates an OpenTelemetry metric producer from Effect metrics.

When to use

Use when you need a MetricProducer for manually wiring Effect metrics into OpenTelemetry instead of using the scoped layer helper.

Details

Requires the current OpenTelemetry Resource, captures the current Effect context, and uses cumulative temporality by default. Pass "delta" for interval-based values.

See

  • registerProducer for attaching a producer to metric readers
  • layer for creating and registering a producer in a scoped layer

Signature

declare function makeProducer(temporality?: TemporalityPreference): Effect<MetricProducer, never, Resource>

Layers

layer

unstable
Since v4.0.0

Creates a Layer that registers a metric producer with metric readers.

Signature

declare function layer(evaluate: LazyArg<any>, options?: {
readonly shutdownTimeout?: Input;
readonly temporality?: TemporalityPreference;
}): Layer<never, never, Resource>

Example Exporting delta metrics

import { OtelMetrics, Resource } from "@effect/opentelemetry"
import {
AggregationTemporality,
InMemoryMetricExporter,
PeriodicExportingMetricReader
} from "@opentelemetry/sdk-metrics"
import { Effect, Layer, Metric } from "effect"
const exporter = new InMemoryMetricExporter(AggregationTemporality.DELTA)
const reader = new PeriodicExportingMetricReader({
exporter,
exportIntervalMillis: 60_000
})
const metricsLayer = OtelMetrics.layer(() => reader, { temporality: "delta" }).pipe(
Layer.provide(Resource.layerEmpty)
)
const program = Effect.gen(function*() {
yield* Metric.update(Metric.counter("docs.requests", { incremental: true }), 2)
yield* Effect.promise(() => reader.forceFlush())
const metric = exporter.getMetrics()[0]?.scopeMetrics[0]?.metrics.find(
(metric) => metric.descriptor.name === "docs.requests"
)
return [metric?.descriptor.name, metric?.aggregationTemporality, metric?.dataPoints[0]?.value] as const
}).pipe(
Effect.provide(metricsLayer),
Effect.provideService(Metric.MetricRegistry, new Map())
)
await Effect.runPromise(program) // => ["docs.requests", AggregationTemporality.DELTA, 2]

Models

Since v4.0.0

Determines how metric values relate to the time interval over which they are aggregated.

Details

cumulative reports total since a fixed start time. Each data point depends on all previous measurements. This is the default behavior. delta reports changes since the last export. Each interval is independent with no dependency on previous measurements.

Signature

type TemporalityPreference = "cumulative" | "delta"

Resource Management

Since v4.0.0

Registers a metric producer with one or more metric readers.

Signature

declare function registerProducer(self: MetricProducer, metricReader: LazyArg<any>, options?: {
readonly shutdownTimeout?: Input;
}): Effect<Array<any>, never, Scope>