Skip to content

Metrics

  • Start here: Metrics guide
  • Common recipes: Metrics() component to install an OTel MeterProvider for the app's lifetime. @measure to time and count a function. metrics_router() to expose Prometheus metrics.

grelmicro.metrics

Metrics.

OpenTelemetry metrics for grelmicro. Installs a MeterProvider for the app's lifetime, emits per-component metrics from the existing hot paths, and exposes a @measure decorator plus a Prometheus /metrics router.

Metrics

Metrics(
    *,
    name: str = "default",
    config: MetricsConfig | None = None,
    service_name: str | None = None,
    exporter: MetricsExporterType | None = None,
    endpoint: str | None = None,
    headers: dict[str, str] | None = None,
    export_interval: float | None = None,
    export_timeout: float | None = None,
    resource_attributes: dict[str, str] | None = None,
    shutdown_timeout: float | None = None,
    env_load: bool | None = None,
)

Metrics component: installs an OTel MeterProvider for the app's lifetime.

Registered as micro.metrics after Grelmicro.use(Metrics(...)). On enter, builds a MeterProvider from the resolved config and installs it as the process-global provider. On exit, the provider is shut down and the previously-installed provider (if any) is restored.

OTel's set_meter_provider refuses to override an already-installed provider, so Metrics writes the process-global directly. This means a single process should not run two Grelmicro apps with Metrics components concurrently: their lifecycles share one OTel global. Sequential apps (the common test scenario) work fine.

Example
from grelmicro import Grelmicro
from grelmicro.metrics import Metrics

micro = Grelmicro(uses=[Metrics(service_name="payments-api")])

async with micro:
    ...

The OTLP and Prometheus exporters are lazy-imported when selected. Install the matching exporter package: opentelemetry-exporter-otlp-proto-http, opentelemetry-exporter-otlp-proto-grpc, or opentelemetry-exporter-prometheus.

Read more in the Metrics docs.

Initialize the component (defer provider build until __aenter__).

PARAMETER DESCRIPTION
name

Registration name. Metrics installs the process-global OTel meter provider, so only one may be registered per app.

TYPE: str DEFAULT: 'default'

config

Pre-built configuration. When provided, individual kwargs must be None. The env path is bypassed.

TYPE: MetricsConfig | None DEFAULT: None

service_name

Service name resource attribute.

TYPE: str | None DEFAULT: None

exporter

Metric exporter.

TYPE: MetricsExporterType | None DEFAULT: None

endpoint

Exporter endpoint.

TYPE: str | None DEFAULT: None

headers

Exporter headers.

TYPE: dict[str, str] | None DEFAULT: None

export_interval

Seconds between periodic exports.

TYPE: float | None DEFAULT: None

export_timeout

Maximum seconds a single export may take.

TYPE: float | None DEFAULT: None

resource_attributes

Extra resource attributes.

TYPE: dict[str, str] | None DEFAULT: None

shutdown_timeout

Maximum seconds to wait for the MeterProvider.shutdown() flush. On timeout the call is abandoned (the daemon shutdown thread keeps running but cannot block loop teardown), a warning is logged, and the rest of __aexit__ proceeds. Pending metrics may be dropped.

TYPE: float | None DEFAULT: None

env_load

Whether to read GREL_METRICS_* environment variables. When None (default), follow GREL_ENV_LOAD.

TYPE: bool | None DEFAULT: None

kind class-attribute

kind: str = 'metrics'

singleton class-attribute

singleton: bool = True

name property

name: str

Return the registration name.

config property

config: MetricsConfig

Return the resolved MetricsConfig.

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

provider property

provider: Any

Return the installed OTel MeterProvider.

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

prometheus_registry property

prometheus_registry: Any

Return the Prometheus CollectorRegistry feeding /metrics.

Only the prometheus exporter sets this. For every other exporter the value is None. The FastAPI metrics_router reads this registry to render the exposition format.

from_config classmethod

from_config(
    config: MetricsConfig, *, name: str = "default"
) -> Self

Construct a Metrics from a pre-built MetricsConfig.

PARAMETER DESCRIPTION
config

The pre-built metrics configuration.

Use this path when the configuration is assembled at startup from a settings tree (for example YAML, Vault, or a pydantic-settings aggregator). The environment path is bypassed and the config is used as-is.

TYPE: MetricsConfig

name

Registration name. Defaults to 'default'.

TYPE: str DEFAULT: 'default'

meter

meter(name: str) -> Meter

Return an OTel Meter for name, cached per scope name.

PARAMETER DESCRIPTION
name

Instrumentation scope name, usually the module name.

TYPE: str

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

counter

counter(
    name: str, *, unit: str = "", description: str = ""
) -> Counter

Create (or reuse) a Counter. Monotonic, increase-only.

PARAMETER DESCRIPTION
name

Instrument name, e.g. orders.placed.

TYPE: str

unit

Unit of measure, e.g. 1 or By.

TYPE: str DEFAULT: ''

description

Human-readable description.

TYPE: str DEFAULT: ''

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

histogram

histogram(
    name: str, *, unit: str = "", description: str = ""
) -> Histogram

Create (or reuse) a Histogram for value distributions.

PARAMETER DESCRIPTION
name

Instrument name, e.g. request.duration.

TYPE: str

unit

Unit of measure, e.g. s or By.

TYPE: str DEFAULT: ''

description

Human-readable description.

TYPE: str DEFAULT: ''

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

up_down_counter

up_down_counter(
    name: str, *, unit: str = "", description: str = ""
) -> UpDownCounter

Create (or reuse) an UpDownCounter that can rise and fall.

PARAMETER DESCRIPTION
name

Instrument name, e.g. queue.depth.

TYPE: str

unit

Unit of measure, e.g. 1.

TYPE: str DEFAULT: ''

description

Human-readable description.

TYPE: str DEFAULT: ''

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

gauge

gauge(
    name: str, *, unit: str = "", description: str = ""
) -> _Gauge

Create (or reuse) a synchronous Gauge recording last-set values.

PARAMETER DESCRIPTION
name

Instrument name, e.g. pool.size.

TYPE: str

unit

Unit of measure, e.g. 1.

TYPE: str DEFAULT: ''

description

Human-readable description.

TYPE: str DEFAULT: ''

RAISES DESCRIPTION
RuntimeError

If accessed before the component has been entered.

MetricsConfig

Bases: BaseModel

Metrics Config.

service_name class-attribute instance-attribute

service_name: str | None = None

Service name resource attribute. Falls back to OTEL_SERVICE_NAME when unset.

exporter class-attribute instance-attribute

Metric exporter.

endpoint class-attribute instance-attribute

endpoint: str | None = None

Exporter endpoint. Falls back to OTEL_EXPORTER_OTLP_ENDPOINT when unset.

headers class-attribute instance-attribute

headers: dict[str, str] = Field(default_factory=dict)

Exporter headers. Falls back to OTEL_EXPORTER_OTLP_HEADERS when empty.

export_interval class-attribute instance-attribute

export_interval: PositiveFloat = 60.0

Seconds between exports for the periodic reader. Applies to the OTLP and console exporters. The Prometheus exporter is pull-based and ignores this value.

export_timeout class-attribute instance-attribute

export_timeout: PositiveFloat = 30.0

Maximum seconds a single periodic export may take before it is abandoned.

resource_attributes class-attribute instance-attribute

resource_attributes: dict[str, str] = Field(
    default_factory=dict
)

Extra resource attributes.

shutdown_timeout class-attribute instance-attribute

shutdown_timeout: PositiveFloat = 5.0

Maximum seconds to wait for the MeterProvider.shutdown() flush. A slow or broken exporter no longer hangs application shutdown past this deadline.

MetricsError

Bases: GrelmicroError

Base metrics error.

MetricsExporterType

Bases: _CaseInsensitiveEnum

Metric exporter selection.

OTLP_HTTP class-attribute instance-attribute

OTLP_HTTP = 'otlp-http'

OTLP_GRPC class-attribute instance-attribute

OTLP_GRPC = 'otlp-grpc'

PROMETHEUS class-attribute instance-attribute

PROMETHEUS = 'prometheus'

CONSOLE class-attribute instance-attribute

CONSOLE = 'console'

NONE class-attribute instance-attribute

NONE = 'none'

MetricsSettingsValidationError

MetricsSettingsValidationError(
    error: ValidationError | str,
)

Bases: MetricsError, SettingsValidationError

Raised when the metrics configuration fails validation.

measure

measure(func: Callable[P, R]) -> Callable[P, R]
measure(
    *,
    name: str | None = None,
    record_in_flight: bool = False,
) -> Callable[[Callable[P, R]], Callable[P, R]]
measure(
    func: Callable[P, R] | None = None,
    *,
    name: str | None = None,
    record_in_flight: bool = False,
) -> (
    Callable[P, R]
    | Callable[[Callable[P, R]], Callable[P, R]]
)

Measure a function's duration, call count, and optional in-flight gauge.

Emits three metrics, all no-ops when no Metrics component is active:

  • <name>.duration: a histogram of wall-clock seconds.
  • <name>.calls: a counter with an outcome attribute (success or error). On failure an error.type attribute carries the exception class name.
  • <name>.active: an up_down_counter present only when record_in_flight=True. Rises on entry, falls on exit.

The base name defaults to the function's module and qualified name, lowercased and dotted. Works on sync and async functions.

PARAMETER DESCRIPTION
func

The function to measure. Bound automatically when @measure is used bare. None when called with arguments (@measure(...)) so the inner decorator can wrap the target.

TYPE: Callable[P, R] | None DEFAULT: None

name

Override the metric base name. Defaults to the wrapped function's module and qualified name, lowercased and dotted.

TYPE: str | None DEFAULT: None

record_in_flight

Also emit a <name>.active up_down_counter that rises while the function runs and falls when it returns or raises.

TYPE: bool DEFAULT: False

PARAMETER DESCRIPTION
func

The function to measure (set automatically for bare decorator).

TYPE: Callable[P, R] | None DEFAULT: None

name

Custom base name. Defaults to the function's dotted qualname.

TYPE: str | None DEFAULT: None

record_in_flight

Emit a <name>.active in-flight gauge.

TYPE: bool DEFAULT: False

metrics_router

metrics_router(
    component: Metrics | None = None,
    *,
    prefix: str = "",
    path: str = "/metrics",
    dependencies: list[Depends] | None = None,
) -> APIRouter

Create a FastAPI router that serves Prometheus metrics.

Mounts GET {prefix}{path} (default GET /metrics) returning the Prometheus exposition format rendered from the component's collector registry. The active component must use the prometheus exporter.

PARAMETER DESCRIPTION
component

Metrics component whose Prometheus registry the endpoint renders. When omitted, the router resolves the default instance from the active Grelmicro app (Grelmicro(uses=[Metrics(...)])).

TYPE: Metrics | None DEFAULT: None

prefix

URL prefix for the metrics endpoint (e.g. '/api/v1').

TYPE: str DEFAULT: ''

path

Path of the metrics endpoint under the prefix.

TYPE: str DEFAULT: '/metrics'

dependencies

FastAPI dependencies applied to the metrics endpoint. A failing dependency blocks the endpoint (401/403). Use to gate /metrics behind authentication.

TYPE: list[Depends] | None DEFAULT: None

RAISES DESCRIPTION
DependencyNotFoundError

If fastapi is not installed.