Skip to main content
The OpenTelemetry Rust Metrics API provides a way to capture measurements about your application’s behavior and performance. Metrics are aggregated measurements that help you understand trends over time.

Key Concepts

The Metrics API consists of several core components:
  • MeterProvider: The entry point for obtaining Meter instances
  • Meter: Creates instruments for recording measurements
  • Instruments: Record measurements synchronously or asynchronously
  • Views: Customize how metrics are aggregated and exported

Instrument Categories

Instruments are categorized as either synchronous or asynchronous:

Synchronous Instruments

Synchronous instruments are used inline with your application’s processing logic. They record measurements as events happen in your code.
  • Counter: Records monotonically increasing values (e.g., requests served, bytes sent)
  • UpDownCounter: Records values that can increase or decrease (e.g., active connections, queue size)
  • Histogram: Records a distribution of values (e.g., request duration, response size)
  • Gauge: Records independent point-in-time values (e.g., CPU usage, memory consumption)

Asynchronous Instruments

Asynchronous instruments use callbacks that are invoked during metric collection. They’re ideal for values that are expensive to compute or are already being tracked elsewhere.
  • ObservableCounter: Observes monotonically increasing values via callback
  • ObservableUpDownCounter: Observes values that can increase or decrease via callback
  • ObservableGauge: Observes current values via callback

Getting Started

To use metrics in your application:
  1. Create a MeterProvider and register it globally
  2. Obtain a Meter from the provider
  3. Create instruments from the meter
  4. Record measurements using the instruments
use opentelemetry::{global, KeyValue};
use opentelemetry_sdk::metrics::SdkMeterProvider;
use opentelemetry_sdk::Resource;

// Initialize the MeterProvider
let exporter = opentelemetry_stdout::MetricExporterBuilder::default().build();
let provider = SdkMeterProvider::builder()
    .with_periodic_exporter(exporter)
    .with_resource(
        Resource::builder()
            .with_service_name("my-service")
            .build(),
    )
    .build();

global::set_meter_provider(provider.clone());

// Get a meter
let meter = global::meter("my-library");

// Create and use a counter
let counter = meter.u64_counter("requests_total").build();
counter.add(1, &[KeyValue::new("endpoint", "/api/users")]);

Choosing the Right Instrument

Counter

Use when values only increase (requests, errors, bytes sent)

UpDownCounter

Use when values can increase or decrease (active connections, queue depth)

Histogram

Use for distributions (latency, request size, temperature)

Gauge

Use for point-in-time values (CPU usage, memory, cache size)

Supported Data Types

Most instruments support multiple numeric types:
  • u64 - Unsigned 64-bit integer
  • i64 - Signed 64-bit integer
  • f64 - 64-bit floating point
The data type is specified as a generic parameter when creating the instrument:
let u64_counter = meter.u64_counter("my_counter").build();
let f64_counter = meter.f64_counter("my_float_counter").build();
let i64_gauge = meter.i64_gauge("my_gauge").build();

Attributes

All measurements can be tagged with attributes (key-value pairs) that add dimensionality to your metrics:
use opentelemetry::KeyValue;

counter.add(
    1,
    &[
        KeyValue::new("method", "GET"),
        KeyValue::new("status", "200"),
        KeyValue::new("endpoint", "/api/users"),
    ],
);
Attributes allow you to slice and dice your metrics data during analysis. However, be mindful of cardinality - too many unique attribute combinations can impact performance.

Next Steps

Meters

Learn about creating and configuring Meters

Instruments

Explore the different instrument types in detail

Views

Customize metric aggregation with Views

Observable Instruments

Use callbacks to report measurements asynchronously

Build docs developers (and LLMs) love