tracer: improve tracing wrapper #240
@@ -2,11 +2,9 @@ package tracer
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"reflect"
 | 
			
		||||
 | 
			
		||||
	"go.unistack.org/micro/v4/logger"
 | 
			
		||||
	"go.unistack.org/micro/v4/options"
 | 
			
		||||
	rutil "go.unistack.org/micro/v4/util/reflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type SpanStatus int
 | 
			
		||||
@@ -95,41 +93,12 @@ type EventOptions struct {
 | 
			
		||||
	Labels []interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func WithSpanLabels(ls ...interface{}) options.Option {
 | 
			
		||||
	return func(src interface{}) error {
 | 
			
		||||
		v, err := options.Get(src, ".Labels")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		} else if rutil.IsZero(v) {
 | 
			
		||||
			v = reflect.MakeSlice(reflect.TypeOf(v), 0, len(ls)).Interface()
 | 
			
		||||
		}
 | 
			
		||||
		cv := reflect.ValueOf(v)
 | 
			
		||||
		for _, l := range ls {
 | 
			
		||||
			reflect.Append(cv, reflect.ValueOf(l))
 | 
			
		||||
		}
 | 
			
		||||
		err = options.Set(src, cv, ".Labels")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
func WithEventLabels(labels ...interface{}) options.Option {
 | 
			
		||||
	return options.Labels(labels...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EventOption func signature
 | 
			
		||||
type EventOption func(o *EventOptions)
 | 
			
		||||
 | 
			
		||||
func WithEventLabels(ls ...interface{}) options.Option {
 | 
			
		||||
	return func(src interface{}) error {
 | 
			
		||||
		v, err := options.Get(src, ".Labels")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		} else if rutil.IsZero(v) {
 | 
			
		||||
			v = reflect.MakeSlice(reflect.TypeOf(v), 0, len(ls)).Interface()
 | 
			
		||||
		}
 | 
			
		||||
		cv := reflect.ValueOf(v)
 | 
			
		||||
		for _, l := range ls {
 | 
			
		||||
			reflect.Append(cv, reflect.ValueOf(l))
 | 
			
		||||
		}
 | 
			
		||||
		err = options.Set(src, cv, ".Labels")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
func WithSpanLabels(labels ...interface{}) options.Option {
 | 
			
		||||
	return options.Labels(labels...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func WithSpanKind(k SpanKind) options.Option {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ package wrapper // import "go.unistack.org/micro/v4/tracer/wrapper"
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"go.unistack.org/micro/v4/client"
 | 
			
		||||
	"go.unistack.org/micro/v4/metadata"
 | 
			
		||||
@@ -12,13 +13,13 @@ import (
 | 
			
		||||
	"go.unistack.org/micro/v4/tracer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var DefaultHeadersExctract = []string{metadata.HeaderTopic, metadata.HeaderEndpoint, metadata.HeaderService, metadata.HeaderXRequestID}
 | 
			
		||||
var DefaultHeadersExctract = []string{metadata.HeaderXRequestID}
 | 
			
		||||
 | 
			
		||||
func extractLabels(md metadata.Metadata) []string {
 | 
			
		||||
	labels := make([]string, 0, 5)
 | 
			
		||||
func ExtractDefaultLabels(md metadata.Metadata) []interface{} {
 | 
			
		||||
	labels := make([]interface{}, 0, len(DefaultHeadersExctract))
 | 
			
		||||
	for _, k := range DefaultHeadersExctract {
 | 
			
		||||
		if v, ok := md.Get(k); ok {
 | 
			
		||||
			labels = append(labels, k, v)
 | 
			
		||||
			labels = append(labels, strings.ToLower(k), v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return labels
 | 
			
		||||
@@ -26,10 +27,9 @@ func extractLabels(md metadata.Metadata) []string {
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	DefaultClientCallObserver = func(ctx context.Context, req client.Request, rsp interface{}, opts []options.Option, sp tracer.Span, err error) {
 | 
			
		||||
		sp.SetName(fmt.Sprintf("Call %s.%s", req.Service(), req.Method()))
 | 
			
		||||
		var labels []interface{}
 | 
			
		||||
		if md, ok := metadata.FromOutgoingContext(ctx); ok {
 | 
			
		||||
			labels = append(labels, extractLabels(md))
 | 
			
		||||
			labels = append(labels, ExtractDefaultLabels(md)...)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sp.SetStatus(tracer.SpanStatusError, err.Error())
 | 
			
		||||
@@ -38,10 +38,9 @@ var (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DefaultClientStreamObserver = func(ctx context.Context, req client.Request, opts []options.Option, stream client.Stream, sp tracer.Span, err error) {
 | 
			
		||||
		sp.SetName(fmt.Sprintf("Stream %s.%s", req.Service(), req.Method()))
 | 
			
		||||
		var labels []interface{}
 | 
			
		||||
		if md, ok := metadata.FromOutgoingContext(ctx); ok {
 | 
			
		||||
			labels = append(labels, extractLabels(md))
 | 
			
		||||
			labels = append(labels, ExtractDefaultLabels(md)...)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sp.SetStatus(tracer.SpanStatusError, err.Error())
 | 
			
		||||
@@ -50,10 +49,9 @@ var (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DefaultServerHandlerObserver = func(ctx context.Context, req server.Request, rsp interface{}, sp tracer.Span, err error) {
 | 
			
		||||
		sp.SetName(fmt.Sprintf("Handler %s.%s", req.Service(), req.Method()))
 | 
			
		||||
		var labels []interface{}
 | 
			
		||||
		if md, ok := metadata.FromIncomingContext(ctx); ok {
 | 
			
		||||
			labels = append(labels, extractLabels(md))
 | 
			
		||||
			labels = append(labels, ExtractDefaultLabels(md)...)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sp.SetStatus(tracer.SpanStatusError, err.Error())
 | 
			
		||||
@@ -62,10 +60,10 @@ var (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DefaultClientCallFuncObserver = func(ctx context.Context, addr string, req client.Request, rsp interface{}, opts client.CallOptions, sp tracer.Span, err error) {
 | 
			
		||||
		sp.SetName(fmt.Sprintf("Call %s.%s", req.Service(), req.Method()))
 | 
			
		||||
		sp.SetName(fmt.Sprintf("%s.%s call", req.Service(), req.Method()))
 | 
			
		||||
		var labels []interface{}
 | 
			
		||||
		if md, ok := metadata.FromOutgoingContext(ctx); ok {
 | 
			
		||||
			labels = append(labels, extractLabels(md))
 | 
			
		||||
			labels = append(labels, ExtractDefaultLabels(md)...)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sp.SetStatus(tracer.SpanStatusError, err.Error())
 | 
			
		||||
@@ -177,23 +175,22 @@ func (ot *tWrapper) Call(ctx context.Context, req client.Request, rsp interface{
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sp, ok := tracer.SpanFromContext(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-client",
 | 
			
		||||
	nctx, sp := ot.opts.Tracer.Start(ctx, fmt.Sprintf("%s.%s rpc-client", req.Service(), req.Method()),
 | 
			
		||||
		tracer.WithSpanKind(tracer.SpanKindClient),
 | 
			
		||||
		tracer.WithSpanLabels(
 | 
			
		||||
			"rpc.service", req.Service(),
 | 
			
		||||
			"rpc.method", req.Method(),
 | 
			
		||||
			"rpc.flavor", "rpc",
 | 
			
		||||
			"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
 | 
			
		||||
			"rpc.call_type", "unary",
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
	}
 | 
			
		||||
	defer sp.Finish()
 | 
			
		||||
 | 
			
		||||
	err := ot.Client.Call(ctx, req, rsp, opts...)
 | 
			
		||||
	err := ot.Client.Call(nctx, req, rsp, opts...)
 | 
			
		||||
 | 
			
		||||
	for _, o := range ot.opts.ClientCallObservers {
 | 
			
		||||
		o(ctx, req, rsp, opts, sp, err)
 | 
			
		||||
		o(nctx, req, rsp, opts, sp, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
@@ -207,23 +204,22 @@ func (ot *tWrapper) Stream(ctx context.Context, req client.Request, opts ...opti
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sp, ok := tracer.SpanFromContext(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-client",
 | 
			
		||||
	nctx, sp := ot.opts.Tracer.Start(ctx, fmt.Sprintf("%s.%s rpc-client", req.Service(), req.Method()),
 | 
			
		||||
		tracer.WithSpanKind(tracer.SpanKindClient),
 | 
			
		||||
		tracer.WithSpanLabels(
 | 
			
		||||
			"rpc.service", req.Service(),
 | 
			
		||||
			"rpc.method", req.Method(),
 | 
			
		||||
			"rpc.flavor", "rpc",
 | 
			
		||||
			"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
 | 
			
		||||
			"rpc.call_type", "stream",
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
	}
 | 
			
		||||
	defer sp.Finish()
 | 
			
		||||
 | 
			
		||||
	stream, err := ot.Client.Stream(ctx, req, opts...)
 | 
			
		||||
	stream, err := ot.Client.Stream(nctx, req, opts...)
 | 
			
		||||
 | 
			
		||||
	for _, o := range ot.opts.ClientStreamObservers {
 | 
			
		||||
		o(ctx, req, opts, stream, sp, err)
 | 
			
		||||
		o(nctx, req, opts, stream, sp, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return stream, err
 | 
			
		||||
@@ -242,24 +238,22 @@ func (ot *tWrapper) ServerHandler(ctx context.Context, req server.Request, rsp i
 | 
			
		||||
		callType = "stream"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sp, ok := tracer.SpanFromContext(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-server",
 | 
			
		||||
	nctx, sp := ot.opts.Tracer.Start(ctx, fmt.Sprintf("%s.%s rpc-server", req.Service(), req.Method()),
 | 
			
		||||
		tracer.WithSpanKind(tracer.SpanKindServer),
 | 
			
		||||
		tracer.WithSpanLabels(
 | 
			
		||||
			"rpc.service", req.Service(),
 | 
			
		||||
			"rpc.method", req.Method(),
 | 
			
		||||
			"rpc.flavor", "rpc",
 | 
			
		||||
			"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
 | 
			
		||||
			"rpc.call_type", callType,
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer sp.Finish()
 | 
			
		||||
 | 
			
		||||
	err := ot.serverHandler(ctx, req, rsp)
 | 
			
		||||
	err := ot.serverHandler(nctx, req, rsp)
 | 
			
		||||
 | 
			
		||||
	for _, o := range ot.opts.ServerHandlerObservers {
 | 
			
		||||
		o(ctx, req, rsp, sp, err)
 | 
			
		||||
		o(nctx, req, rsp, sp, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
@@ -297,23 +291,23 @@ func (ot *tWrapper) ClientCallFunc(ctx context.Context, addr string, req client.
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sp, ok := tracer.SpanFromContext(ctx)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-client",
 | 
			
		||||
	nctx, sp := ot.opts.Tracer.Start(ctx, fmt.Sprintf("%s.%s rpc-client", req.Service(), req.Method()),
 | 
			
		||||
		tracer.WithSpanKind(tracer.SpanKindClient),
 | 
			
		||||
		tracer.WithSpanLabels(
 | 
			
		||||
			"rpc.service", req.Service(),
 | 
			
		||||
			"rpc.method", req.Method(),
 | 
			
		||||
			"rpc.flavor", "rpc",
 | 
			
		||||
			"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
 | 
			
		||||
			"rpc.call_type", "unary",
 | 
			
		||||
		),
 | 
			
		||||
	)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer sp.Finish()
 | 
			
		||||
 | 
			
		||||
	err := ot.clientCallFunc(ctx, addr, req, rsp, opts)
 | 
			
		||||
	err := ot.clientCallFunc(nctx, addr, req, rsp, opts)
 | 
			
		||||
 | 
			
		||||
	for _, o := range ot.opts.ClientCallFuncObservers {
 | 
			
		||||
		o(ctx, addr, req, rsp, opts, sp, err)
 | 
			
		||||
		o(nctx, addr, req, rsp, opts, sp, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user