Record independent point-in-time values with Gauge instruments in OpenTelemetry Rust
A Gauge is a synchronous instrument that records independent, non-additive values. Gauges are ideal for measurements where only the current value matters, such as CPU usage, memory consumption, or temperature.
Values are independent measurements (not cumulative)
You’re measuring instantaneous state
Historical values aren’t aggregated
Common examples:
CPU usage percentage
Memory consumption
Temperature readings
Cache size
Queue depth at a point in time
Thread pool size
Gauges record point-in-time values. The last value recorded is what gets exported. Unlike histograms, gauges don’t calculate distributions or percentiles.
use opentelemetry::KeyValue;// Record a simple valuef64_gauge.record(45.2, &[]);// Record with attributesf64_gauge.record( 67.8, &[ KeyValue::new("core", "0"), KeyValue::new("host", "server-01"), ],);// Each call overwrites the previous value for the same attribute setf64_gauge.record(52.1, &[KeyValue::new("core", "0")]);
Each call to record with the same attribute set overwrites the previous value. Only the last recorded value is exported.
use opentelemetry::{global, KeyValue};use opentelemetry_sdk::metrics::SdkMeterProvider;use opentelemetry_sdk::Resource;fn init_meter_provider() -> SdkMeterProvider { 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()); provider}fn main() -> Result<(), Box<dyn std::error::Error>> { let meter_provider = init_meter_provider(); let meter = global::meter("system-monitor"); // Create gauges for system metrics let cpu_gauge = meter .f64_gauge("cpu_usage") .with_description("Current CPU usage percentage") .with_unit("%") .build(); let memory_gauge = meter .u64_gauge("memory_usage") .with_description("Current memory usage in bytes") .with_unit("By") .build(); let temperature_gauge = meter .i64_gauge("cpu_temperature") .with_description("Current CPU temperature") .with_unit("Cel") .build(); // Record current system state cpu_gauge.record(45.2, &[KeyValue::new("core", "0")]); cpu_gauge.record(52.1, &[KeyValue::new("core", "1")]); memory_gauge.record(1024 * 1024 * 512, &[]); temperature_gauge.record(65, &[KeyValue::new("sensor", "cpu0")]); meter_provider.shutdown()?; Ok(())}
let temperature = meter.i64_gauge("temperature").with_unit("Cel").build();temperature.record(-15, &[KeyValue::new("location", "freezer")]);let balance = meter.i64_gauge("account_balance").build();balance.record(-250, &[]);
let cpu_usage = meter.f64_gauge("cpu_usage").with_unit("%").build();cpu_usage.record(67.8, &[]);let voltage = meter.f64_gauge("voltage").with_unit("V").build();voltage.record(3.3, &[KeyValue::new("rail", "vcc")]);
// Use when you control when to recordlet gauge = meter.f64_gauge("cpu_usage").build();loop { let usage = calculate_cpu_usage(); gauge.record(usage, &[]); thread::sleep(Duration::from_secs(1));}
Gauges support attributes to track multiple related measurements:
let cpu_gauge = meter.f64_gauge("cpu_usage").build();// Different CPU corescpu_gauge.record(45.2, &[KeyValue::new("core", "0")]);cpu_gauge.record(52.1, &[KeyValue::new("core", "1")]);cpu_gauge.record(38.7, &[KeyValue::new("core", "2")]);cpu_gauge.record(61.3, &[KeyValue::new("core", "3")]);
Each unique attribute combination creates a separate gauge value. Keep cardinality reasonable to avoid memory issues.
Gauges can be cloned to share across your application:
let gauge = meter.f64_gauge("temperature").build();let gauge_clone = gauge.clone();// Both record to the same underlying gaugegauge.record(22.5, &[]);gauge_clone.record(23.1, &[]); // Overwrites previous value
Clone gauges when sharing across modules. Avoid creating multiple gauges with the same name.
// Only the last value matterslet gauge = meter.f64_gauge("cpu_usage").build();gauge.record(45.2, &[]);gauge.record(67.8, &[]);gauge.record(52.1, &[]);// Exported: 52.1
// Records current value, not changeslet gauge = meter.i64_gauge("queue_depth").build();gauge.record(10, &[]); // Queue has 10 itemsgauge.record(15, &[]); // Queue now has 15 items
let cpu = meter.f64_gauge("system_cpu_usage").with_unit("%").build();let memory = meter.u64_gauge("system_memory_used").with_unit("By").build();let disk = meter.u64_gauge("disk_space_available").with_unit("By").build();cpu.record(67.8, &[]);memory.record(8589934592, &[]); // 8 GB in bytesdisk.record(107374182400, &[]); // 100 GB in bytes