Menu
Datadog Blog·September 1, 2026

Building Reliable Rust Observability at Scale with OpenTelemetry

This article explores Datadog's approach to enhancing Rust application observability at scale by developing an opinionated OpenTelemetry-based library. It addresses critical system design challenges like consistent sampling, context propagation, and ensuring high-quality trace data in complex distributed environments. The solution emphasizes standardization and automation to achieve reliable telemetry across diverse services.

Read original on Datadog Blog

The Challenge of Distributed Tracing in Rust

In distributed systems, especially those leveraging languages like Rust known for performance but also complexity, achieving reliable observability is paramount. The article highlights the inherent difficulties in ensuring consistent trace propagation and sampling across numerous services. Without a standardized approach, engineering teams often face fragmented visibility, making debugging and performance analysis a significant hurdle in large-scale deployments.

Leveraging OpenTelemetry for Standardization

Datadog chose OpenTelemetry as the foundation for their Rust observability library due to its vendor-agnostic and extensible nature. OpenTelemetry provides specifications and SDKs for collecting telemetry data (traces, metrics, logs), which is crucial for building a unified observability strategy. However, merely adopting OpenTelemetry isn't enough; an opinionated library was needed to enforce best practices and reduce cognitive load for developers.

ℹ️

Key Observability Concepts

Distributed Tracing: Follows requests as they propagate through microservices, helping identify bottlenecks. Sampling: Reduces the volume of trace data by selecting a subset of traces to store and analyze. Context Propagation: The mechanism by which trace identifiers are passed between services so that spans can be linked together into a single trace.

Architectural Considerations for a Custom Library

  • Consistent Sampling Strategies: Implementing a deterministic sampling mechanism that balances data fidelity with cost and performance, potentially involving head-based or tail-based sampling.
  • Automated Context Propagation: Ensuring trace contexts are automatically injected and extracted across network boundaries and asynchronous operations, which is particularly challenging in Rust's concurrency models.
  • Developer Experience (DX): Simplifying the API for developers to instrument their code, reducing boilerplate, and providing clear guidance on how to emit high-quality telemetry.
  • Extensibility and Integrations: Designing the library to be easily extendable for custom instrumentation and integrated with existing Datadog agents and backend services.

The design of such a library often involves wrapping OpenTelemetry primitives with higher-level abstractions that enforce specific company policies, ensuring that all services adhere to a common observability standard. This reduces inconsistencies and improves the overall quality and usefulness of collected telemetry data, which is vital for operating reliable distributed systems.

rust
use datadog_opentelemetry_rust::start_tracing;
use tracing::{info, instrument};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize the Datadog-specific OpenTelemetry tracing setup
    let _tracer = start_tracing("my-rust-service");

    // Your application logic, now automatically instrumented
    my_business_logic().await;

    info!("Service finished execution.");
    Ok(())
}

#[instrument]
async fn my_business_logic() {
    info!("Executing business logic...");
    // ... further async calls that will be part of the same trace
}
RustOpenTelemetryObservabilityDistributed TracingSREMicroservicesTelemetryInstrumentation

Comments

Loading comments...