package module
Version: v1.16.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: May 22, 2023 License: Apache-2.0 Imports: 16 Imported by: 18


OpenTelemetry/OpenTracing Bridge

Getting started

go get

Assuming you have configured an OpenTelemetry TracerProvider, these will be the steps to follow to wire up the bridge:

import (
	otelBridge ""

func main() {
	/* Create tracerProvider and configure OpenTelemetry ... */
	otelTracer := tracerProvider.Tracer("tracer_name")
	// Use the bridgeTracer as your OpenTracing tracer.
	bridgeTracer, wrapperTracerProvider := otelBridge.NewTracerPair(otelTracer)
	// Set the wrapperTracerProvider as the global OpenTelemetry
	// TracerProvider so instrumentation will use it by default.

	/* ... */

Interop from trace context from OpenTracing to OpenTelemetry

In order to get OpenTracing spans properly into the OpenTelemetry context, so they can be propagated (both internally, and externally), you will need to explicitly use the BridgeTracer for creating your OpenTracing spans, rather than a bare OpenTracing Tracer instance.

When you have started an OpenTracing Span, make sure the OpenTelemetry knows about it like this:

	ctxWithOTSpan := opentracing.ContextWithSpan(ctx, otSpan)
	ctxWithOTAndOTelSpan := bridgeTracer.ContextWithSpanHook(ctxWithOTSpan, otSpan)
	// Propagate the otSpan to both OpenTracing and OpenTelemetry
	// instrumentation by using the ctxWithOTAndOTelSpan context.

Extended Functionality

The bridge functionality can be extended beyond the OpenTracing API.

Any trace.SpanContext method can be accessed as following:

type spanContextProvider interface {
	IsSampled() bool
	TraceID() trace.TraceID
	SpanID() trace.SpanID
	TraceFlags() trace.TraceFlags
	... // any other available method can be added here to access it

var sc opentracing.SpanContext = ...
if s, ok := sc.(spanContextProvider); ok {
	// Use TraceID by s.TraceID()
	// Use SpanID by s.SpanID()
	// Use TraceFlags by s.TraceFlags()



Package opentracing implements a bridge that forwards OpenTracing API calls to the OpenTelemetry SDK.

To use the bridge, first create an OpenTelemetry tracer of choice. Then use the NewTracerPair() function to create two tracers - one implementing OpenTracing API (BridgeTracer) and one that implements the OpenTelemetry API (WrapperTracer) and mostly forwards the calls to the OpenTelemetry tracer of choice, but does some extra steps to make the interaction between both APIs working. If the OpenTelemetry tracer of choice already knows how to cooperate with OpenTracing API through the OpenTracing bridge (explained in detail below), then it is fine to skip the WrapperTracer by calling the NewBridgeTracer() function to get the bridge tracer and then passing the chosen OpenTelemetry tracer to the SetOpenTelemetryTracer() function of the bridge tracer.

To use an OpenTelemetry span as the parent of an OpenTracing span, create a context using the ContextWithBridgeSpan() function of the bridge tracer, and then use the StartSpanFromContext function of the OpenTracing API.

Bridge tracer also allows the user to install a warning handler through the SetWarningHandler() function. The warning handler will be called when there is some misbehavior of the OpenTelemetry tracer with regard to the cooperation with the OpenTracing API.

For an OpenTelemetry tracer to cooperate with OpenTracing API through the BridgeTracer, the OpenTelemetry tracer needs to (reasoning is below the list):

1. Return the same context it received in the Start() function if migration.SkipContextSetup() returns true.

2. Implement the migration.DeferredContextSetupTracerExtension interface. The implementation should setup the context it would normally do in the Start() function if the migration.SkipContextSetup() function returned false. Calling ContextWithBridgeSpan() is not necessary.

3. Have an access to the BridgeTracer instance.

4. If the migration.SkipContextSetup() function returned false, the tracer should use the ContextWithBridgeSpan() function to install the created span as an active OpenTracing span.

There are some differences between OpenTracing and OpenTelemetry APIs, especially with regard to Go context handling. When a span is created with an OpenTracing API (through the StartSpan() function) the Go context is not available. BridgeTracer has access to the OpenTelemetry tracer of choice, so in the StartSpan() function BridgeTracer translates the parameters to the OpenTelemetry version and uses the OpenTelemetry tracer's Start() function to actually create a span. The OpenTelemetry Start() function takes the Go context as a parameter, so BridgeTracer at this point passes a temporary context to Start(). All the changes to the temporary context will be lost at the end of the StartSpan() function, so the OpenTelemetry tracer of choice should not do anything with the context. If the returned context is different, BridgeTracer will warn about it. The OpenTelemetry tracer of choice can learn about this situation by using the migration.SkipContextSetup() function. The tracer will receive an opportunity to set up the context at a later stage. Usually after StartSpan() is finished, users of the OpenTracing API are calling (either directly or through the opentracing.StartSpanFromContext() helper function) the opentracing.ContextWithSpan() function to insert the created OpenTracing span into the context. At that time, the OpenTelemetry tracer of choice has a chance of setting up the context through a hook invoked inside the opentracing.ContextWithSpan() function. For that to happen, the tracer should implement the migration.DeferredContextSetupTracerExtension interface. This so far explains the need for points 1. and 2.

When the span is created with the OpenTelemetry API (with the Start() function) then migration.SkipContextSetup() will return false. This means that the tracer can do the usual setup of the context, but it also should set up the active OpenTracing span in the context. This is because OpenTracing API is not used at all in the creation of the span, but the OpenTracing API may be used during the time when the created OpenTelemetry span is current. For this case to work, we need to also set up active OpenTracing span in the context. This can be done with the ContextWithBridgeSpan() function. This means that the OpenTelemetry tracer of choice needs to have an access to the BridgeTracer instance. This should explain the need for points 3. and 4.

Another difference related to the Go context handling is in logging - OpenTracing API does not take a context parameter in the LogFields() function, so when the call to the function gets translated to OpenTelemetry AddEvent() function, an empty context is passed.



This section is empty.


This section is empty.


func NewTracerPair

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

NewTracerPair is a utility function that creates a BridgeTracer and a WrapperTracerProvider. WrapperTracerProvider creates a single instance of WrapperTracer. The BridgeTracer forwards the calls to the WrapperTracer that wraps the passed tracer. BridgeTracer and WrapperTracerProvider are returned to the caller and the caller is expected to register BridgeTracer with opentracing and WrapperTracerProvider with opentelemetry.

func NewTracerPairWithContext

func NewTracerPairWithContext(ctx context.Context, tracer trace.Tracer) (context.Context, *BridgeTracer, *WrapperTracerProvider)

NewTracerPairWithContext is a convenience function. It calls NewTracerPair and returns a hooked version of ctx with the created BridgeTracer along with the BridgeTracer and WrapperTracerProvider.


type BridgeTracer

type BridgeTracer struct {
	// contains filtered or unexported fields

BridgeTracer is an implementation of the OpenTracing tracer, which translates the calls to the OpenTracing API into OpenTelemetry counterparts and calls the underlying OpenTelemetry tracer.

func NewBridgeTracer

func NewBridgeTracer() *BridgeTracer

NewBridgeTracer creates a new BridgeTracer. The new tracer forwards the calls to the OpenTelemetry Noop tracer, so it should be overridden with the SetOpenTelemetryTracer function. The warnings handler does nothing by default, so to override it use the SetWarningHandler function.

func (*BridgeTracer) ContextWithBridgeSpan

func (t *BridgeTracer) ContextWithBridgeSpan(ctx context.Context, span trace.Span) context.Context

ContextWithBridgeSpan sets up the context with the passed OpenTelemetry span as the active OpenTracing span.

This function should be used by the OpenTelemetry tracers that want to be aware how to operate in the environment using OpenTracing API.

func (*BridgeTracer) ContextWithSpanHook

func (t *BridgeTracer) ContextWithSpanHook(ctx context.Context, span ot.Span) context.Context

ContextWithSpanHook is an implementation of the OpenTracing tracer extension interface. It will call the DeferredContextSetupHook function on the tracer if it implements the DeferredContextSetupTracerExtension interface.

func (*BridgeTracer) Extract

func (t *BridgeTracer) Extract(format interface{}, carrier interface{}) (ot.SpanContext, error)

Extract is a part of the implementation of the OpenTracing Tracer interface.

Currently only the HTTPHeaders and TextMap formats are supported.

func (*BridgeTracer) Inject

func (t *BridgeTracer) Inject(sm ot.SpanContext, format interface{}, carrier interface{}) error

Inject is a part of the implementation of the OpenTracing Tracer interface.

Currently only the HTTPHeaders and TextMap formats are supported.

func (*BridgeTracer) NewHookedContext

func (t *BridgeTracer) NewHookedContext(ctx context.Context) context.Context

NewHookedContext returns a Context that has ctx as its parent and is wrapped to handle baggage set and get operations.

func (*BridgeTracer) SetOpenTelemetryTracer

func (t *BridgeTracer) SetOpenTelemetryTracer(tracer trace.Tracer)

SetOpenTelemetryTracer overrides the underlying OpenTelemetry tracer. The passed tracer should know how to operate in the environment that uses OpenTracing API.

func (*BridgeTracer) SetTextMapPropagator added in v0.13.0

func (t *BridgeTracer) SetTextMapPropagator(propagator propagation.TextMapPropagator)

SetTextMapPropagator sets propagator as the TextMapPropagator to use by the BridgeTracer.

func (*BridgeTracer) SetWarningHandler

func (t *BridgeTracer) SetWarningHandler(handler BridgeWarningHandler)

SetWarningHandler overrides the warning handler.

func (*BridgeTracer) StartSpan

func (t *BridgeTracer) StartSpan(operationName string, opts ...ot.StartSpanOption) ot.Span

StartSpan is a part of the implementation of the OpenTracing Tracer interface.

type BridgeWarningHandler

type BridgeWarningHandler func(msg string)

BridgeWarningHandler is a type of handler that receives warnings from the BridgeTracer.

type TracerProvider added in v1.12.0

type TracerProvider struct {
	// contains filtered or unexported fields

TracerProvider is an OpenTelemetry TracerProvider that wraps an OpenTracing Tracer.

func NewTracerProvider added in v1.12.0

func NewTracerProvider(bridge *BridgeTracer, provider trace.TracerProvider) *TracerProvider

NewTracerProvider returns a new TracerProvider that creates new instances of WrapperTracer from the given TracerProvider.

func (*TracerProvider) Tracer added in v1.12.0

func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer

Tracer creates a WrappedTracer that wraps the OpenTelemetry tracer for each call to Tracer(). Repeated calls to Tracer() with the same configuration will look up and return an existing instance of WrapperTracer.

type WrapperTracer

type WrapperTracer struct {
	// contains filtered or unexported fields

WrapperTracer is a wrapper around an OpenTelemetry tracer. It mostly forwards the calls to the wrapped tracer, but also does some extra steps like setting up a context with the active OpenTracing span.

It does not need to be used when the OpenTelemetry tracer is also aware how to operate in environment where OpenTracing API is also used.

func NewWrapperTracer

func NewWrapperTracer(bridge *BridgeTracer, tracer trace.Tracer) *WrapperTracer

NewWrapperTracer wraps the passed tracer and also talks to the passed bridge tracer when setting up the context with the new active OpenTracing span.

func (*WrapperTracer) DeferredContextSetupHook

func (t *WrapperTracer) DeferredContextSetupHook(ctx context.Context, span trace.Span) context.Context

DeferredContextSetupHook is a part of the implementation of the DeferredContextSetupTracerExtension interface. It will try to forward the call to the wrapped tracer if it implements the interface.

func (*WrapperTracer) Start

Start forwards the call to the wrapped tracer. It also tries to override the tracer of the returned span if the span implements the OverrideTracerSpanExtension interface.

type WrapperTracerProvider deprecated added in v0.12.0

type WrapperTracerProvider struct {
	// contains filtered or unexported fields

WrapperTracerProvider is an OpenTelemetry TracerProvider that wraps an OpenTracing Tracer, created by the deprecated NewWrappedTracerProvider.

Deprecated: Use the TracerProvider from NewTracerProvider(...) instead.

func NewWrappedTracerProvider deprecated added in v0.12.0

func NewWrappedTracerProvider(bridge *BridgeTracer, tracer trace.Tracer) *WrapperTracerProvider

NewWrappedTracerProvider creates a new trace provider that creates a single instance of WrapperTracer that wraps OpenTelemetry tracer, and always returns it unmodified from Tracer().

Deprecated: Use NewTracerProvider(...) instead.

func (*WrapperTracerProvider) Tracer added in v0.12.0

Tracer returns the WrapperTracer associated with the WrapperTracerProvider.


Path Synopsis
Package migration provides interfaces and functions that are useful for providing a cooperation of the OpenTelemetry tracers with the OpenTracing API.
Package migration provides interfaces and functions that are useful for providing a cooperation of the OpenTelemetry tracers with the OpenTracing API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL