summaryrefslogtreecommitdiff
path: root/vendor/github.com/uber/jaeger-client-go/tracer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uber/jaeger-client-go/tracer.go')
-rw-r--r--vendor/github.com/uber/jaeger-client-go/tracer.go164
1 files changed, 98 insertions, 66 deletions
diff --git a/vendor/github.com/uber/jaeger-client-go/tracer.go b/vendor/github.com/uber/jaeger-client-go/tracer.go
index d87fb10be..745a0c38a 100644
--- a/vendor/github.com/uber/jaeger-client-go/tracer.go
+++ b/vendor/github.com/uber/jaeger-client-go/tracer.go
@@ -47,15 +47,15 @@ type Tracer struct {
randomNumber func() uint64
options struct {
- poolSpans bool
- gen128Bit bool // whether to generate 128bit trace IDs
- zipkinSharedRPCSpan bool
- highTraceIDGenerator func() uint64 // custom high trace ID generator
- maxTagValueLength int
+ gen128Bit bool // whether to generate 128bit trace IDs
+ zipkinSharedRPCSpan bool
+ highTraceIDGenerator func() uint64 // custom high trace ID generator
+ maxTagValueLength int
+ noDebugFlagOnForcedSampling bool
// more options to come
}
- // pool for Span objects
- spanPool sync.Pool
+ // allocator of Span objects
+ spanAllocator SpanAllocator
injectors map[interface{}]Injector
extractors map[interface{}]Extractor
@@ -81,15 +81,13 @@ func NewTracer(
options ...TracerOption,
) (opentracing.Tracer, io.Closer) {
t := &Tracer{
- serviceName: serviceName,
- sampler: sampler,
- reporter: reporter,
- injectors: make(map[interface{}]Injector),
- extractors: make(map[interface{}]Extractor),
- metrics: *NewNullMetrics(),
- spanPool: sync.Pool{New: func() interface{} {
- return &Span{}
- }},
+ serviceName: serviceName,
+ sampler: sampler,
+ reporter: reporter,
+ injectors: make(map[interface{}]Injector),
+ extractors: make(map[interface{}]Extractor),
+ metrics: *NewNullMetrics(),
+ spanAllocator: simpleSpanAllocator{},
}
for _, option := range options {
@@ -148,7 +146,15 @@ func NewTracer(
if hostname, err := os.Hostname(); err == nil {
t.tags = append(t.tags, Tag{key: TracerHostnameTagKey, value: hostname})
}
- if ip, err := utils.HostIP(); err == nil {
+ if ipval, ok := t.getTag(TracerIPTagKey); ok {
+ ipv4, err := utils.ParseIPToUint32(ipval.(string))
+ if err != nil {
+ t.hostIPv4 = 0
+ t.logger.Error("Unable to convert the externally provided ip to uint32: " + err.Error())
+ } else {
+ t.hostIPv4 = ipv4
+ }
+ } else if ip, err := utils.HostIP(); err == nil {
t.tags = append(t.tags, Tag{key: TracerIPTagKey, value: ip.String()})
t.hostIPv4 = utils.PackIPAsUint32(ip)
} else {
@@ -217,20 +223,30 @@ func (t *Tracer) startSpanWithOptions(
var references []Reference
var parent SpanContext
var hasParent bool // need this because `parent` is a value, not reference
+ var ctx SpanContext
+ var isSelfRef bool
for _, ref := range options.References {
- ctx, ok := ref.ReferencedContext.(SpanContext)
+ ctxRef, ok := ref.ReferencedContext.(SpanContext)
if !ok {
t.logger.Error(fmt.Sprintf(
"Reference contains invalid type of SpanReference: %s",
reflect.ValueOf(ref.ReferencedContext)))
continue
}
- if !isValidReference(ctx) {
+ if !isValidReference(ctxRef) {
+ continue
+ }
+
+ if ref.Type == selfRefType {
+ isSelfRef = true
+ ctx = ctxRef
continue
}
- references = append(references, Reference{Type: ref.Type, Context: ctx})
+
+ references = append(references, Reference{Type: ref.Type, Context: ctxRef})
+
if !hasParent {
- parent = ctx
+ parent = ctxRef
hasParent = ref.Type == opentracing.ChildOfRef
}
}
@@ -246,42 +262,43 @@ func (t *Tracer) startSpanWithOptions(
}
var samplerTags []Tag
- var ctx SpanContext
newTrace := false
- if !hasParent || !parent.IsValid() {
- newTrace = true
- ctx.traceID.Low = t.randomID()
- if t.options.gen128Bit {
- ctx.traceID.High = t.options.highTraceIDGenerator()
- }
- ctx.spanID = SpanID(ctx.traceID.Low)
- ctx.parentID = 0
- ctx.flags = byte(0)
- if hasParent && parent.isDebugIDContainerOnly() && t.isDebugAllowed(operationName) {
- ctx.flags |= (flagSampled | flagDebug)
- samplerTags = []Tag{{key: JaegerDebugHeader, value: parent.debugID}}
- } else if sampled, tags := t.sampler.IsSampled(ctx.traceID, operationName); sampled {
- ctx.flags |= flagSampled
- samplerTags = tags
- }
- } else {
- ctx.traceID = parent.traceID
- if rpcServer && t.options.zipkinSharedRPCSpan {
- // Support Zipkin's one-span-per-RPC model
- ctx.spanID = parent.spanID
- ctx.parentID = parent.parentID
+ if !isSelfRef {
+ if !hasParent || !parent.IsValid() {
+ newTrace = true
+ ctx.traceID.Low = t.randomID()
+ if t.options.gen128Bit {
+ ctx.traceID.High = t.options.highTraceIDGenerator()
+ }
+ ctx.spanID = SpanID(ctx.traceID.Low)
+ ctx.parentID = 0
+ ctx.flags = byte(0)
+ if hasParent && parent.isDebugIDContainerOnly() && t.isDebugAllowed(operationName) {
+ ctx.flags |= (flagSampled | flagDebug)
+ samplerTags = []Tag{{key: JaegerDebugHeader, value: parent.debugID}}
+ } else if sampled, tags := t.sampler.IsSampled(ctx.traceID, operationName); sampled {
+ ctx.flags |= flagSampled
+ samplerTags = tags
+ }
} else {
- ctx.spanID = SpanID(t.randomID())
- ctx.parentID = parent.spanID
+ ctx.traceID = parent.traceID
+ if rpcServer && t.options.zipkinSharedRPCSpan {
+ // Support Zipkin's one-span-per-RPC model
+ ctx.spanID = parent.spanID
+ ctx.parentID = parent.parentID
+ } else {
+ ctx.spanID = SpanID(t.randomID())
+ ctx.parentID = parent.spanID
+ }
+ ctx.flags = parent.flags
}
- ctx.flags = parent.flags
- }
- if hasParent {
- // copy baggage items
- if l := len(parent.baggage); l > 0 {
- ctx.baggage = make(map[string]string, len(parent.baggage))
- for k, v := range parent.baggage {
- ctx.baggage[k] = v
+ if hasParent {
+ // copy baggage items
+ if l := len(parent.baggage); l > 0 {
+ ctx.baggage = make(map[string]string, len(parent.baggage))
+ for k, v := range parent.baggage {
+ ctx.baggage[k] = v
+ }
}
}
}
@@ -350,18 +367,20 @@ func (t *Tracer) Tags() []opentracing.Tag {
return tags
}
+// getTag returns the value of specific tag, if not exists, return nil.
+func (t *Tracer) getTag(key string) (interface{}, bool) {
+ for _, tag := range t.tags {
+ if tag.key == key {
+ return tag.value, true
+ }
+ }
+ return nil, false
+}
+
// newSpan returns an instance of a clean Span object.
// If options.PoolSpans is true, the spans are retrieved from an object pool.
func (t *Tracer) newSpan() *Span {
- if !t.options.poolSpans {
- return &Span{}
- }
- sp := t.spanPool.Get().(*Span)
- sp.context = emptyContext
- sp.tracer = nil
- sp.tags = nil
- sp.logs = nil
- return sp
+ return t.spanAllocator.Get()
}
func (t *Tracer) startSpanInternal(
@@ -416,12 +435,15 @@ func (t *Tracer) startSpanInternal(
func (t *Tracer) reportSpan(sp *Span) {
t.metrics.SpansFinished.Inc(1)
+
+ // Note: if the reporter is processing Span asynchronously need to Retain() it
+ // otherwise, in the racing condition will be rewritten span data before it will be sent
+ // * To remove object use method span.Release()
if sp.context.IsSampled() {
t.reporter.Report(sp)
}
- if t.options.poolSpans {
- t.spanPool.Put(sp)
- }
+
+ sp.Release()
}
// randomID generates a random trace/span ID, using tracer.random() generator.
@@ -443,3 +465,13 @@ func (t *Tracer) setBaggage(sp *Span, key, value string) {
func (t *Tracer) isDebugAllowed(operation string) bool {
return t.debugThrottler.IsAllowed(operation)
}
+
+// SelfRef creates an opentracing compliant SpanReference from a jaeger
+// SpanContext. This is a factory function in order to encapsulate jaeger specific
+// types.
+func SelfRef(ctx SpanContext) opentracing.SpanReference {
+ return opentracing.SpanReference{
+ Type: selfRefType,
+ ReferencedContext: ctx,
+ }
+}