OpenTelemetry Setup
Configure distributed tracing and metrics with OpenTelemetry
Overview
OpenTelemetry integration is meant to wire the SDK's messaging operations into your tracing and metrics pipeline without hand-instrumenting every call site — in a distributed system where a message is published by one service and consumed by another, per-call logging tells you almost nothing compared to spans that correlate across process boundaries. The C++ SDK's OTel support is designed around that goal: registering a TracerProvider and MeterProvider globally before creating the client is intended to make every gRPC call automatically instrumented.
set_tracer_provider() and set_meter_provider() accept a provider pointer, and SendEvent/SendCommand/queue operations are meant to generate spans against whatever provider is registered. Gotchas: this integration is not yet active in the current release — the SDK ships a no-op stub (otel.cc) where OtelSpan, OtelCounter, and OtelHistogram are empty implementations that compile away, so no spans or metrics are actually emitted regardless of what provider you register; the example demonstrates the intended shape of the API, not working telemetry, and says so explicitly at runtime; and enabling this in the future will require rebuilding with -DKUBEMQ_ENABLE_OTEL=ON plus the opentelemetry-cpp SDK — don't assume it's active just because your build flags are set today.
Prerequisites
- KubeMQ server running on
localhost:50000 - C++ SDK installed with
KUBEMQ_ENABLE_OTEL=ON(see CMake build instructions) - C++17 compiler (GCC 9+, Clang 9+, MSVC 2019+)
opentelemetry-cppSDK installed (vcpkg:opentelemetry-cpp)- OpenTelemetry collector or compatible backend (Jaeger, Zipkin, OTLP endpoint)
Code
// Example: observability/opentelemetry_setup
//
// Demonstrates OpenTelemetry integration for distributed tracing and metrics
// with the KubeMQ C++ SDK. When an OpenTelemetry TracerProvider and
// MeterProvider are globally registered, the SDK instruments gRPC calls
// automatically. This example sends a demo event to generate trace spans.
//
// Channel: cpp-observability.opentelemetry-setup
// Client ID: cpp-observability-opentelemetry-setup-client
//
// Build with: cmake -DKUBEMQ_ENABLE_OTEL=ON ...
// Run with a KubeMQ server and optionally an OpenTelemetry collector
// (e.g., Jaeger, Zipkin) for trace visualization.
#include <kubemq/kubemq.h>
#include <chrono>
#include <iostream>
#include <thread>
// To enable OpenTelemetry tracing, install the opentelemetry-cpp SDK and
// configure a TracerProvider before creating the KubeMQ client:
//
// #include <opentelemetry/sdk/trace/tracer_provider.h>
// #include <opentelemetry/exporters/ostream/span_exporter.h>
// #include <opentelemetry/trace/provider.h>
//
// auto exporter = std::make_unique<opentelemetry::exporter::trace::OStreamSpanExporter>();
// auto processor = std::make_unique<opentelemetry::sdk::trace::SimpleSpanProcessor>(
// std::move(exporter));
// auto provider = std::make_shared<opentelemetry::sdk::trace::TracerProvider>(
// std::move(processor));
// opentelemetry::trace::Provider::SetTracerProvider(provider);
int main() {
std::cout << "[1] OpenTelemetry providers configured (using default/no-op)" << std::endl;
std::cout << "[INFO] To see real traces, configure an OpenTelemetry collector and "
<< "replace the no-op provider above." << std::endl;
kubemq::ClientOptions options;
options.set_address("localhost", 50000);
options.set_client_id("cpp-observability-opentelemetry-setup-client");
auto client_result = kubemq::Client::Create(options);
if (!client_result.ok()) {
std::cerr << "[ERROR] Failed to create client: " << client_result.status().message()
<< std::endl;
return 1;
}
auto& client = *client_result;
// Send a demo event to generate trace spans
auto event_result = kubemq::Event::Builder()
.SetChannel("cpp-observability.opentelemetry-setup")
.SetBody("traced-event")
.SetMetadata("otel-demo")
.Build();
if (!event_result.ok()) {
std::cerr << "[ERROR] Build event: " << event_result.status().message() << std::endl;
return 1;
}
auto send_status = client->SendEvent(*event_result);
if (!send_status.ok()) {
std::cerr << "[ERROR] SendEvent: " << send_status.message() << std::endl;
return 1;
}
std::cout << "[2] Event sent with tracing enabled" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
auto close_status = client->Close();
if (!close_status.ok()) {
std::cerr << "[ERROR] Close failed: " << close_status.message() << std::endl;
return 1;
}
std::cout << "[3] Client closed" << std::endl;
return 0;
}How It Works
- OpenTelemetry support is opt-in and not yet active in the current release. The SDK ships a no-op stub (
otel.cc) for all tracing and metrics types —OtelSpan,OtelCounter, andOtelHistogramare all empty implementations that compile away.set_tracer_provider()andset_meter_provider()accept a provider pointer but the underlyingInitOtel()is also a no-op until a real OTel build is wired in. - The example runs without a real OTel provider: the
[1]output line acknowledges this explicitly ("using default/no-op"). No spans or metrics are emitted. - The commented-out block shows the intended setup for when the OTel middleware is implemented: configure an
OStreamSpanExporter-backedTracerProviderand callopentelemetry::trace::Provider::SetTracerProvider(provider)before creating the client, then rebuild with-DKUBEMQ_ENABLE_OTEL=ON. - A demo event is sent to
cpp-observability.opentelemetry-setupso the code path is exercised; the one-second sleep is a placeholder for exporter flush time once real tracing is enabled.
Related
Was this page helpful?