or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

attributes.mdbridges.mdcontext-propagation.mdexporters-other.mdexporters-otlp.mdindex.mdlogging.mdmetrics.mdsdk-log.mdsdk-metric.mdsdk-resource.mdsdk-trace.mdsemantic-conventions.mdtracing.md
tile.json

bridges.mddocs/

OpenCensus and OpenTracing Bridges

OpenTelemetry provides bridges to help migrate from OpenCensus and OpenTracing to OpenTelemetry.

Overview

Bridges allow gradual migration:

  1. OpenCensus Bridge: Use OpenCensus instrumentation with OpenTelemetry
  2. OpenTracing Bridge: Use OpenTracing instrumentation with OpenTelemetry

OpenCensus Bridge

Migrate from OpenCensus to OpenTelemetry while maintaining existing OpenCensus instrumentation.

Package: go.opentelemetry.io/otel/bridge/opencensus

Installation

go get go.opentelemetry.io/otel/bridge/opencensus@v1.38.0

Basic Usage

package main

import (
	"context"
	"log"

	"go.opencensus.io/trace"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/bridge/opencensus"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	ctx := context.Background()

	// Setup OpenTelemetry
	exporter, err := otlptracehttp.New(ctx)
	if err != nil {
		log.Fatal(err)
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tp)

	// Install OpenCensus bridge
	opencensus.InstallTraceBridge(opencensus.WithTracerProvider(tp))

	// Now OpenCensus instrumentation will send data to OpenTelemetry
	ctx, span := trace.StartSpan(ctx, "opencensus-operation")
	defer span.End()

	// Your code using OpenCensus
}

InstallTraceBridge

Installs the OpenCensus trace bridge, which overwrites the global OpenCensus tracer implementation.

func InstallTraceBridge(opts ...TraceOption)

TraceOption

func WithTracerProvider(tp trace.TracerProvider) TraceOption

Conversion Functions

Convert between OpenCensus and OpenTelemetry span contexts.

func OTelSpanContextToOC(sc trace.SpanContext) octrace.SpanContext
func OCSpanContextToOTel(sc octrace.SpanContext) trace.SpanContext

Migration Strategy

Phase 1: Bridge Installation

// Install bridge
opencensus.InstallTraceBridge(opencensus.WithTracerProvider(tp))

// Existing OpenCensus code works unchanged
ctx, span := trace.StartSpan(ctx, "operation")
defer span.End()

Phase 2: Gradual Migration

// New code uses OpenTelemetry directly
import (
	otelTrace "go.opentelemetry.io/otel/trace"
)

// New code
tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "new-operation")
defer span.End()

// Old code still uses OpenCensus (via bridge)
ctx, ocSpan := trace.StartSpan(ctx, "legacy-operation")
defer ocSpan.End()

Phase 3: Complete Migration

// Remove OpenCensus dependency
// All code uses OpenTelemetry
tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "operation")
defer span.End()

OpenTracing Bridge

Use OpenTracing instrumentation with OpenTelemetry.

Package: go.opentelemetry.io/otel/bridge/opentracing

Installation

go get go.opentelemetry.io/otel/bridge/opentracing@v1.38.0

Basic Usage

package main

import (
	"context"
	"log"

	"github.com/opentracing/opentracing-go"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/bridge/opentracing"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	ctx := context.Background()

	// Setup OpenTelemetry
	exporter, err := otlptracehttp.New(ctx)
	if err != nil {
		log.Fatal(err)
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tp)

	// Create OpenTracing bridge
	bridgeTracer, wrapperTracerProvider := opentracing.NewTracerPair(tp.Tracer("opentracing-bridge"))
	opentracing.SetGlobalTracer(bridgeTracer)

	defer wrapperTracerProvider.Shutdown(ctx)

	// Now OpenTracing instrumentation will send data to OpenTelemetry
	span := opentracing.GlobalTracer().StartSpan("opentracing-operation")
	defer span.Finish()

	// Your code using OpenTracing
}

NewTracerPair

Creates an OpenTracing-compatible tracer and TracerProvider.

func NewTracerPair(tracer trace.Tracer) (*BridgeTracer, *WrapperTracerProvider)

Migration Strategy

Phase 1: Bridge Installation

// Install bridge
bridgeTracer, wrapperTP := opentracing.NewTracerPair(tp.Tracer("opentracing-bridge"))
opentracing.SetGlobalTracer(bridgeTracer)

// Existing OpenTracing code works unchanged
span := opentracing.GlobalTracer().StartSpan("operation")
defer span.Finish()

Phase 2: Gradual Migration

// New code uses OpenTelemetry directly
tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "new-operation")
defer span.End()

// Old code still uses OpenTracing (via bridge)
otSpan := opentracing.GlobalTracer().StartSpan("legacy-operation")
defer otSpan.Finish()

Phase 3: Complete Migration

// Remove OpenTracing dependency
// All code uses OpenTelemetry
tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "operation")
defer span.End()

Complete Migration Example

Mixed Instrumentation

package main

import (
	"context"
	"log"

	"github.com/opentracing/opentracing-go"
	ocTrace "go.opencensus.io/trace"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/bridge/opencensus"
	"go.opentelemetry.io/otel/bridge/opentracing"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	ctx := context.Background()

	// Setup OpenTelemetry
	exporter, err := otlptracehttp.New(ctx)
	if err != nil {
		log.Fatal(err)
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tp)

	// Install OpenCensus bridge
	ocTracer := opencensus.NewTracer(tp.Tracer("opencensus-bridge"))
	ocTrace.DefaultTracer = ocTracer

	// Install OpenTracing bridge
	otBridge, otWrapper := opentracing.NewTracerPair(tp.Tracer("opentracing-bridge"))
	opentracing.SetGlobalTracer(otBridge)

	defer func() {
		otWrapper.Shutdown(ctx)
		tp.Shutdown(ctx)
	}()

	// All three tracing systems work together
	useOpenTelemetry(ctx)
	useOpenCensus(ctx)
	useOpenTracing()
}

func useOpenTelemetry(ctx context.Context) {
	tracer := otel.Tracer("my-service")
	ctx, span := tracer.Start(ctx, "otel-operation")
	defer span.End()

	// OpenTelemetry code
}

func useOpenCensus(ctx context.Context) {
	ctx, span := ocTrace.StartSpan(ctx, "opencensus-operation")
	defer span.End()

	// OpenCensus code
}

func useOpenTracing() {
	span := opentracing.GlobalTracer().StartSpan("opentracing-operation")
	defer span.Finish()

	// OpenTracing code
}

Migration Guidance

OpenCensus to OpenTelemetry

Trace API Changes

OpenCensusOpenTelemetry
trace.StartSpan(ctx, "name")tracer.Start(ctx, "name")
span.End()span.End()
span.AddAttributes()span.SetAttributes()
span.Annotate()span.AddEvent()
span.SetStatus()span.SetStatus()

Example Migration

Before (OpenCensus):

import "go.opencensus.io/trace"

ctx, span := trace.StartSpan(ctx, "operation")
defer span.End()

span.AddAttributes(
	trace.StringAttribute("key", "value"),
)
span.Annotate([]trace.Attribute{}, "event")

After (OpenTelemetry):

import (
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
)

tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "operation")
defer span.End()

span.SetAttributes(
	attribute.String("key", "value"),
)
span.AddEvent("event")

OpenTracing to OpenTelemetry

Trace API Changes

OpenTracingOpenTelemetry
tracer.StartSpan("name")tracer.Start(ctx, "name")
span.Finish()span.End()
span.SetTag()span.SetAttributes()
span.LogFields()span.AddEvent()
span.Context()span.SpanContext()

Example Migration

Before (OpenTracing):

import (
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

span := opentracing.StartSpan("operation")
defer span.Finish()

span.SetTag("key", "value")
span.LogFields(
	log.String("event", "something happened"),
)

After (OpenTelemetry):

import (
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
)

tracer := otel.Tracer("my-service")
ctx, span := tracer.Start(ctx, "operation")
defer span.End()

span.SetAttributes(
	attribute.String("key", "value"),
)
span.AddEvent("something happened")

Best Practices

1. Use Bridges for Gradual Migration

// Good: Use bridge during migration period
bridgeTracer, _ := opentracing.NewTracerPair(tp.Tracer("bridge"))
opentracing.SetGlobalTracer(bridgeTracer)

// Bad: Try to do full migration at once (risky)

2. Migrate New Code First

// New features use OpenTelemetry directly
func newFeature(ctx context.Context) {
	tracer := otel.Tracer("my-service")
	ctx, span := tracer.Start(ctx, "new-feature")
	defer span.End()
}

// Legacy code continues using bridge

3. Test Thoroughly

// Ensure both old and new instrumentation work together
func testMixedInstrumentation(t *testing.T) {
	// Test OpenTelemetry
	// Test bridged OpenCensus/OpenTracing
	// Test interaction between them
}

4. Remove Bridges After Migration

// After migration is complete, remove bridge code
// and uninstall OpenCensus/OpenTracing dependencies

Related Documentation

  • SDK Trace: OpenTelemetry trace implementation
  • Tracing API: Core tracing API
  • OTLP Exporters: Exporting trace data