KubeMQ
Client SDKsGoHow-to guidesObservability

OpenTelemetry Setup

Configure OpenTelemetry tracing and metrics for the KubeMQ Go SDK to observe messaging in production.

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 metrics broken out by channel and operation. Instrumenting that by hand around every SendEvent or Subscribe call is tedious and easy to get inconsistent; letting the client do it guarantees uniform coverage.

kubemq.WithTracerProvider(tp) and kubemq.WithMeterProvider(mp) inject standard OpenTelemetry providers into the client at construction time. Once set, every subsequent operation on that client automatically emits spans and records metrics — you write no tracing code in your business logic. kubemq.WithCardinalityThreshold(...) bounds the number of unique label combinations tracked, which matters once channel or client-ID names become dynamic. Gotchas: instrumentation is inert until you attach a real exporter (OTLP, Jaeger) to the provider — the providers shown here export nowhere by default; forgetting to shut down the provider on exit drops the last in-flight batch of spans and metrics; and high channel cardinality without a threshold can quietly blow up your metrics backend's storage.

Prerequisites

  • KubeMQ server running on localhost:50000
  • Go SDK installed (go get github.com/kubemq-io/kubemq-go/v2)

Code

main.go
// Example: observability/opentelemetry-setup
//
// Demonstrates setting up OpenTelemetry tracing and metrics with
// the KubeMQ Go SDK. The SDK integrates with OTel via TracerProvider
// and MeterProvider options.
//
// This example uses the OTel SDK providers available in the module.
// In production, you would configure exporters (e.g., OTLP, Jaeger)
// to send telemetry data to your observability backend.
//
// Channel: go-observability.opentelemetry-setup
// Client ID: go-observability-opentelemetry-setup-client
//
// Run with a KubeMQ server on localhost:50000
// (see https://docs.kubemq.io/deploy).
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"go.opentelemetry.io/otel"
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"

	"github.com/kubemq-io/kubemq-go/v2"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// Create a TracerProvider. In production, add a real exporter
	// (e.g., sdktrace.WithBatcher(otlpExporter)).
	tp := sdktrace.NewTracerProvider()
	defer func() {
		if err := tp.Shutdown(ctx); err != nil {
			log.Printf("TracerProvider shutdown: %v", err)
		}
	}()
	otel.SetTracerProvider(tp)

	// Create a MeterProvider for metrics instrumentation.
	mp := sdkmetric.NewMeterProvider()
	defer func() {
		if err := mp.Shutdown(ctx); err != nil {
			log.Printf("MeterProvider shutdown: %v", err)
		}
	}()

	// Create a KubeMQ client with OTel providers.
	// The SDK automatically instruments all operations with traces and metrics.
	client, err := kubemq.NewClient(ctx,
		kubemq.WithAddress("localhost", 50000),
		kubemq.WithClientId("go-observability-opentelemetry-setup-client"),
		// Pass the OTel providers to the SDK.
		kubemq.WithTracerProvider(tp),
		kubemq.WithMeterProvider(mp),
		// Optional: control metric cardinality for high-throughput scenarios.
		kubemq.WithCardinalityThreshold(100),
	)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	defer client.Close()

	channel := "go-observability.opentelemetry-setup"

	// Send an event — this operation will be traced and metered by the SDK.
	err = client.SendEvent(ctx, kubemq.NewEvent().
		SetChannel(channel).
		SetBody([]byte("instrumented event")).
		SetMetadata("otel-demo"))
	if err != nil {
		log.Printf("SendEvent: %v", err)
	} else {
		fmt.Println("Event sent with OpenTelemetry instrumentation")
	}

	fmt.Println("OpenTelemetry setup demo complete")
	fmt.Println("In production, traces and metrics would be exported to your backend")
}

How It Works

  1. A sdktrace.TracerProvider and sdkmetric.MeterProvider are created from the standard OTel Go SDK (no exporters configured here — add a real OTLP or Jaeger exporter in production).
  2. kubemq.WithTracerProvider(tp) and kubemq.WithMeterProvider(mp) inject both providers into the SDK; all subsequent operations on that client are automatically traced and metered.
  3. kubemq.WithCardinalityThreshold(100) caps the number of unique label combinations tracked for metrics, preventing cardinality explosions in high-throughput scenarios.
  4. Each defer tp.Shutdown(ctx) / mp.Shutdown(ctx) flushes buffered telemetry before the process exits; omitting this call drops the last batch of spans and metrics.

Was this page helpful?

On this page