Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

RFC: Add an extension to Tracer interface for custom go context creation #220

Merged
merged 3 commits into from Sep 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions ext.go
@@ -0,0 +1,24 @@
package opentracing

import (
"context"
)

// TracerContextWithSpanExtension is an extension interface that the
// implementation of the Tracer interface may want to implement. It
// allows to have some control over the go context when the
// ContextWithSpan is invoked.
//
// The primary purpose of this extension are adapters from opentracing
// API to some other tracing API.
type TracerContextWithSpanExtension interface {
// ContextWithSpanHook gets called by the ContextWithSpan
// function, when the Tracer implementation also implements
// this interface. It allows to put extra information into the
// context and make it available to the callers of the
// ContextWithSpan.
//
// This hook is invoked before the ContextWithSpan function
// actually puts the span into the context.
ContextWithSpanHook(ctx context.Context, span Span) context.Context
}
3 changes: 3 additions & 0 deletions gocontext.go
Expand Up @@ -9,6 +9,9 @@ var activeSpanKey = contextKey{}
// ContextWithSpan returns a new `context.Context` that holds a reference to
// `span`'s SpanContext.
func ContextWithSpan(ctx context.Context, span Span) context.Context {
if tracerWithHook, ok := span.Tracer().(TracerContextWithSpanExtension); ok {
ctx = tracerWithHook.ContextWithSpanHook(ctx, span)
}
return context.WithValue(ctx, activeSpanKey, span)
}

Expand Down
35 changes: 35 additions & 0 deletions gocontext_test.go
Expand Up @@ -29,6 +29,41 @@ func TestContextWithSpan(t *testing.T) {
}
}

type noopExtTracer struct {
NoopTracer
}

type noopExtTracerCtxType struct{}

func (noopExtTracer) ContextWithSpanHook(ctx context.Context, span Span) context.Context {
return context.WithValue(ctx, noopExtTracerCtxType{}, noopExtTracerCtxType{})
}

var _ Tracer = noopExtTracer{}
var _ TracerContextWithSpanExtension = noopExtTracer{}

type noopExtSpan struct {
noopSpan
}

func (noopExtSpan) Tracer() Tracer {
return noopExtTracer{}
}

var _ Span = noopExtSpan{}

func TestContextWithSpanWithExtension(t *testing.T) {
span := &noopExtSpan{}
ctx := ContextWithSpan(context.Background(), span)
span2 := SpanFromContext(ctx)
if span != span2 {
t.Errorf("Not the same span returned from context, expected=%+v, actual=%+v", span, span2)
}
if _, ok := ctx.Value(noopExtTracerCtxType{}).(noopExtTracerCtxType); !ok {
t.Error("ContextWithSpanHook was not called")
}
}

func TestStartSpanFromContext(t *testing.T) {
testTracer := testTracer{}

Expand Down