diff --git a/go.mod b/go.mod index bd9bfc3..21ca5e8 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/opentracing/opentracing-go v1.2.0 - go.unistack.org/micro/v3 v3.10.28 + go.unistack.org/micro/v3 v3.10.43 ) require github.com/stretchr/testify v1.8.1 // indirect diff --git a/go.sum b/go.sum index 0ace5fb..ae23ffc 100644 --- a/go.sum +++ b/go.sum @@ -13,10 +13,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -go.unistack.org/micro/v3 v3.10.27 h1:jluDdhkG9P/nchaNlhLkBmGxUASkV/L+/fuWG5RX1tY= -go.unistack.org/micro/v3 v3.10.27/go.mod h1:ALkeXpqChYDjx8KPi7tz9mmIyOnob6nlNswsg8BnZjQ= -go.unistack.org/micro/v3 v3.10.28 h1:/87lGekrmi0/66pioy+Nh8lVUBBYnVqKoHiNYX5OmMI= -go.unistack.org/micro/v3 v3.10.28/go.mod h1:eUgtvbtiiz6te93m0ZdmoecbitWwjdBmmr84srmEIKA= +go.unistack.org/micro/v3 v3.10.43 h1:GjUgu1lSKrhIov67jZQg6hUVUw0xZ6+ub8s6JRu6uj4= +go.unistack.org/micro/v3 v3.10.43/go.mod h1:CSmEf5ddmft94MyKHnUSMM0W5dpmmTVbgImbgQWV5Ak= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/opentracing.go b/opentracing.go index e1a1ef8..817695d 100644 --- a/opentracing.go +++ b/opentracing.go @@ -9,6 +9,7 @@ import ( otlog "github.com/opentracing/opentracing-go/log" "go.unistack.org/micro/v3/metadata" "go.unistack.org/micro/v3/tracer" + rutil "go.unistack.org/micro/v3/util/reflect" ) var _ tracer.Tracer = &otTracer{} @@ -40,6 +41,11 @@ func (t *otTracer) Init(opts ...tracer.Option) error { return nil } +type spanContext interface { + TraceID() idStringer + SpanID() idStringer +} + func (t *otTracer) Start(ctx context.Context, name string, opts ...tracer.SpanOption) (context.Context, tracer.Span) { options := tracer.NewSpanOptions(opts...) var span ot.Span @@ -53,17 +59,50 @@ func (t *otTracer) Start(ctx context.Context, name string, opts ...tracer.SpanOp case tracer.SpanKindServer, tracer.SpanKindConsumer: ctx, span = t.startSpanFromIncomingContext(ctx, name) } + sp := &otSpan{span: span, opts: options} + + spctx := span.Context() + if v, ok := spctx.(spanContext); ok { + sp.traceID = v.TraceID().String() + sp.spanID = v.SpanID().String() + } else { + if val, err := rutil.StructFieldByName(spctx, "TraceID"); err == nil { + sp.traceID = fmt.Sprintf("%v", val) + } + if val, err := rutil.StructFieldByName(spctx, "SpanID"); err == nil { + sp.spanID = fmt.Sprintf("%v", val) + } + } + return tracer.NewSpanContext(ctx, sp), sp } +type idStringer struct { + s string +} + +func (s idStringer) String() string { + return s.s +} + type otSpan struct { span ot.Span + spanID string + traceID string opts tracer.SpanOptions status tracer.SpanStatus statusMsg string } +func (os *otSpan) TraceID() string { + return os.traceID +} + +func (os *otSpan) SpanID() string { + return os.spanID +} + func (os *otSpan) SetStatus(st tracer.SpanStatus, msg string) { os.status = st os.statusMsg = msg @@ -140,10 +179,6 @@ func NewTracer(opts ...tracer.Option) *otTracer { return &otTracer{opts: options} } -func spanFromContext(ctx context.Context) ot.Span { - return ot.SpanFromContext(ctx) -} - func (t *otTracer) startSpanFromAny(ctx context.Context, name string, opts ...ot.StartSpanOption) (context.Context, ot.Span) { if tracerSpan, ok := tracer.SpanFromContext(ctx); ok && tracerSpan != nil { return t.startSpanFromContext(ctx, name, opts...) diff --git a/opentracing_test.go b/opentracing_test.go index f6c0104..a56a2a8 100644 --- a/opentracing_test.go +++ b/opentracing_test.go @@ -2,49 +2,31 @@ package opentracing import ( "context" - "sync" "testing" - "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/mocktracer" "go.unistack.org/micro/v3/metadata" + "go.unistack.org/micro/v3/tracer" ) -func TestStartSpanFromIncomingContext(t *testing.T) { - md := metadata.New(2) - md.Set("key", "val") - - var g sync.WaitGroup - +func TestTraceID(t *testing.T) { + md := metadata.New(1) ctx, cancel := context.WithCancel(context.Background()) defer cancel() ctx = metadata.NewIncomingContext(ctx, md) - tracer := opentracing.GlobalTracer() - - g.Add(8000) - cherr := make(chan error) - for i := 0; i < 8000; i++ { - go func() { - defer g.Done() - _, sp, err := startSpanFromIncomingContext(ctx, tracer, "test") - if err != nil { - cherr <- err - } - sp.Finish() - }() + tr := NewTracer(Tracer(mocktracer.New())) + if err := tr.Init(); err != nil { + t.Fatal(err) } - for { - select { - default: - g.Wait() - close(cherr) - case err, ok := <-cherr: - if err != nil { - t.Fatal(err) - } else if !ok { - return - } - } + var sp tracer.Span + + ctx, sp = tr.Start(ctx, "test") + if v := sp.TraceID(); v != "43" { + t.Fatalf("invalid span trace id %#+v", v) + } + if v := sp.SpanID(); v != "44" { + t.Fatalf("invalid span span id %#+v", v) } }