Merge pull request 'tracer: improve tracing info' (#238) from tracing into v3

Reviewed-on: #238
This commit is contained in:
Василий Толстов 2023-09-01 08:41:46 +03:00
commit ca80e3ecf2
3 changed files with 73 additions and 47 deletions

View File

@ -19,6 +19,8 @@ var (
HeaderTimeout = "Micro-Timeout" HeaderTimeout = "Micro-Timeout"
// HeaderAuthorization specifies Authorization header // HeaderAuthorization specifies Authorization header
HeaderAuthorization = "Authorization" HeaderAuthorization = "Authorization"
// HeaderXRequestID specifies request id
HeaderXRequestID = "X-Request-Id"
) )
// Metadata is our way of representing request headers internally. // Metadata is our way of representing request headers internally.

View File

@ -91,11 +91,19 @@ type SpanOptions struct {
type SpanOption func(o *SpanOptions) type SpanOption func(o *SpanOptions)
// EventOptions contains event options // EventOptions contains event options
type EventOptions struct{} type EventOptions struct {
Labels []interface{}
}
// EventOption func signature // EventOption func signature
type EventOption func(o *EventOptions) type EventOption func(o *EventOptions)
func WithEventLabels(labels ...interface{}) EventOption {
return func(o *EventOptions) {
o.Labels = labels
}
}
func WithSpanLabels(labels ...interface{}) SpanOption { func WithSpanLabels(labels ...interface{}) SpanOption {
return func(o *SpanOptions) { return func(o *SpanOptions) {
o.Labels = labels o.Labels = labels

View File

@ -11,107 +11,89 @@ import (
"go.unistack.org/micro/v3/tracer" "go.unistack.org/micro/v3/tracer"
) )
var DefaultHeadersExctract = []string{metadata.HeaderTopic, metadata.HeaderEndpoint, metadata.HeaderService, metadata.HeaderXRequestID}
func extractLabels(md metadata.Metadata) []string {
labels := make([]string, 0, 5)
for _, k := range DefaultHeadersExctract {
if v, ok := md.Get(k); ok {
labels = append(labels, k, v)
}
}
return labels
}
var ( var (
DefaultClientCallObserver = func(ctx context.Context, req client.Request, rsp interface{}, opts []client.CallOption, sp tracer.Span, err error) { DefaultClientCallObserver = func(ctx context.Context, req client.Request, rsp interface{}, opts []client.CallOption, sp tracer.Span, err error) {
sp.SetName(fmt.Sprintf("Call %s.%s", req.Service(), req.Method())) sp.SetName(fmt.Sprintf("Call %s.%s", req.Service(), req.Method()))
var labels []interface{} var labels []interface{}
if md, ok := metadata.FromOutgoingContext(ctx); ok { if md, ok := metadata.FromOutgoingContext(ctx); ok {
labels = make([]interface{}, 0, len(md)+1) labels = append(labels, extractLabels(md))
for k, v := range md {
labels = append(labels, k, v)
}
} }
if err != nil { if err != nil {
labels = append(labels, "error", err.Error())
sp.SetStatus(tracer.SpanStatusError, err.Error()) sp.SetStatus(tracer.SpanStatusError, err.Error())
} }
labels = append(labels, "kind", sp.Kind()) sp.AddLabels(labels...)
sp.SetLabels(labels...)
} }
DefaultClientStreamObserver = func(ctx context.Context, req client.Request, opts []client.CallOption, stream client.Stream, sp tracer.Span, err error) { DefaultClientStreamObserver = func(ctx context.Context, req client.Request, opts []client.CallOption, stream client.Stream, sp tracer.Span, err error) {
sp.SetName(fmt.Sprintf("Stream %s.%s", req.Service(), req.Method())) sp.SetName(fmt.Sprintf("Stream %s.%s", req.Service(), req.Method()))
var labels []interface{} var labels []interface{}
if md, ok := metadata.FromOutgoingContext(ctx); ok { if md, ok := metadata.FromOutgoingContext(ctx); ok {
labels = make([]interface{}, 0, len(md)) labels = append(labels, extractLabels(md))
for k, v := range md {
labels = append(labels, k, v)
}
} }
if err != nil { if err != nil {
labels = append(labels, "error", err.Error())
sp.SetStatus(tracer.SpanStatusError, err.Error()) sp.SetStatus(tracer.SpanStatusError, err.Error())
} }
labels = append(labels, "kind", sp.Kind()) sp.AddLabels(labels...)
sp.SetLabels(labels...)
} }
DefaultClientPublishObserver = func(ctx context.Context, msg client.Message, opts []client.PublishOption, sp tracer.Span, err error) { DefaultClientPublishObserver = func(ctx context.Context, msg client.Message, opts []client.PublishOption, sp tracer.Span, err error) {
sp.SetName(fmt.Sprintf("Publish %s", msg.Topic())) sp.SetName(fmt.Sprintf("Publish %s", msg.Topic()))
var labels []interface{} var labels []interface{}
if md, ok := metadata.FromOutgoingContext(ctx); ok { if md, ok := metadata.FromOutgoingContext(ctx); ok {
labels = make([]interface{}, 0, len(md)) labels = append(labels, extractLabels(md))
for k, v := range md {
labels = append(labels, k, v)
}
} }
if err != nil { if err != nil {
labels = append(labels, "error", err.Error())
sp.SetStatus(tracer.SpanStatusError, err.Error()) sp.SetStatus(tracer.SpanStatusError, err.Error())
} }
labels = append(labels, "kind", sp.Kind()) sp.AddLabels(labels...)
sp.SetLabels(labels...)
} }
DefaultServerHandlerObserver = func(ctx context.Context, req server.Request, rsp interface{}, sp tracer.Span, err error) { 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())) sp.SetName(fmt.Sprintf("Handler %s.%s", req.Service(), req.Method()))
var labels []interface{} var labels []interface{}
if md, ok := metadata.FromIncomingContext(ctx); ok { if md, ok := metadata.FromIncomingContext(ctx); ok {
labels = make([]interface{}, 0, len(md)) labels = append(labels, extractLabels(md))
for k, v := range md {
labels = append(labels, k, v)
}
} }
if err != nil { if err != nil {
labels = append(labels, "error", err.Error())
sp.SetStatus(tracer.SpanStatusError, err.Error()) sp.SetStatus(tracer.SpanStatusError, err.Error())
} }
labels = append(labels, "kind", sp.Kind()) sp.AddLabels(labels...)
sp.SetLabels(labels...)
} }
DefaultServerSubscriberObserver = func(ctx context.Context, msg server.Message, sp tracer.Span, err error) { DefaultServerSubscriberObserver = func(ctx context.Context, msg server.Message, sp tracer.Span, err error) {
sp.SetName(fmt.Sprintf("Subscriber %s", msg.Topic())) sp.SetName(fmt.Sprintf("Subscriber %s", msg.Topic()))
var labels []interface{} var labels []interface{}
if md, ok := metadata.FromIncomingContext(ctx); ok { if md, ok := metadata.FromIncomingContext(ctx); ok {
labels = make([]interface{}, 0, len(md)) labels = append(labels, extractLabels(md))
for k, v := range md {
labels = append(labels, k, v)
}
} }
if err != nil { if err != nil {
labels = append(labels, "error", err.Error())
sp.SetStatus(tracer.SpanStatusError, err.Error()) sp.SetStatus(tracer.SpanStatusError, err.Error())
} }
labels = append(labels, "kind", sp.Kind()) sp.AddLabels(labels...)
sp.SetLabels(labels...)
} }
DefaultClientCallFuncObserver = func(ctx context.Context, addr string, req client.Request, rsp interface{}, opts client.CallOptions, sp tracer.Span, err error) { 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("Call %s.%s", req.Service(), req.Method()))
var labels []interface{} var labels []interface{}
if md, ok := metadata.FromOutgoingContext(ctx); ok { if md, ok := metadata.FromOutgoingContext(ctx); ok {
labels = make([]interface{}, 0, len(md)) labels = append(labels, extractLabels(md))
for k, v := range md {
labels = append(labels, k, v)
}
} }
if err != nil { if err != nil {
labels = append(labels, "error", err.Error())
sp.SetStatus(tracer.SpanStatusError, err.Error()) sp.SetStatus(tracer.SpanStatusError, err.Error())
} }
labels = append(labels, "kind", sp.Kind()) sp.AddLabels(labels...)
sp.SetLabels(labels...)
} }
DefaultSkipEndpoints = []string{"Meter.Metrics", "Health.Live", "Health.Ready", "Health.Version"} DefaultSkipEndpoints = []string{"Meter.Metrics", "Health.Live", "Health.Ready", "Health.Version"}
@ -243,7 +225,14 @@ func (ot *tWrapper) Call(ctx context.Context, req client.Request, rsp interface{
sp, ok := tracer.SpanFromContext(ctx) sp, ok := tracer.SpanFromContext(ctx)
if !ok { if !ok {
ctx, sp = ot.opts.Tracer.Start(ctx, "", tracer.WithSpanKind(tracer.SpanKindClient)) ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-client",
tracer.WithSpanKind(tracer.SpanKindClient),
tracer.WithSpanLabels(
"rpc.flavor", "rpc",
"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
"rpc.call_type", "unary",
),
)
} }
defer sp.Finish() defer sp.Finish()
@ -266,7 +255,14 @@ func (ot *tWrapper) Stream(ctx context.Context, req client.Request, opts ...clie
sp, ok := tracer.SpanFromContext(ctx) sp, ok := tracer.SpanFromContext(ctx)
if !ok { if !ok {
ctx, sp = ot.opts.Tracer.Start(ctx, "", tracer.WithSpanKind(tracer.SpanKindClient)) ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-client",
tracer.WithSpanKind(tracer.SpanKindClient),
tracer.WithSpanLabels(
"rpc.flavor", "rpc",
"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
"rpc.call_type", "stream",
),
)
} }
defer sp.Finish() defer sp.Finish()
@ -303,10 +299,23 @@ func (ot *tWrapper) ServerHandler(ctx context.Context, req server.Request, rsp i
} }
} }
callType := "unary"
if req.Stream() {
callType = "stream"
}
sp, ok := tracer.SpanFromContext(ctx) sp, ok := tracer.SpanFromContext(ctx)
if !ok { if !ok {
ctx, sp = ot.opts.Tracer.Start(ctx, "", tracer.WithSpanKind(tracer.SpanKindServer)) ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-server",
tracer.WithSpanKind(tracer.SpanKindServer),
tracer.WithSpanLabels(
"rpc.flavor", "rpc",
"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
"rpc.call_type", callType,
),
)
} }
defer sp.Finish() defer sp.Finish()
err := ot.serverHandler(ctx, req, rsp) err := ot.serverHandler(ctx, req, rsp)
@ -368,7 +377,14 @@ func (ot *tWrapper) ClientCallFunc(ctx context.Context, addr string, req client.
sp, ok := tracer.SpanFromContext(ctx) sp, ok := tracer.SpanFromContext(ctx)
if !ok { if !ok {
ctx, sp = ot.opts.Tracer.Start(ctx, "", tracer.WithSpanKind(tracer.SpanKindClient)) ctx, sp = ot.opts.Tracer.Start(ctx, "rpc-client",
tracer.WithSpanKind(tracer.SpanKindClient),
tracer.WithSpanLabels(
"rpc.flavor", "rpc",
"rpc.call", "/"+req.Service()+"/"+req.Endpoint(),
"rpc.call_type", "unary",
),
)
} }
defer sp.Finish() defer sp.Finish()