diff --git a/go.mod b/go.mod index b762cd6..6211712 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,5 @@ toolchain go1.22.2 require ( github.com/opentracing/opentracing-go v1.2.0 go.opentelemetry.io/otel v1.26.0 - go.unistack.org/micro/v3 v3.10.73 + go.unistack.org/micro/v3 v3.10.77 ) diff --git a/go.sum b/go.sum index 89d5e2f..e9dbe68 100644 --- a/go.sum +++ b/go.sum @@ -13,7 +13,7 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.unistack.org/micro/v3 v3.10.73 h1:C8z8SBGDWWB0lemExr/P6WAbMFD4L1w6rpf61OU/RmY= -go.unistack.org/micro/v3 v3.10.73/go.mod h1:erMgt3Bl7vQQ0e9UpQyR5NlLiZ9pKeEJ9+1tfYFaqUg= +go.unistack.org/micro/v3 v3.10.77 h1:nn731y84q3S8a4UgpVdC/wN9cs30ruZeH81rKw6XcUc= +go.unistack.org/micro/v3 v3.10.77/go.mod h1:erMgt3Bl7vQQ0e9UpQyR5NlLiZ9pKeEJ9+1tfYFaqUg= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/opentracing.go b/opentracing.go index d73f2e1..1f3454d 100644 --- a/opentracing.go +++ b/opentracing.go @@ -49,6 +49,9 @@ type spanContext interface { func (t *otTracer) Start(ctx context.Context, name string, opts ...tracer.SpanOption) (context.Context, tracer.Span) { options := tracer.NewSpanOptions(opts...) + if len(options.Labels)%2 != 0 { + options.Labels = options.Labels[:len(options.Labels)-1] + } var span ot.Span switch options.Kind { case tracer.SpanKindUnspecified: @@ -95,6 +98,7 @@ type otSpan struct { status tracer.SpanStatus statusMsg string labels []interface{} + finished bool } func (os *otSpan) TraceID() string { @@ -119,7 +123,16 @@ func (os *otSpan) Tracer() tracer.Tracer { } func (os *otSpan) Finish(opts ...tracer.SpanOption) { + if os.finished { + return + } + options := os.opts + + options.Status = os.status + options.StatusMsg = os.statusMsg + options.Labels = append(options.Labels, os.labels...) + for _, o := range opts { o(&options) } @@ -128,26 +141,32 @@ func (os *otSpan) Finish(opts ...tracer.SpanOption) { return } - labels := append(options.Labels, os.labels...) - l := len(labels) + if len(options.Labels)%2 != 0 { + options.Labels = options.Labels[:len(options.Labels)-1] + } + + l := len(options.Labels) for idx := 0; idx < l; idx++ { - switch lt := labels[idx].(type) { + switch lt := options.Labels[idx].(type) { case attribute.KeyValue: os.span.SetTag(string(lt.Key), lt.Value.AsInterface()) case string: if l > idx+1 { - os.span.SetTag(lt, labels[idx+1]) + os.span.SetTag(lt, options.Labels[idx+1]) idx++ } } } - if os.status == tracer.SpanStatusError { + if options.Status == tracer.SpanStatusError { os.span.SetTag("error", true) - os.span.LogKV("error", os.statusMsg) + os.span.LogKV("error", options.StatusMsg) } + os.span.SetTag("span.kind", options.Kind) os.span.Finish() + + os.finished = true } func (os *otSpan) AddEvent(name string, opts ...tracer.EventOption) { diff --git a/opentracing_test.go b/opentracing_test.go index 7812e1a..4f8545f 100644 --- a/opentracing_test.go +++ b/opentracing_test.go @@ -2,6 +2,7 @@ package opentracing import ( "context" + "fmt" "testing" "github.com/opentracing/opentracing-go/mocktracer" @@ -46,8 +47,15 @@ func TestTraceTags(t *testing.T) { var sp tracer.Span ctx, sp = tr.Start(ctx, "test", tracer.WithSpanLabels("key", "val", "odd")) - sp.Finish() - + sp.Finish(tracer.WithSpanLabels("xkey", "xval")) + _ = ctx msp := mtr.FinishedSpans()[0] - t.Logf("mock span %#+v", msp.Tags()) + + if "val" != fmt.Sprintf("%v", msp.Tags()["key"]) { + t.Fatal("mock span invalid") + } + + if "xval" != fmt.Sprintf("%v", msp.Tags()["xkey"]) { + t.Fatalf("mock span invalid %#+v", msp) + } }