add default propagation for trace (#919)
* add default propagation for trace * add trace carrierpull/920/head
parent
d78eb3ee4b
commit
8f8b861f7d
@ -0,0 +1,41 @@ |
||||
package tracing |
||||
|
||||
import ( |
||||
"google.golang.org/grpc/metadata" |
||||
) |
||||
|
||||
// MetadataCarrier is grpc metadata carrier
|
||||
type MetadataCarrier metadata.MD |
||||
|
||||
// Get returns the value associated with the passed key.
|
||||
func (mc MetadataCarrier) Get(key string) string { |
||||
values := metadata.MD(mc).Get(key) |
||||
if len(values) == 0 { |
||||
return "" |
||||
} |
||||
return values[0] |
||||
} |
||||
|
||||
// Set stores the key-value pair.
|
||||
func (mc MetadataCarrier) Set(key string, value string) { |
||||
metadata.MD(mc).Set(key, value) |
||||
} |
||||
|
||||
// Keys lists the keys stored in this carrier.
|
||||
func (mc MetadataCarrier) Keys() []string { |
||||
keys := make([]string, 0, metadata.MD(mc).Len()) |
||||
for key := range metadata.MD(mc) { |
||||
keys = append(keys, key) |
||||
} |
||||
return keys |
||||
} |
||||
|
||||
// Del delete key
|
||||
func (mc MetadataCarrier) Del(key string) { |
||||
delete(mc, key) |
||||
} |
||||
|
||||
// Clone copy MetadataCarrier
|
||||
func (mc MetadataCarrier) Clone() MetadataCarrier { |
||||
return MetadataCarrier(metadata.MD(mc).Copy()) |
||||
} |
@ -0,0 +1,75 @@ |
||||
package tracing |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
|
||||
"go.opentelemetry.io/otel" |
||||
"go.opentelemetry.io/otel/attribute" |
||||
"go.opentelemetry.io/otel/codes" |
||||
"go.opentelemetry.io/otel/propagation" |
||||
"go.opentelemetry.io/otel/trace" |
||||
) |
||||
|
||||
// Tracer is otel span tracer
|
||||
type Tracer struct { |
||||
tracer trace.Tracer |
||||
kind trace.SpanKind |
||||
} |
||||
|
||||
// NewTracer create tracer instance
|
||||
func NewTracer(kind trace.SpanKind, opts ...Option) *Tracer { |
||||
options := options{} |
||||
for _, o := range opts { |
||||
o(&options) |
||||
} |
||||
if options.TracerProvider != nil { |
||||
otel.SetTracerProvider(options.TracerProvider) |
||||
} |
||||
if options.Propagators != nil { |
||||
otel.SetTextMapPropagator(options.Propagators) |
||||
} else { |
||||
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{})) |
||||
} |
||||
var name string |
||||
if kind == trace.SpanKindServer { |
||||
name = "server" |
||||
} else if kind == trace.SpanKindClient { |
||||
name = "client" |
||||
} else { |
||||
panic(fmt.Sprintf("unsupported span kind: %v", kind)) |
||||
} |
||||
tracer := otel.Tracer(name) |
||||
return &Tracer{tracer: tracer, kind: kind} |
||||
} |
||||
|
||||
// Start start tracing span
|
||||
func (t *Tracer) Start(ctx context.Context, component string, operation string, carrier propagation.TextMapCarrier) (context.Context, trace.Span) { |
||||
if t.kind == trace.SpanKindServer { |
||||
ctx = otel.GetTextMapPropagator().Extract(ctx, carrier) |
||||
} |
||||
ctx, span := t.tracer.Start(ctx, |
||||
operation, |
||||
trace.WithAttributes(attribute.String("component", component)), |
||||
trace.WithSpanKind(t.kind), |
||||
) |
||||
if t.kind == trace.SpanKindClient { |
||||
otel.GetTextMapPropagator().Inject(ctx, carrier) |
||||
} |
||||
return ctx, span |
||||
} |
||||
|
||||
// End finish tracing span
|
||||
func (t *Tracer) End(ctx context.Context, span trace.Span, err error) { |
||||
if err != nil { |
||||
span.RecordError(err) |
||||
span.SetAttributes( |
||||
attribute.String("event", "error"), |
||||
attribute.String("message", err.Error()), |
||||
) |
||||
span.SetStatus(codes.Error, err.Error()) |
||||
} else { |
||||
span.SetStatus(codes.Ok, "OK") |
||||
} |
||||
span.End() |
||||
} |
Loading…
Reference in new issue