Tracing: traces now correctly form a tree (#1170)

* First cut of trace

* Dial it back yo

* Defensive programming
This commit is contained in:
Janos Dobronszki 2020-02-06 17:22:16 +00:00 committed by GitHub
parent 16552620e0
commit 92571db693
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 18 deletions

View File

@ -49,27 +49,27 @@ func (t *Tracer) Start(ctx context.Context, name string) (context.Context, *trac
// return span if no context // return span if no context
if ctx == nil { if ctx == nil {
return context.Background(), span return trace.ToContext(context.Background(), span.Trace, span.Id), span
} }
traceID, parentSpanID, ok := trace.FromContext(ctx)
s, ok := trace.FromContext(ctx) // If the trace can not be found in the header,
// that means this is where the trace is created.
if !ok { if !ok {
return ctx, span return trace.ToContext(ctx, span.Trace, span.Id), span
} }
// set trace id // set trace id
span.Trace = s.Trace span.Trace = traceID
// set parent // set parent
span.Parent = s.Id span.Parent = parentSpanID
// return the sapn // return the span
return ctx, span return trace.ToContext(ctx, span.Trace, span.Id), span
} }
func (t *Tracer) Finish(s *trace.Span) error { func (t *Tracer) Finish(s *trace.Span) error {
// set finished time // set finished time
s.Duration = time.Since(s.Started) s.Duration = time.Since(s.Started)
// save the span // save the span
t.buffer.Put(s) t.buffer.Put(s)
@ -84,7 +84,7 @@ func NewTracer(opts ...trace.Option) trace.Tracer {
return &Tracer{ return &Tracer{
opts: options, opts: options,
// the last 64 requests // the last 256 requests
buffer: ring.New(64), buffer: ring.New(256),
} }
} }

View File

@ -3,6 +3,7 @@ package trace
import ( import (
"context" "context"
"github.com/micro/go-micro/v2/metadata"
"time" "time"
) )
@ -34,17 +35,32 @@ type Span struct {
Metadata map[string]string Metadata map[string]string
} }
type spanKey struct{} const (
traceIDKey = "Micro-Trace-Id"
spanIDKey = "Micro-Span-Id"
)
// FromContext returns a span from context // FromContext returns a span from context
func FromContext(ctx context.Context) (*Span, bool) { func FromContext(ctx context.Context) (traceID string, parentSpanID string, isFound bool) {
s, ok := ctx.Value(spanKey{}).(*Span) traceID, traceOk := metadata.Get(ctx, traceIDKey)
return s, ok microID, microOk := metadata.Get(ctx, "Micro-Id")
if !traceOk && !microOk {
isFound = false
return
}
if !traceOk {
traceID = microID
}
parentSpanID, ok := metadata.Get(ctx, spanIDKey)
return traceID, parentSpanID, ok
} }
// NewContext creates a new context with the span // ToContext saves the trace and span ids in the context
func NewContext(ctx context.Context, s *Span) context.Context { func ToContext(ctx context.Context, traceID, parentSpanID string) context.Context {
return context.WithValue(ctx, spanKey{}, s) return metadata.MergeContext(ctx, map[string]string{
traceIDKey: traceID,
spanIDKey: parentSpanID,
}, true)
} }
var ( var (

View File

@ -63,6 +63,9 @@ func NewContext(ctx context.Context, md Metadata) context.Context {
// MergeContext merges metadata to existing metadata, overwriting if specified // MergeContext merges metadata to existing metadata, overwriting if specified
func MergeContext(ctx context.Context, patchMd Metadata, overwrite bool) context.Context { func MergeContext(ctx context.Context, patchMd Metadata, overwrite bool) context.Context {
if ctx == nil {
ctx = context.Background()
}
md, _ := ctx.Value(metaKey{}).(Metadata) md, _ := ctx.Value(metaKey{}).(Metadata)
cmd := make(Metadata) cmd := make(Metadata)
for k, v := range md { for k, v := range md {