SigNoz Cloud - This page is relevant for SigNoz Cloud editions.
Self-Host - This page is relevant for self-hosted SigNoz editions.

Rust OpenTelemetry Instrumentation

This document contains instructions on how to set up OpenTelemetry (OTel) instrumentation in your Rust applications and view your application traces in SigNoz.

Info

Using self-hosted SigNoz? Most steps are identical. To adapt this guide, update the endpoint and remove the ingestion key header as shown in Cloud → Self-Hosted.

Prerequisites

Send traces to SigNoz

Based on your application environment, you can choose the setup below to send traces to SigNoz.

From VMs, there are two ways to send data to SigNoz:

  • Direct to SigNoz Cloud (recommended for beginners): no extra installs beyond the SDK; you only need the region endpoint and ingestion key.
  • Via OTel Collector binary: it listens at http://localhost:4318, forwards telemetry to SigNoz, and does not require an ingestion key from the app. Install it with the OTel Collector binary guide.

Step 1: Instrument your application with OpenTelemetry

To configure your Rust application to send data, we need to initialize OpenTelemetry. OpenTelemetry provides crates which you need to add to your Cargo.toml file, just below the [dependencies] section.

Cargo.toml
opentelemetry = { version = "0.27.0", features = ["trace"] }
opentelemetry_sdk = { version = "0.27.0", features = ["trace", "rt-tokio"] }
opentelemetry-otlp = { version = "0.27.0", features = ["grpc-tonic", "trace", "tls-roots"] }
tokio = { version = "1", features = ["full"] }
tonic = { version = "0.12" }

After adding these in Cargo.toml, you need to use them in the entry point of your Rust application, which is the main.rs file in the majority of applications.

src/main.rs
use opentelemetry::trace::{TraceContextExt, Tracer};
use opentelemetry::{global, KeyValue};
use opentelemetry_otlp::{SpanExporter, WithExportConfig, WithTonicConfig};
use opentelemetry_sdk::trace::TracerProvider;
use opentelemetry_sdk::Resource;

Step 2: Initialize the tracer and create the env file

Add the following function to your main.rs file. The init_tracer function initializes an OpenTelemetry tracer with the OpenTelemetry OTLP exporter, which sends data to SigNoz Cloud.

src/main.rs
fn init_tracer() -> TracerProvider {
    let signoz_ingestion_key = std::env::var("SIGNOZ_INGESTION_KEY")
        .expect("SIGNOZ_INGESTION_KEY not set");
    let signoz_endpoint = std::env::var("SIGNOZ_ENDPOINT")
        .expect("SIGNOZ_ENDPOINT not set");
    let app_name = std::env::var("APP_NAME")
        .expect("APP_NAME not set");

    let mut metadata = tonic::metadata::MetadataMap::new();
    metadata.insert(
        "signoz-ingestion-key",
        tonic::metadata::MetadataValue::try_from(&signoz_ingestion_key).unwrap(),
    );

    let exporter = SpanExporter::builder()
        .with_tonic()
        .with_tls_config(tonic::transport::ClientTlsConfig::new().with_native_roots())
        .with_metadata(metadata)
        .with_endpoint(signoz_endpoint)
        .build()
        .expect("Failed to create span exporter");

    let resource = Resource::new(vec![
        KeyValue::new("service.name", app_name),
    ]);

    TracerProvider::builder()
        .with_resource(resource)
        .with_batch_exporter(exporter, opentelemetry_sdk::runtime::Tokio)
        .build()
    }

After adding this function, you need to create a .env file in the root of the project. The structure should look like this:

project_root/
|-- Cargo.toml
|-- src/
|   |-- main.rs
|-- .env

Paste the following in the .env file:

PORT=3000
APP_NAME=<service_name>
SIGNOZ_ENDPOINT=https://ingest.<region>.signoz.cloud:443
SIGNOZ_INGESTION_KEY=<your-ingestion-key>
  • Set <region> to match your SigNoz Cloud region
  • Replace <your-ingestion-key> with your SigNoz ingestion key
  • <service_name> is the name of your service
  • PORT (Optional) - If it is a web app, pass the port; otherwise, you can ignore this variable.

Step 3: Add the OpenTelemetry instrumentation for your Rust app

Open your Cargo.toml file and paste these below [dependencies]:

Cargo.toml
dotenv = "0.15.0"

Import these at the top so you can use variables from the .env file:

src/main.rs
use dotenv::dotenv;

After importing, call these functions inside the main() function by pasting the following code at the start of the main() function:

src/main.rs
dotenv().ok();
let tracer_provider = init_tracer();
global::set_tracer_provider(tracer_provider.clone());

Also, change:

src/main.rs
fn main(){
    //rest of the code
}

to

src/main.rs
#[tokio::main]
async fn main() {
    //rest of the code
}

To send data to SigNoz Cloud, add the following block:

src/main.rs
let tracer = global::tracer("my_app");

tracer.in_span("operation", |cx| {
    let span = cx.span();
    span.set_attribute(KeyValue::new("KEY", "value"));

    span.add_event(
        "Operations",
        vec![
            KeyValue::new("SigNoz is", "Awesome"),
        ],
    );
});

// Shutdown trace provider
tracer_provider.shutdown().expect("Failed to shutdown tracer provider");

Step 4: Set environment variables and run app

Go to your .env file and update the values of the required variables: APP_NAME, SIGNOZ_ENDPOINT, and SIGNOZ_INGESTION_KEY.

Run cargo run in the terminal to start the application.

Sample Rust Application

We have included a sample Rust application at Sample Rust App Github Repo.

Get Help

If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack.

If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.

Last updated: November 20, 2025

Edit on GitHub

Was this page helpful?