tracer: improve tracing info #238
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user