> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/open-telemetry/opentelemetry-rust/llms.txt
> Use this file to discover all available pages before exploring further.

# Meters

> Create and configure Meters for instrumenting your Rust applications with OpenTelemetry

A `Meter` is the entry point for creating instruments that record measurements in your application. Meters should be scoped to a single library or application component.

## MeterProvider

The `MeterProvider` trait provides access to named `Meter` instances:

```rust theme={null}
pub trait MeterProvider {
    fn meter(&self, name: &'static str) -> Meter;
    fn meter_with_scope(&self, scope: InstrumentationScope) -> Meter;
}
```

## Creating a Meter

There are two ways to create a meter:

### Simple Meter Creation

The simplest way is to use a static name:

```rust theme={null}
use opentelemetry::{global, metrics::MeterProvider};

let provider = global::meter_provider();
let meter = provider.meter("my_app");
```

### Meter with Full Scope

For libraries and crates, you should include version and schema information:

```rust theme={null}
use opentelemetry::InstrumentationScope;
use opentelemetry::metrics::MeterProvider;
use opentelemetry_sdk::metrics::SdkMeterProvider;

let provider = SdkMeterProvider::default();

let scope = InstrumentationScope::builder(env!("CARGO_PKG_NAME"))
    .with_version(env!("CARGO_PKG_VERSION"))
    .with_schema_url("https://opentelemetry.io/schemas/1.0.0")
    .build();

let meter = provider.meter_with_scope(scope);
```

## Meter Naming Guidelines

The meter name should:

* Be unique within your application
* Represent the instrumentation scope (typically the library or module name)
* Not collide with other applications or libraries
* Be stable across versions

<Tip>
  Use your crate name as the meter name. For applications, use the application name. For libraries, use `env!("CARGO_PKG_NAME")` to automatically use your crate name.
</Tip>

## Global Meter Provider

OpenTelemetry provides a global meter provider that can be accessed from anywhere in your application:

```rust theme={null}
use opentelemetry::global;
use opentelemetry_sdk::metrics::SdkMeterProvider;
use opentelemetry_sdk::Resource;

// Initialize and set global provider
let exporter = opentelemetry_stdout::MetricExporterBuilder::default().build();
let provider = SdkMeterProvider::builder()
    .with_periodic_exporter(exporter)
    .with_resource(
        Resource::builder()
            .with_service_name("metrics-basic-example")
            .build(),
    )
    .build();

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

// Access the global provider from anywhere
let meter = global::meter("mylibraryname");
```

## Creating Instruments

Once you have a `Meter`, you can create instruments to record measurements. All instruments are created using a builder pattern:

```rust theme={null}
use opentelemetry::KeyValue;

let meter = global::meter("my-meter");

// Counter
let counter = meter.u64_counter("requests_total")
    .with_description("Total number of requests")
    .with_unit("requests")
    .build();

counter.add(1, &[KeyValue::new("method", "GET")]);

// Histogram
let histogram = meter.f64_histogram("request_duration")
    .with_description("Request duration in seconds")
    .with_unit("s")
    .with_boundaries(vec![0.0, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0])
    .build();

histogram.record(0.123, &[KeyValue::new("endpoint", "/api/users")]);

// Gauge
let gauge = meter.f64_gauge("cpu_usage")
    .with_description("Current CPU usage percentage")
    .with_unit("%")
    .build();

gauge.record(45.2, &[KeyValue::new("core", "0")]);
```

## Available Instrument Builders

The `Meter` provides builders for all instrument types:

### Synchronous Instruments

```rust theme={null}
// Counters (monotonically increasing)
pub fn u64_counter(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, Counter<u64>>
pub fn f64_counter(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, Counter<f64>>

// UpDownCounters (can increase or decrease)
pub fn i64_up_down_counter(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, UpDownCounter<i64>>
pub fn f64_up_down_counter(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, UpDownCounter<f64>>

// Gauges (independent values)
pub fn u64_gauge(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, Gauge<u64>>
pub fn i64_gauge(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, Gauge<i64>>
pub fn f64_gauge(&self, name: impl Into<Cow<'static, str>>) -> InstrumentBuilder<'_, Gauge<f64>>

// Histograms (distributions)
pub fn f64_histogram(&self, name: impl Into<Cow<'static, str>>) -> HistogramBuilder<'_, Histogram<f64>>
pub fn u64_histogram(&self, name: impl Into<Cow<'static, str>>) -> HistogramBuilder<'_, Histogram<u64>>
```

### Asynchronous Instruments

```rust theme={null}
// Observable Counters
pub fn u64_observable_counter(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableCounter<u64>, u64>
pub fn f64_observable_counter(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableCounter<f64>, f64>

// Observable UpDownCounters
pub fn i64_observable_up_down_counter(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<i64>, i64>
pub fn f64_observable_up_down_counter(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableUpDownCounter<f64>, f64>

// Observable Gauges
pub fn u64_observable_gauge(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableGauge<u64>, u64>
pub fn i64_observable_gauge(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableGauge<i64>, i64>
pub fn f64_observable_gauge(&self, name: impl Into<Cow<'static, str>>) -> AsyncInstrumentBuilder<'_, ObservableGauge<f64>, f64>
```

## Instrument Configuration

All instrument builders support common configuration options:

```rust theme={null}
let instrument = meter.u64_counter("my_counter")
    .with_description("A detailed description of what this measures")
    .with_unit("requests")  // Unit is case-sensitive: "kb" != "kB"
    .build();
```

<Warning>
  Unit names are case-sensitive. Use standard units like "ms" for milliseconds, "s" for seconds, "By" for bytes, etc.
</Warning>

## Instrument Reuse

Instruments can be cloned to create multiple handles to the same underlying metric:

```rust theme={null}
let counter = meter.u64_counter("requests").build();
let counter_clone = counter.clone();

// Both record to the same metric
counter.add(1, &[]);
counter_clone.add(1, &[]);
```

<Tip>
  Clone instruments rather than creating duplicates. Creating multiple instruments with the same name can lower SDK performance.
</Tip>

## Shutting Down

When your application terminates, shut down the meter provider to flush any pending metrics:

```rust theme={null}
meter_provider.shutdown()?;
```

This ensures all metrics are exported before the application exits.

## Next Steps

<CardGroup cols={2}>
  <Card title="Instruments" href="/metrics/instruments">
    Learn about the different instrument types
  </Card>

  <Card title="Counter" href="/metrics/counter">
    Record monotonically increasing values
  </Card>

  <Card title="Histogram" href="/metrics/histogram">
    Record value distributions
  </Card>

  <Card title="Observable Instruments" href="/metrics/observable-instruments">
    Use callbacks to report measurements
  </Card>
</CardGroup>
