Skip to main content

Overview

OpenTelemetry Rust can be configured through:
  • Environment variables (runtime configuration)
  • Cargo feature flags (compile-time configuration)
  • Programmatic configuration (in code)

Environment variables

General configuration

VariableDescriptionDefault
OTEL_SDK_DISABLEDDisable the SDKfalse
OTEL_RESOURCE_ATTRIBUTESResource attributes as key-value pairs
OTEL_SERVICE_NAMEService nameunknown_service
OTEL_LOG_LEVELSDK log level (error, warn, info, debug, trace)info

OTLP exporter configuration

VariableDescriptionDefault
OTEL_EXPORTER_OTLP_ENDPOINTOTLP endpoint URLhttp://localhost:4317
OTEL_EXPORTER_OTLP_PROTOCOLProtocol (grpc, http/protobuf, http/json)grpc
OTEL_EXPORTER_OTLP_TIMEOUTExport timeout in milliseconds10000
OTEL_EXPORTER_OTLP_HEADERSHeaders as key-value pairs
OTEL_EXPORTER_OTLP_COMPRESSIONCompression (gzip, none)none

Signal-specific endpoints

VariableDescription
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTTraces endpoint
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTMetrics endpoint
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTLogs endpoint
OTEL_EXPORTER_OTLP_TRACES_HEADERSTraces headers
OTEL_EXPORTER_OTLP_METRICS_HEADERSMetrics headers
OTEL_EXPORTER_OTLP_LOGS_HEADERSLogs headers

Batch processor configuration

Spans:
VariableDescriptionDefault
OTEL_BSP_MAX_QUEUE_SIZEMax queue size2048
OTEL_BSP_MAX_EXPORT_BATCH_SIZEMax batch size512
OTEL_BSP_SCHEDULE_DELAYExport interval (ms)5000
OTEL_BSP_EXPORT_TIMEOUTExport timeout (ms)30000
Logs:
VariableDescriptionDefault
OTEL_BLRP_MAX_QUEUE_SIZEMax queue size2048
OTEL_BLRP_MAX_EXPORT_BATCH_SIZEMax batch size512
OTEL_BLRP_SCHEDULE_DELAYExport interval (ms)1000
OTEL_BLRP_EXPORT_TIMEOUTExport timeout (ms)30000

Trace configuration

VariableDescriptionDefault
OTEL_TRACES_SAMPLERSampler typeparentbased_always_on
OTEL_TRACES_SAMPLER_ARGSampler argument
OTEL_SPAN_ATTRIBUTE_COUNT_LIMITMax attributes per span128
OTEL_SPAN_EVENT_COUNT_LIMITMax events per span128
OTEL_SPAN_LINK_COUNT_LIMITMax links per span128
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMITMax attribute value lengthunlimited

Sampler types

  • always_on - Sample all spans
  • always_off - Sample no spans
  • traceidratio - Sample based on trace ID (requires OTEL_TRACES_SAMPLER_ARG = ratio)
  • parentbased_always_on - Use parent decision, otherwise always sample
  • parentbased_always_off - Use parent decision, otherwise never sample
  • parentbased_traceidratio - Use parent decision, otherwise ratio-based

Propagator configuration

VariableDescriptionDefault
OTEL_PROPAGATORSComma-separated list of propagatorstracecontext,baggage
Supported propagators:
  • tracecontext - W3C Trace Context
  • baggage - W3C Baggage
  • b3 - B3 single header
  • b3multi - B3 multi header
  • jaeger - Jaeger propagation
  • xray - AWS X-Ray
  • ottrace - OpenTracing

Feature flags

opentelemetry crate

[dependencies]
opentelemetry = { version = "0.31", features = [
    "trace",           # Tracing API
    "metrics",         # Metrics API
    "logs",            # Logs API
    "internal-logs",   # Internal SDK logging
]}

opentelemetry-sdk crate

[dependencies]
opentelemetry_sdk = { version = "0.31", features = [
    "trace",           # Tracing SDK
    "metrics",         # Metrics SDK
    "logs",            # Logs SDK
    "rt-tokio",        # Tokio runtime for batch processors
    "rt-tokio-current-thread",  # Tokio current-thread runtime
]}
Experimental features:
[dependencies]
opentelemetry_sdk = { version = "0.31", features = [
    "jaeger_remote_sampler",  # Jaeger remote sampling
    "experimental_metrics_periodicreader_with_async_runtime",
    "experimental_logs_batch_log_processor_with_async_runtime",
    "experimental_trace_batch_span_processor_with_async_runtime",
]}

opentelemetry-otlp crate

[dependencies]
opentelemetry-otlp = { version = "0.31", features = [
    "grpc-tonic",      # gRPC with tonic
    "http-proto",      # HTTP with protobuf
    "http-json",       # HTTP with JSON
    "reqwest-blocking", # Blocking reqwest client
    "reqwest-rustls",  # Reqwest with rustls
    "compression-gzip", # gzip compression
    "compression-zstd", # zstd compression
]}

Complete configuration example

Environment file (.env)

# Service identification
OTEL_SERVICE_NAME=my-rust-service
OTEL_RESOURCE_ATTRIBUTES=service.version=1.0.0,deployment.environment=production

# OTLP exporter
OTEL_EXPORTER_OTLP_ENDPOINT=https://otel-collector.example.com:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_HEADERS=api-key=secret123
OTEL_EXPORTER_OTLP_COMPRESSION=gzip
OTEL_EXPORTER_OTLP_TIMEOUT=30000

# Batch processing
OTEL_BSP_MAX_QUEUE_SIZE=4096
OTEL_BSP_MAX_EXPORT_BATCH_SIZE=1024
OTEL_BSP_SCHEDULE_DELAY=10000

# Sampling
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1

# Propagation
OTEL_PROPAGATORS=tracecontext,baggage

# Limits
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=256
OTEL_SPAN_EVENT_COUNT_LIMIT=256

Cargo.toml

[dependencies]
opentelemetry = { version = "0.31", features = ["trace", "metrics", "logs"] }
opentelemetry_sdk = { version = "0.31", features = ["trace", "metrics", "logs", "rt-tokio"] }
opentelemetry-otlp = { version = "0.31", features = [
    "grpc-tonic",
    "compression-gzip",
    "reqwest-rustls",
]}

Application code

use opentelemetry::global;
use opentelemetry_sdk::{
    trace::{TracerProvider, BatchSpanProcessor},
    Resource,
    runtime::Tokio,
};
use opentelemetry_otlp::SpanExporter;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Resource detection uses OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES
    let resource = Resource::builder().build();
    
    // Exporter uses OTEL_EXPORTER_OTLP_* variables
    let exporter = SpanExporter::builder()
        .with_tonic()  // Uses OTEL_EXPORTER_OTLP_ENDPOINT
        .build()?;
    
    // Batch processor uses OTEL_BSP_* variables
    let processor = BatchSpanProcessor::builder(exporter, Tokio).build();
    
    let provider = TracerProvider::builder()
        .with_resource(resource)
        .with_span_processor(processor)
        .build();
    
    global::set_tracer_provider(provider);
    
    // Application code...
    
    global::shutdown_tracer_provider();
    Ok(())
}

Override precedence

Configuration is resolved in this order (highest to lowest priority):
  1. Programmatic configuration - Values set in code
  2. Environment variables - Runtime configuration
  3. Default values - Built-in defaults
// Programmatic configuration takes precedence
let exporter = SpanExporter::builder()
    .with_tonic()
    .with_endpoint("http://custom-endpoint:4317")  // Overrides OTEL_EXPORTER_OTLP_ENDPOINT
    .build()?;

Best practices

Use environment variables for deployment - Different environments (dev, staging, prod) can have different configurations without code changes.
Validate configuration - Check that environment variables are set correctly before running in production.
Secure sensitive values - Don’t commit API keys or tokens to version control. Use secret management systems.
Feature flags reduce binary size - Only enable the features you need to minimize dependencies and compile time.

Configuration by environment

Development

OTEL_SERVICE_NAME=my-service-dev
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
OTEL_TRACES_SAMPLER=always_on
OTEL_BSP_SCHEDULE_DELAY=1000  # Fast export for debugging

Staging

OTEL_SERVICE_NAME=my-service-staging
OTEL_EXPORTER_OTLP_ENDPOINT=https://staging-collector.example.com:4317
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.5  # 50% sampling
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=staging

Production

OTEL_SERVICE_NAME=my-service
OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com:4317
OTEL_EXPORTER_OTLP_HEADERS=api-key=${SECRET_API_KEY}
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1  # 10% sampling
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,service.version=${APP_VERSION}
OTEL_BSP_MAX_QUEUE_SIZE=8192  # Higher throughput

Resource detection

Configure resource attributes

Batch processing

Tune batch processor settings

Build docs developers (and LLMs) love