Skip to main content

What is OpenTelemetry?

OpenTelemetry is a vendor-neutral observability framework for cloud-native software. It provides a collection of APIs, SDKs, and tools to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior. The OpenTelemetry Rust implementation consists of two main components:
  • API (opentelemetry crate): Defines interfaces for instrumentation
  • SDK (opentelemetry_sdk crate): Provides implementations of the API for data collection and export

Architecture

OpenTelemetry follows a layered architecture that separates concerns:
// API layer - used by application developers
use opentelemetry::{global, trace::Tracer, KeyValue};

// SDK layer - used for configuration
use opentelemetry_sdk::trace::SdkTracerProvider;
This separation allows you to write instrumentation code once using the API, while swapping out different SDK implementations for different environments.

Three Pillars of Observability

OpenTelemetry provides three types of telemetry signals:

Traces

Traces track the progression of requests as they flow through distributed systems. Each trace is composed of spans representing individual operations.
use opentelemetry::{global, trace::{Span, Tracer}, KeyValue};

// Get a tracer from a provider
let tracer = global::tracer("my_service");

// Start a new span
let mut span = tracer.start("my_span");

// Set some attributes
span.set_attribute(KeyValue::new("http.client_ip", "83.164.160.102"));

// Perform some work...

// End the span to export
span.end();

Metrics

Metrics provide quantitative measurements about your service. OpenTelemetry supports various instrument types for different measurement patterns.
use opentelemetry::{global, KeyValue};

// Get a meter from a provider
let meter = global::meter("my_service");

// Create an instrument (in this case, a Counter)
let counter = meter.u64_counter("request.count").build();

// Record a measurement
counter.add(1, &[KeyValue::new("http.client_ip", "83.164.160.102")]);

Logs

The logs API provides a bridge between existing logging libraries and OpenTelemetry. It’s not intended to be called directly by application developers.
// Application developers use familiar logging libraries
use tracing::error;

error!(
    name: "my-event-name",
    event_id = 20,
    user_name = "otel",
    message = "This is an example message"
);
The OpenTelemetry appenders (opentelemetry-appender-log and opentelemetry-appender-tracing) bridge these logs to the OpenTelemetry ecosystem.

Global Providers

OpenTelemetry uses global provider singletons to make telemetry available throughout your application:
use opentelemetry::global;
use opentelemetry_sdk::trace::SdkTracerProvider;

// Configure the global TracerProvider singleton
let provider = SdkTracerProvider::builder()
    .with_simple_exporter(exporter)
    .build();

global::set_tracer_provider(provider);

// Later, anywhere in your codebase:
let tracer = global::tracer("my-component");
This pattern allows libraries to instrument their code without requiring dependency injection.

Getting Started

The typical setup flow for OpenTelemetry involves:
  1. Choose an exporter - Determine where you want to send telemetry (stdout, OTLP, Prometheus, etc.)
  2. Configure providers - Set up TracerProvider, MeterProvider, and/or LoggerProvider
  3. Instrument your code - Use the API to create spans, record metrics, and emit logs
  4. Export telemetry - Configure how and when data is sent to your observability backend
use opentelemetry::{global, trace::Tracer};
use opentelemetry_sdk::trace::SdkTracerProvider;

fn main() {
    // Initialize the SDK
    let provider = SdkTracerProvider::builder()
        .with_simple_exporter(exporter)
        .build();
    global::set_tracer_provider(provider.clone());

    // Use the API for instrumentation
    let tracer = global::tracer("my_app");
    tracer.in_span("doing_work", |cx| {
        // Your application logic here
    });

    // Cleanup
    provider.shutdown().expect("Failed to shutdown provider");
}

Next Steps

Signals

Deep dive into traces, metrics, and logs

Resources

Learn about resource detection and attributes

Context Propagation

Understand how context flows across services

Quick Start

Start instrumenting your application
The OpenTelemetry Rust ecosystem includes several crates:
  • opentelemetry - Core API
  • opentelemetry_sdk - SDK implementation
  • opentelemetry-otlp - OTLP exporter
  • opentelemetry-stdout - Stdout exporter for debugging
  • opentelemetry-prometheus - Prometheus metrics exporter
  • opentelemetry-zipkin - Zipkin trace exporter
  • opentelemetry-http - HTTP context propagation utilities

Build docs developers (and LLMs) love