From b499dbdcdd316afdc6a7fc3dfc466b90f3f04997 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Mon, 9 Sep 2019 19:19:21 +0200 Subject: [PATCH] add some migration api and use it --- .../bridge/opentracing/internal/mock.go | 13 +++++++++++-- experimental/bridge/opentracing/lib.go | 18 +++++++++++++++++- .../bridge/opentracing/migration/api.go | 11 +++++++++++ .../bridge/opentracing/migration/defer.go | 16 ++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 experimental/bridge/opentracing/migration/api.go create mode 100644 experimental/bridge/opentracing/migration/defer.go diff --git a/experimental/bridge/opentracing/internal/mock.go b/experimental/bridge/opentracing/internal/mock.go index 8b08c6c74f25..5ee6c69d2333 100644 --- a/experimental/bridge/opentracing/internal/mock.go +++ b/experimental/bridge/opentracing/internal/mock.go @@ -12,6 +12,8 @@ import ( otelkey "go.opentelemetry.io/api/key" oteltag "go.opentelemetry.io/api/tag" oteltrace "go.opentelemetry.io/api/trace" + + migration "go.opentelemetry.io/experimental/bridge/opentracing/migration" ) var ( @@ -38,6 +40,9 @@ type MockTracer struct { rand *rand.Rand } +var _ oteltrace.Tracer = &MockTracer{} +var _ migration.DeferredContextSetupExtension = &MockTracer{} + func NewMockTracer() *MockTracer { return &MockTracer{ Resources: oteltag.NewEmptyMap(), @@ -94,7 +99,9 @@ func (t *MockTracer) Start(ctx context.Context, name string, opts ...oteltrace.S Events: nil, } ctx = oteltrace.SetCurrentSpan(ctx, span) - ctx = t.addSpareContextValue(ctx) + if !migration.SkipContextSetup(ctx) { + ctx = t.addSpareContextValue(ctx) + } return ctx, span } @@ -186,7 +193,9 @@ func (t *MockTracer) Inject(ctx context.Context, span oteltrace.Span, injector o })) } -var _ oteltrace.Tracer = &MockTracer{} +func (t *MockTracer) DeferredContextSetupHook(ctx context.Context, span oteltrace.Span) context.Context { + return t.addSpareContextValue(ctx) +} type MockEvent struct { CtxAttributes oteltag.Map diff --git a/experimental/bridge/opentracing/lib.go b/experimental/bridge/opentracing/lib.go index 44440b976863..f7306fea331f 100644 --- a/experimental/bridge/opentracing/lib.go +++ b/experimental/bridge/opentracing/lib.go @@ -18,9 +18,11 @@ import ( "context" "fmt" "net/http" + "os" "reflect" "strconv" "strings" + "sync" "google.golang.org/grpc/codes" @@ -31,6 +33,8 @@ import ( otelcore "go.opentelemetry.io/api/core" otelregistry "go.opentelemetry.io/api/registry" oteltrace "go.opentelemetry.io/api/trace" + + migration "go.opentelemetry.io/experimental/bridge/opentracing/migration" ) type bridgeSpanContext struct { @@ -233,6 +237,8 @@ func (s *bridgeSpan) Log(data ot.LogData) { type BridgeTracer struct { otelTracer oteltrace.Tracer + + warnOnce sync.Once } var _ ot.Tracer = &BridgeTracer{} @@ -253,12 +259,19 @@ func (t *BridgeTracer) StartSpan(operationName string, opts ...ot.StartSpanOptio bReference, _ := otSpanReferencesToBridgeReferenceAndLinks(sso.References) // TODO: handle span kind, needs SpanData to be in the API first? attributes, _, hadTrueErrorTag := otTagsToOtelAttributesKindAndError(sso.Tags) - _, otelSpan := t.otelTracer.Start(context.Background(), operationName, func(opts *oteltrace.SpanOptions) { + checkCtx := migration.WithDeferredSetup(context.Background()) + checkCtx2, otelSpan := t.otelTracer.Start(checkCtx, operationName, func(opts *oteltrace.SpanOptions) { opts.Attributes = attributes opts.StartTime = sso.StartTime opts.Reference = bReference.ToOtelReference() opts.RecordEvent = true }) + if checkCtx != checkCtx2 { + t.warnOnce.Do(func() { + // TODO: what to use for logging? + fmt.Fprintf(os.Stderr, "SDK should have deferred the context setup, see the documentation of go.opentelemetry.io/experimental/bridge/opentracing/migration\n") + }) + } if hadTrueErrorTag { otelSpan.SetStatus(codes.Unknown) } @@ -282,6 +295,9 @@ func (t *BridgeTracer) StartSpan(operationName string, opts ...ot.StartSpanOptio func (t *BridgeTracer) ContextWithSpanHook(ctx context.Context, span ot.Span) context.Context { if bSpan, ok := span.(*bridgeSpan); ok { + if tracerWithExtension, ok := bSpan.tracer.otelTracer.(migration.DeferredContextSetupExtension); ok { + ctx = tracerWithExtension.DeferredContextSetupHook(ctx, bSpan.otelSpan) + } ctx = oteltrace.SetCurrentSpan(ctx, bSpan.otelSpan) } return ctx diff --git a/experimental/bridge/opentracing/migration/api.go b/experimental/bridge/opentracing/migration/api.go new file mode 100644 index 000000000000..31d64031112c --- /dev/null +++ b/experimental/bridge/opentracing/migration/api.go @@ -0,0 +1,11 @@ +package migration // import "go.opentelemetry.io/experimental/bridge/opentracing/migration" + +import ( + "context" + + oteltrace "go.opentelemetry.io/api/trace" +) + +type DeferredContextSetupExtension interface { + DeferredContextSetupHook(ctx context.Context, span oteltrace.Span) context.Context +} diff --git a/experimental/bridge/opentracing/migration/defer.go b/experimental/bridge/opentracing/migration/defer.go new file mode 100644 index 000000000000..b2538452e5b7 --- /dev/null +++ b/experimental/bridge/opentracing/migration/defer.go @@ -0,0 +1,16 @@ +package migration + +import ( + "context" +) + +type doDeferredContextSetupType struct{} + +func WithDeferredSetup(ctx context.Context) context.Context { + return context.WithValue(ctx, doDeferredContextSetupType{}, doDeferredContextSetupType{}) +} + +func SkipContextSetup(ctx context.Context) bool { + _, ok := ctx.Value(doDeferredContextSetupType{}).(doDeferredContextSetupType) + return ok +}