OpenTelemetry Setup
Bridge the KubeMQ Rust SDK tracing events to OpenTelemetry to export traces and metrics to backends like Jaeger or OTLP.
Overview
OpenTelemetry integration wires the SDK's messaging operations into your tracing and metrics pipeline without hand-instrumenting every call site. In a distributed system where a message might be published by one service, queued, and consumed by three others, per-call logging tells you almost nothing — you need spans that correlate across process boundaries and latency/error visibility broken out by channel and operation. The Rust SDK takes a deliberately minimal approach here: it has no built-in OpenTelemetry dependency, only the lightweight tracing crate, which keeps the SDK's dependency footprint small regardless of whether your application uses OTel at all.
The SDK emits tracing spans and events for connections, sends, receives, and errors. Your application bridges those events to an OpenTelemetry backend by registering an OpenTelemetryLayer (from tracing-opentelemetry) on the global tracing_subscriber — once wired up, every SDK-emitted event flows into your OTel pipeline automatically alongside your own instrumented code. Gotchas: the subscriber must be initialized before the KubeMQ client is created, or early connection spans are missed; the stdout exporter shown here is for local debugging only — production needs a real OTLP or Jaeger exporter; and because the bridge lives entirely in your application, not the SDK, a missing or misconfigured subscriber fails silently — the client works fine, it just emits no telemetry.
Prerequisites
- KubeMQ server running on
localhost:50000 - Rust SDK installed (
cargo add kubemq) - Bridge crates in your application (
cargo add tracing-subscriber tracing-opentelemetry opentelemetry_sdk opentelemetry-stdout)
Code
use kubemq::prelude::*;
use kubemq::EventBuilder;
use std::time::Duration;
// The KubeMQ Rust SDK emits `tracing` events for each operation.
// To forward those events to OpenTelemetry you wire up a tracing subscriber
// that includes the tracing-opentelemetry layer in your *application*:
//
// use opentelemetry_sdk::trace::SdkTracerProvider;
// use opentelemetry_stdout::SpanExporter;
// use tracing_opentelemetry::OpenTelemetryLayer;
// use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
//
// let exporter = SpanExporter::default();
// let provider = SdkTracerProvider::builder()
// .with_simple_exporter(exporter)
// .build();
// let tracer = provider.tracer("kubemq-app");
//
// tracing_subscriber::registry()
// .with(OpenTelemetryLayer::new(tracer))
// .init();
//
// After that, all `tracing` events emitted by the SDK (and your own
// instrumented code) flow into the OpenTelemetry pipeline automatically.
#[tokio::main]
async fn main() -> kubemq::Result<()> {
// Initialise a minimal tracing subscriber so SDK events appear on stdout.
// Replace this with the OpenTelemetry setup above for production use.
tracing_subscriber::fmt::init();
let client = KubemqClient::builder()
.host("localhost")
.port(50000)
.build()
.await?;
let event = EventBuilder::new()
.channel("rust-observability.otel-example")
.body(b"traced-event".to_vec())
.metadata("otel-demo")
.build();
client.send_event(event).await?;
println!("Event sent — tracing events emitted to subscriber");
tokio::time::sleep(Duration::from_secs(1)).await;
client.close().await?;
Ok(())
}How It Works
- The KubeMQ Rust SDK depends only on the
tracingcrate for diagnostics — there is no OpenTelemetry dependency inside the SDK itself. - The SDK emits
tracingspans and events for connections, sends, receives, and errors. - To route those events to an OTel backend, add
tracing-opentelemetryto your application and register anOpenTelemetryLayeron the global tracing subscriber (see the commented setup above). - For production, replace the stdout exporter (
opentelemetry-stdout) with an OTLP exporter targeting Jaeger, Zipkin, or any OTel-compatible collector. - Review timeouts, channel names, and client IDs before running against shared environments.
- Run the program while the server from the prerequisites is available.
Related
Was this page helpful?