Upgraded DataDog tracing library to 1.14.0
This commit is contained in:
parent
1f2fe08c33
commit
adc2b62c22
13 changed files with 485 additions and 60 deletions
8
Gopkg.lock
generated
8
Gopkg.lock
generated
|
@ -1864,7 +1864,7 @@
|
||||||
version = "v1.20.1"
|
version = "v1.20.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:b886012746f19e2a7c6c3901ea9f86e8a5e32ff2b4407086f4f3181269976957"
|
digest = "1:b49eceff862a3048ec28dad1fce40bcbdc1703119dbad35d7e5f1beb4f9a4527"
|
||||||
name = "gopkg.in/DataDog/dd-trace-go.v1"
|
name = "gopkg.in/DataDog/dd-trace-go.v1"
|
||||||
packages = [
|
packages = [
|
||||||
"ddtrace",
|
"ddtrace",
|
||||||
|
@ -1872,10 +1872,11 @@
|
||||||
"ddtrace/internal",
|
"ddtrace/internal",
|
||||||
"ddtrace/opentracer",
|
"ddtrace/opentracer",
|
||||||
"ddtrace/tracer",
|
"ddtrace/tracer",
|
||||||
|
"internal/globalconfig",
|
||||||
]
|
]
|
||||||
pruneopts = "NUT"
|
pruneopts = "NUT"
|
||||||
revision = "7fb2bce4b1ed6ab61f7a9e1be30dea56de19db7c"
|
revision = "c19e9e56d5b5b71b6507ce1b0ec06d85aa3705a1"
|
||||||
version = "v1.8.0"
|
version = "v1.14.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:c970218a20933dd0a2eb2006de922217fa9276f57d25009b2a934eb1c50031cc"
|
digest = "1:c970218a20933dd0a2eb2006de922217fa9276f57d25009b2a934eb1c50031cc"
|
||||||
|
@ -2287,6 +2288,7 @@
|
||||||
"github.com/opentracing/opentracing-go/log",
|
"github.com/opentracing/opentracing-go/log",
|
||||||
"github.com/openzipkin-contrib/zipkin-go-opentracing",
|
"github.com/openzipkin-contrib/zipkin-go-opentracing",
|
||||||
"github.com/patrickmn/go-cache",
|
"github.com/patrickmn/go-cache",
|
||||||
|
"github.com/pmezard/go-difflib/difflib",
|
||||||
"github.com/prometheus/client_golang/prometheus",
|
"github.com/prometheus/client_golang/prometheus",
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp",
|
"github.com/prometheus/client_golang/prometheus/promhttp",
|
||||||
"github.com/prometheus/client_model/go",
|
"github.com/prometheus/client_model/go",
|
||||||
|
|
|
@ -285,7 +285,7 @@ required = [
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "gopkg.in/DataDog/dd-trace-go.v1"
|
name = "gopkg.in/DataDog/dd-trace-go.v1"
|
||||||
version = "1.7.0"
|
version = "1.13.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/instana/go-sensor"
|
name = "github.com/instana/go-sensor"
|
||||||
|
|
10
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go
generated
vendored
10
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go
generated
vendored
|
@ -91,6 +91,12 @@ type FinishConfig struct {
|
||||||
|
|
||||||
// NoDebugStack will prevent any set errors from generating an attached stack trace tag.
|
// NoDebugStack will prevent any set errors from generating an attached stack trace tag.
|
||||||
NoDebugStack bool
|
NoDebugStack bool
|
||||||
|
|
||||||
|
// StackFrames specifies the number of stack frames to be attached in spans that finish with errors.
|
||||||
|
StackFrames uint
|
||||||
|
|
||||||
|
// SkipStackFrames specifies the offset at which to start reporting stack frames from the stack.
|
||||||
|
SkipStackFrames uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartSpanConfig holds the configuration for starting a new span. It is usually passed
|
// StartSpanConfig holds the configuration for starting a new span. It is usually passed
|
||||||
|
@ -108,4 +114,8 @@ type StartSpanConfig struct {
|
||||||
// Tags holds a set of key/value pairs that should be set as metadata on the
|
// Tags holds a set of key/value pairs that should be set as metadata on the
|
||||||
// new span.
|
// new span.
|
||||||
Tags map[string]interface{}
|
Tags map[string]interface{}
|
||||||
|
|
||||||
|
// Force-set the SpanID, rather than use a random number. If no Parent SpanContext is present,
|
||||||
|
// then this will also set the TraceID to the same value.
|
||||||
|
SpanID uint64
|
||||||
}
|
}
|
||||||
|
|
25
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go
generated
vendored
25
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go
generated
vendored
|
@ -27,10 +27,15 @@ const (
|
||||||
// HTTPURL sets the HTTP URL for a span.
|
// HTTPURL sets the HTTP URL for a span.
|
||||||
HTTPURL = "http.url"
|
HTTPURL = "http.url"
|
||||||
|
|
||||||
// TODO: In the next major version, suffix these constants (SpanType, etc)
|
// TODO: In the next major version, prefix these constants (SpanType, etc)
|
||||||
// with "*Key" (SpanTypeKey, etc) to more easily differentiate between
|
// with "Key*" (KeySpanType, etc) to more easily differentiate between
|
||||||
// constants representing tag values and constants representing keys.
|
// constants representing tag values and constants representing keys.
|
||||||
|
|
||||||
|
// SpanName is a pseudo-key for setting a span's operation name by means of
|
||||||
|
// a tag. It is mostly here to facilitate vendor-agnostic frameworks like Opentracing
|
||||||
|
// and OpenCensus.
|
||||||
|
SpanName = "span.name"
|
||||||
|
|
||||||
// SpanType defines the Span type (web, db, cache).
|
// SpanType defines the Span type (web, db, cache).
|
||||||
SpanType = "span.type"
|
SpanType = "span.type"
|
||||||
|
|
||||||
|
@ -54,4 +59,20 @@ const (
|
||||||
|
|
||||||
// Environment specifies the environment to use with a trace.
|
// Environment specifies the environment to use with a trace.
|
||||||
Environment = "env"
|
Environment = "env"
|
||||||
|
|
||||||
|
// EventSampleRate specifies the rate at which this span will be sampled
|
||||||
|
// as an APM event.
|
||||||
|
EventSampleRate = "_dd1.sr.eausr"
|
||||||
|
|
||||||
|
// AnalyticsEvent specifies whether the span should be recorded as a Trace
|
||||||
|
// Search & Analytics event.
|
||||||
|
AnalyticsEvent = "analytics.event"
|
||||||
|
|
||||||
|
// ManualKeep is a tag which specifies that the trace to which this span
|
||||||
|
// belongs to should be kept when set to true.
|
||||||
|
ManualKeep = "manual.keep"
|
||||||
|
|
||||||
|
// ManualDrop is a tag which specifies that the trace to which this span
|
||||||
|
// belongs to should be dropped when set to true.
|
||||||
|
ManualDrop = "manual.drop"
|
||||||
)
|
)
|
||||||
|
|
5
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go
generated
vendored
5
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go
generated
vendored
|
@ -18,6 +18,11 @@ func ResourceName(name string) opentracing.StartSpanOption {
|
||||||
return opentracing.Tag{Key: ext.ResourceName, Value: name}
|
return opentracing.Tag{Key: ext.ResourceName, Value: name}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SpanName sets the Datadog operation name for the span.
|
||||||
|
func SpanName(name string) opentracing.StartSpanOption {
|
||||||
|
return opentracing.Tag{Key: ext.SpanName, Value: name}
|
||||||
|
}
|
||||||
|
|
||||||
// SpanType can be used with opentracing.StartSpan to set the type of a span.
|
// SpanType can be used with opentracing.StartSpan to set the type of a span.
|
||||||
func SpanType(name string) opentracing.StartSpanOption {
|
func SpanType(name string) opentracing.StartSpanOption {
|
||||||
return opentracing.Tag{Key: ext.SpanType, Value: name}
|
return opentracing.Tag{Key: ext.SpanType, Value: name}
|
||||||
|
|
55
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go
generated
vendored
55
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go
generated
vendored
|
@ -1,6 +1,7 @@
|
||||||
package tracer
|
package tracer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -8,6 +9,7 @@ import (
|
||||||
|
|
||||||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
|
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
|
||||||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
|
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
|
||||||
|
"gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
// config holds the tracer configuration.
|
// config holds the tracer configuration.
|
||||||
|
@ -21,7 +23,7 @@ type config struct {
|
||||||
// sampler specifies the sampler that will be used for sampling traces.
|
// sampler specifies the sampler that will be used for sampling traces.
|
||||||
sampler Sampler
|
sampler Sampler
|
||||||
|
|
||||||
// agentAddr specifies the hostname and of the agent where the traces
|
// agentAddr specifies the hostname and port of the agent where the traces
|
||||||
// are sent to.
|
// are sent to.
|
||||||
agentAddr string
|
agentAddr string
|
||||||
|
|
||||||
|
@ -37,6 +39,10 @@ type config struct {
|
||||||
|
|
||||||
// httpRoundTripper defines the http.RoundTripper used by the agent transport.
|
// httpRoundTripper defines the http.RoundTripper used by the agent transport.
|
||||||
httpRoundTripper http.RoundTripper
|
httpRoundTripper http.RoundTripper
|
||||||
|
|
||||||
|
// hostname is automatically assigned when the DD_TRACE_REPORT_HOSTNAME is set to true,
|
||||||
|
// and is added as a special tag to the root span of traces.
|
||||||
|
hostname string
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartOption represents a function that can be provided as a parameter to Start.
|
// StartOption represents a function that can be provided as a parameter to Start.
|
||||||
|
@ -47,6 +53,14 @@ func defaults(c *config) {
|
||||||
c.serviceName = filepath.Base(os.Args[0])
|
c.serviceName = filepath.Base(os.Args[0])
|
||||||
c.sampler = NewAllSampler()
|
c.sampler = NewAllSampler()
|
||||||
c.agentAddr = defaultAddress
|
c.agentAddr = defaultAddress
|
||||||
|
|
||||||
|
if os.Getenv("DD_TRACE_REPORT_HOSTNAME") == "true" {
|
||||||
|
var err error
|
||||||
|
c.hostname, err = os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("%sunable to look up hostname: %v\n", errorPrefix, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithPrioritySampling is deprecated, and priority sampling is enabled by default.
|
// WithPrioritySampling is deprecated, and priority sampling is enabled by default.
|
||||||
|
@ -117,6 +131,22 @@ func WithHTTPRoundTripper(r http.RoundTripper) StartOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAnalytics allows specifying whether Trace Search & Analytics should be enabled
|
||||||
|
// for integrations.
|
||||||
|
func WithAnalytics(on bool) StartOption {
|
||||||
|
if on {
|
||||||
|
return WithAnalyticsRate(1.0)
|
||||||
|
}
|
||||||
|
return WithAnalyticsRate(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAnalyticsRate sets the global sampling rate for sampling APM events.
|
||||||
|
func WithAnalyticsRate(rate float64) StartOption {
|
||||||
|
return func(_ *config) {
|
||||||
|
globalconfig.SetAnalyticsRate(rate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StartSpanOption is a configuration option for StartSpan. It is aliased in order
|
// StartSpanOption is a configuration option for StartSpan. It is aliased in order
|
||||||
// to help godoc group all the functions returning it together. It is considered
|
// to help godoc group all the functions returning it together. It is considered
|
||||||
// more correct to refer to it as the type as the origin, ddtrace.StartSpanOption.
|
// more correct to refer to it as the type as the origin, ddtrace.StartSpanOption.
|
||||||
|
@ -149,6 +179,15 @@ func SpanType(name string) StartSpanOption {
|
||||||
return Tag(ext.SpanType, name)
|
return Tag(ext.SpanType, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSpanID sets the SpanID on the started span, instead of using a random number.
|
||||||
|
// If there is no parent Span (eg from ChildOf), then the TraceID will also be set to the
|
||||||
|
// value given here.
|
||||||
|
func WithSpanID(id uint64) StartSpanOption {
|
||||||
|
return func(cfg *ddtrace.StartSpanConfig) {
|
||||||
|
cfg.SpanID = id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ChildOf tells StartSpan to use the given span context as a parent for the
|
// ChildOf tells StartSpan to use the given span context as a parent for the
|
||||||
// created span.
|
// created span.
|
||||||
func ChildOf(ctx ddtrace.SpanContext) StartSpanOption {
|
func ChildOf(ctx ddtrace.SpanContext) StartSpanOption {
|
||||||
|
@ -179,7 +218,8 @@ func FinishTime(t time.Time) FinishOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithError marks the span as having had an error. It uses the information from
|
// WithError marks the span as having had an error. It uses the information from
|
||||||
// err to set tags such as the error message, error type and stack trace.
|
// err to set tags such as the error message, error type and stack trace. It has
|
||||||
|
// no effect if the error is nil.
|
||||||
func WithError(err error) FinishOption {
|
func WithError(err error) FinishOption {
|
||||||
return func(cfg *ddtrace.FinishConfig) {
|
return func(cfg *ddtrace.FinishConfig) {
|
||||||
cfg.Error = err
|
cfg.Error = err
|
||||||
|
@ -194,3 +234,14 @@ func NoDebugStack() FinishOption {
|
||||||
cfg.NoDebugStack = true
|
cfg.NoDebugStack = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StackFrames limits the number of stack frames included into erroneous spans to n, starting from skip.
|
||||||
|
func StackFrames(n, skip uint) FinishOption {
|
||||||
|
if n == 0 {
|
||||||
|
return NoDebugStack()
|
||||||
|
}
|
||||||
|
return func(cfg *ddtrace.FinishConfig) {
|
||||||
|
cfg.StackFrames = n
|
||||||
|
cfg.SkipStackFrames = skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go
generated
vendored
2
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go
generated
vendored
|
@ -140,5 +140,5 @@ func (ps *prioritySampler) apply(spn *span) {
|
||||||
} else {
|
} else {
|
||||||
spn.SetTag(ext.SamplingPriority, ext.PriorityAutoReject)
|
spn.SetTag(ext.SamplingPriority, ext.PriorityAutoReject)
|
||||||
}
|
}
|
||||||
spn.SetTag(samplingPriorityRateKey, rate)
|
spn.SetTag(keySamplingPriorityRate, rate)
|
||||||
}
|
}
|
||||||
|
|
97
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go
generated
vendored
97
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go
generated
vendored
|
@ -5,7 +5,9 @@ package tracer
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -30,6 +32,13 @@ var (
|
||||||
_ msgp.Decodable = (*spanLists)(nil)
|
_ msgp.Decodable = (*spanLists)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// errorConfig holds customization options for setting error tags.
|
||||||
|
type errorConfig struct {
|
||||||
|
noDebugStack bool
|
||||||
|
stackFrames uint
|
||||||
|
stackSkip uint
|
||||||
|
}
|
||||||
|
|
||||||
// span represents a computation. Callers must call Finish when a span is
|
// span represents a computation. Callers must call Finish when a span is
|
||||||
// complete to ensure it's submitted.
|
// complete to ensure it's submitted.
|
||||||
type span struct {
|
type span struct {
|
||||||
|
@ -80,8 +89,13 @@ func (s *span) SetTag(key string, value interface{}) {
|
||||||
if s.finished {
|
if s.finished {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if key == ext.Error {
|
switch key {
|
||||||
s.setTagError(value, true)
|
case ext.Error:
|
||||||
|
s.setTagError(value, &errorConfig{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v, ok := value.(bool); ok {
|
||||||
|
s.setTagBool(key, v)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v, ok := value.(string); ok {
|
if v, ok := value.(string); ok {
|
||||||
|
@ -99,7 +113,7 @@ func (s *span) SetTag(key string, value interface{}) {
|
||||||
|
|
||||||
// setTagError sets the error tag. It accounts for various valid scenarios.
|
// setTagError sets the error tag. It accounts for various valid scenarios.
|
||||||
// This method is not safe for concurrent use.
|
// This method is not safe for concurrent use.
|
||||||
func (s *span) setTagError(value interface{}, debugStack bool) {
|
func (s *span) setTagError(value interface{}, cfg *errorConfig) {
|
||||||
if s.finished {
|
if s.finished {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -117,8 +131,12 @@ func (s *span) setTagError(value interface{}, debugStack bool) {
|
||||||
s.Error = 1
|
s.Error = 1
|
||||||
s.Meta[ext.ErrorMsg] = v.Error()
|
s.Meta[ext.ErrorMsg] = v.Error()
|
||||||
s.Meta[ext.ErrorType] = reflect.TypeOf(v).String()
|
s.Meta[ext.ErrorType] = reflect.TypeOf(v).String()
|
||||||
if debugStack {
|
if !cfg.noDebugStack {
|
||||||
|
if cfg.stackFrames == 0 {
|
||||||
s.Meta[ext.ErrorStack] = string(debug.Stack())
|
s.Meta[ext.ErrorStack] = string(debug.Stack())
|
||||||
|
} else {
|
||||||
|
s.Meta[ext.ErrorStack] = takeStacktrace(cfg.stackFrames, cfg.stackSkip)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case nil:
|
case nil:
|
||||||
// no error
|
// no error
|
||||||
|
@ -130,9 +148,40 @@ func (s *span) setTagError(value interface{}, debugStack bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// takeStacktrace takes stacktrace
|
||||||
|
func takeStacktrace(n, skip uint) string {
|
||||||
|
var builder strings.Builder
|
||||||
|
pcs := make([]uintptr, n)
|
||||||
|
|
||||||
|
// +2 to exclude runtime.Callers and takeStacktrace
|
||||||
|
numFrames := runtime.Callers(2+int(skip), pcs)
|
||||||
|
if numFrames == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
frames := runtime.CallersFrames(pcs[:numFrames])
|
||||||
|
for i := 0; ; i++ {
|
||||||
|
frame, more := frames.Next()
|
||||||
|
if i != 0 {
|
||||||
|
builder.WriteByte('\n')
|
||||||
|
}
|
||||||
|
builder.WriteString(frame.Function)
|
||||||
|
builder.WriteByte('\n')
|
||||||
|
builder.WriteByte('\t')
|
||||||
|
builder.WriteString(frame.File)
|
||||||
|
builder.WriteByte(':')
|
||||||
|
builder.WriteString(strconv.Itoa(frame.Line))
|
||||||
|
if !more {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
// setTagString sets a string tag. This method is not safe for concurrent use.
|
// setTagString sets a string tag. This method is not safe for concurrent use.
|
||||||
func (s *span) setTagString(key, v string) {
|
func (s *span) setTagString(key, v string) {
|
||||||
switch key {
|
switch key {
|
||||||
|
case ext.SpanName:
|
||||||
|
s.Name = v
|
||||||
case ext.ServiceName:
|
case ext.ServiceName:
|
||||||
s.Service = v
|
s.Service = v
|
||||||
case ext.ResourceName:
|
case ext.ResourceName:
|
||||||
|
@ -144,13 +193,39 @@ func (s *span) setTagString(key, v string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setTagBool sets a boolean tag on the span.
|
||||||
|
func (s *span) setTagBool(key string, v bool) {
|
||||||
|
switch key {
|
||||||
|
case ext.AnalyticsEvent:
|
||||||
|
if v {
|
||||||
|
s.setTagNumeric(ext.EventSampleRate, 1.0)
|
||||||
|
} else {
|
||||||
|
s.setTagNumeric(ext.EventSampleRate, 0.0)
|
||||||
|
}
|
||||||
|
case ext.ManualDrop:
|
||||||
|
if v {
|
||||||
|
s.setTagNumeric(ext.SamplingPriority, ext.PriorityUserReject)
|
||||||
|
}
|
||||||
|
case ext.ManualKeep:
|
||||||
|
if v {
|
||||||
|
s.setTagNumeric(ext.SamplingPriority, ext.PriorityUserKeep)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if v {
|
||||||
|
s.setTagString(key, "true")
|
||||||
|
} else {
|
||||||
|
s.setTagString(key, "false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setTagNumeric sets a numeric tag, in our case called a metric. This method
|
// setTagNumeric sets a numeric tag, in our case called a metric. This method
|
||||||
// is not safe for concurrent use.
|
// is not safe for concurrent use.
|
||||||
func (s *span) setTagNumeric(key string, v float64) {
|
func (s *span) setTagNumeric(key string, v float64) {
|
||||||
switch key {
|
switch key {
|
||||||
case ext.SamplingPriority:
|
case ext.SamplingPriority:
|
||||||
// setting sampling priority per spec
|
// setting sampling priority per spec
|
||||||
s.Metrics[samplingPriorityKey] = v
|
s.Metrics[keySamplingPriority] = v
|
||||||
s.context.setSamplingPriority(int(v))
|
s.context.setSamplingPriority(int(v))
|
||||||
default:
|
default:
|
||||||
s.Metrics[key] = v
|
s.Metrics[key] = v
|
||||||
|
@ -172,7 +247,11 @@ func (s *span) Finish(opts ...ddtrace.FinishOption) {
|
||||||
}
|
}
|
||||||
if cfg.Error != nil {
|
if cfg.Error != nil {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
s.setTagError(cfg.Error, !cfg.NoDebugStack)
|
s.setTagError(cfg.Error, &errorConfig{
|
||||||
|
noDebugStack: cfg.NoDebugStack,
|
||||||
|
stackFrames: cfg.StackFrames,
|
||||||
|
stackSkip: cfg.SkipStackFrames,
|
||||||
|
})
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
}
|
}
|
||||||
s.finish(t)
|
s.finish(t)
|
||||||
|
@ -236,6 +315,8 @@ func (s *span) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
samplingPriorityKey = "_sampling_priority_v1"
|
keySamplingPriority = "_sampling_priority_v1"
|
||||||
samplingPriorityRateKey = "_sampling_priority_rate_v1"
|
keySamplingPriorityRate = "_sampling_priority_rate_v1"
|
||||||
|
keyOrigin = "_dd.origin"
|
||||||
|
keyHostname = "_dd.hostname"
|
||||||
)
|
)
|
||||||
|
|
100
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go
generated
vendored
100
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go
generated
vendored
|
@ -27,8 +27,7 @@ type spanContext struct {
|
||||||
|
|
||||||
mu sync.RWMutex // guards below fields
|
mu sync.RWMutex // guards below fields
|
||||||
baggage map[string]string
|
baggage map[string]string
|
||||||
priority int
|
origin string // e.g. "synthetics"
|
||||||
hasPriority bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSpanContext creates a new SpanContext to serve as context for the given
|
// newSpanContext creates a new SpanContext to serve as context for the given
|
||||||
|
@ -42,15 +41,10 @@ func newSpanContext(span *span, parent *spanContext) *spanContext {
|
||||||
spanID: span.SpanID,
|
spanID: span.SpanID,
|
||||||
span: span,
|
span: span,
|
||||||
}
|
}
|
||||||
if v, ok := span.Metrics[samplingPriorityKey]; ok {
|
|
||||||
context.hasPriority = true
|
|
||||||
context.priority = int(v)
|
|
||||||
}
|
|
||||||
if parent != nil {
|
if parent != nil {
|
||||||
context.trace = parent.trace
|
context.trace = parent.trace
|
||||||
context.drop = parent.drop
|
context.drop = parent.drop
|
||||||
context.hasPriority = parent.hasSamplingPriority()
|
context.origin = parent.origin
|
||||||
context.priority = parent.samplingPriority()
|
|
||||||
parent.ForeachBaggageItem(func(k, v string) bool {
|
parent.ForeachBaggageItem(func(k, v string) bool {
|
||||||
context.setBaggageItem(k, v)
|
context.setBaggageItem(k, v)
|
||||||
return true
|
return true
|
||||||
|
@ -59,6 +53,10 @@ func newSpanContext(span *span, parent *spanContext) *spanContext {
|
||||||
if context.trace == nil {
|
if context.trace == nil {
|
||||||
context.trace = newTrace()
|
context.trace = newTrace()
|
||||||
}
|
}
|
||||||
|
if context.trace.root == nil {
|
||||||
|
// first span in the trace can safely be assumed to be the root
|
||||||
|
context.trace.root = span
|
||||||
|
}
|
||||||
// put span in context's trace
|
// put span in context's trace
|
||||||
context.trace.push(span)
|
context.trace.push(span)
|
||||||
return context
|
return context
|
||||||
|
@ -82,22 +80,21 @@ func (c *spanContext) ForeachBaggageItem(handler func(k, v string) bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *spanContext) setSamplingPriority(p int) {
|
func (c *spanContext) setSamplingPriority(p int) {
|
||||||
c.mu.Lock()
|
if c.trace == nil {
|
||||||
defer c.mu.Unlock()
|
c.trace = newTrace()
|
||||||
c.priority = p
|
}
|
||||||
c.hasPriority = true
|
c.trace.setSamplingPriority(float64(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *spanContext) samplingPriority() int {
|
func (c *spanContext) samplingPriority() int {
|
||||||
c.mu.RLock()
|
if c.trace == nil {
|
||||||
defer c.mu.RUnlock()
|
return 0
|
||||||
return c.priority
|
}
|
||||||
|
return c.trace.samplingPriority()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *spanContext) hasSamplingPriority() bool {
|
func (c *spanContext) hasSamplingPriority() bool {
|
||||||
c.mu.RLock()
|
return c.trace != nil && c.trace.hasSamplingPriority()
|
||||||
defer c.mu.RUnlock()
|
|
||||||
return c.hasPriority
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *spanContext) setBaggageItem(key, val string) {
|
func (c *spanContext) setBaggageItem(key, val string) {
|
||||||
|
@ -116,15 +113,23 @@ func (c *spanContext) baggageItem(key string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// finish marks this span as finished in the trace.
|
// finish marks this span as finished in the trace.
|
||||||
func (c *spanContext) finish() { c.trace.ackFinish() }
|
func (c *spanContext) finish() { c.trace.finishedOne(c.span) }
|
||||||
|
|
||||||
// trace holds information about a specific trace. This structure is shared
|
// trace contains shared context information about a trace, such as sampling
|
||||||
// between all spans in a trace.
|
// priority, the root reference and a buffer of the spans which are part of the
|
||||||
|
// trace, if these exist.
|
||||||
type trace struct {
|
type trace struct {
|
||||||
mu sync.RWMutex // guards below fields
|
mu sync.RWMutex // guards below fields
|
||||||
spans []*span // all the spans that are part of this trace
|
spans []*span // all the spans that are part of this trace
|
||||||
finished int // the number of finished spans
|
finished int // the number of finished spans
|
||||||
full bool // signifies that the span buffer is full
|
full bool // signifies that the span buffer is full
|
||||||
|
priority *float64 // sampling priority
|
||||||
|
locked bool // specifies if the sampling priority can be altered
|
||||||
|
|
||||||
|
// root specifies the root of the trace, if known; it is nil when a span
|
||||||
|
// context is extracted from a carrier, at which point there are no spans in
|
||||||
|
// the trace yet.
|
||||||
|
root *span
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -146,6 +151,42 @@ func newTrace() *trace {
|
||||||
return &trace{spans: make([]*span, 0, traceStartSize)}
|
return &trace{spans: make([]*span, 0, traceStartSize)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *trace) hasSamplingPriority() bool {
|
||||||
|
t.mu.RLock()
|
||||||
|
defer t.mu.RUnlock()
|
||||||
|
return t.priority != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *trace) samplingPriority() int {
|
||||||
|
t.mu.RLock()
|
||||||
|
defer t.mu.RUnlock()
|
||||||
|
if t.priority == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int(*t.priority)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *trace) setSamplingPriority(p float64) {
|
||||||
|
t.mu.Lock()
|
||||||
|
defer t.mu.Unlock()
|
||||||
|
t.setSamplingPriorityLocked(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *trace) setSamplingPriorityLocked(p float64) {
|
||||||
|
if t.locked {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if t.root == nil {
|
||||||
|
// this trace is distributed (no local root); modifications
|
||||||
|
// to the sampling priority are not allowed.
|
||||||
|
t.locked = true
|
||||||
|
}
|
||||||
|
if t.priority == nil {
|
||||||
|
t.priority = new(float64)
|
||||||
|
}
|
||||||
|
*t.priority = p
|
||||||
|
}
|
||||||
|
|
||||||
// push pushes a new span into the trace. If the buffer is full, it returns
|
// push pushes a new span into the trace. If the buffer is full, it returns
|
||||||
// a errBufferFull error.
|
// a errBufferFull error.
|
||||||
func (t *trace) push(sp *span) {
|
func (t *trace) push(sp *span) {
|
||||||
|
@ -164,12 +205,16 @@ func (t *trace) push(sp *span) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if v, ok := sp.Metrics[keySamplingPriority]; ok {
|
||||||
|
t.setSamplingPriorityLocked(v)
|
||||||
|
}
|
||||||
t.spans = append(t.spans, sp)
|
t.spans = append(t.spans, sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ackFinish aknowledges that another span in the trace has finished, and checks
|
// finishedOne aknowledges that another span in the trace has finished, and checks
|
||||||
// if the trace is complete, in which case it calls the onFinish function.
|
// if the trace is complete, in which case it calls the onFinish function. It uses
|
||||||
func (t *trace) ackFinish() {
|
// the given priority, if non-nil, to mark the root span.
|
||||||
|
func (t *trace) finishedOne(s *span) {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
defer t.mu.Unlock()
|
defer t.mu.Unlock()
|
||||||
if t.full {
|
if t.full {
|
||||||
|
@ -180,6 +225,13 @@ func (t *trace) ackFinish() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.finished++
|
t.finished++
|
||||||
|
if s == t.root && t.priority != nil {
|
||||||
|
// after the root has finished we lock down the priority;
|
||||||
|
// we won't be able to make changes to a span after finishing
|
||||||
|
// without causing a race condition.
|
||||||
|
t.root.Metrics[keySamplingPriority] = *t.priority
|
||||||
|
t.locked = true
|
||||||
|
}
|
||||||
if len(t.spans) != t.finished {
|
if len(t.spans) != t.finished {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
180
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go
generated
vendored
180
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go
generated
vendored
|
@ -2,10 +2,12 @@ package tracer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
|
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
|
||||||
|
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPHeadersCarrier wraps an http.Header as a TextMapWriter and TextMapReader, allowing
|
// HTTPHeadersCarrier wraps an http.Header as a TextMapWriter and TextMapReader, allowing
|
||||||
|
@ -54,6 +56,11 @@ func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
headerPropagationStyleInject = "DD_PROPAGATION_STYLE_INJECT"
|
||||||
|
headerPropagationStyleExtract = "DD_PROPAGATION_STYLE_EXTRACT"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultBaggageHeaderPrefix specifies the prefix that will be used in
|
// DefaultBaggageHeaderPrefix specifies the prefix that will be used in
|
||||||
// HTTP headers or text maps to prefix baggage keys.
|
// HTTP headers or text maps to prefix baggage keys.
|
||||||
|
@ -72,6 +79,10 @@ const (
|
||||||
DefaultPriorityHeader = "x-datadog-sampling-priority"
|
DefaultPriorityHeader = "x-datadog-sampling-priority"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// originHeader specifies the name of the header indicating the origin of the trace.
|
||||||
|
// It is used with the Synthetics product and usually has the value "synthetics".
|
||||||
|
const originHeader = "x-datadog-origin"
|
||||||
|
|
||||||
// PropagatorConfig defines the configuration for initializing a propagator.
|
// PropagatorConfig defines the configuration for initializing a propagator.
|
||||||
type PropagatorConfig struct {
|
type PropagatorConfig struct {
|
||||||
// BaggagePrefix specifies the prefix that will be used to store baggage
|
// BaggagePrefix specifies the prefix that will be used to store baggage
|
||||||
|
@ -110,21 +121,86 @@ func NewPropagator(cfg *PropagatorConfig) Propagator {
|
||||||
if cfg.PriorityHeader == "" {
|
if cfg.PriorityHeader == "" {
|
||||||
cfg.PriorityHeader = DefaultPriorityHeader
|
cfg.PriorityHeader = DefaultPriorityHeader
|
||||||
}
|
}
|
||||||
return &propagator{cfg}
|
return &chainedPropagator{
|
||||||
|
injectors: getPropagators(cfg, headerPropagationStyleInject),
|
||||||
|
extractors: getPropagators(cfg, headerPropagationStyleExtract),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// propagator implements a propagator which uses TextMap internally.
|
// chainedPropagator implements Propagator and applies a list of injectors and extractors.
|
||||||
// It propagates the trace and span IDs, as well as the baggage from the
|
// When injecting, all injectors are called to propagate the span context.
|
||||||
// context.
|
// When extracting, it tries each extractor, selecting the first successful one.
|
||||||
type propagator struct{ cfg *PropagatorConfig }
|
type chainedPropagator struct {
|
||||||
|
injectors []Propagator
|
||||||
|
extractors []Propagator
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPropagators returns a list of propagators based on the list found in the
|
||||||
|
// given environment variable. If the list doesn't contain a value or has invalid
|
||||||
|
// values, the default propagator will be returned.
|
||||||
|
func getPropagators(cfg *PropagatorConfig, env string) []Propagator {
|
||||||
|
dd := &propagator{cfg}
|
||||||
|
ps := os.Getenv(env)
|
||||||
|
if ps == "" {
|
||||||
|
return []Propagator{dd}
|
||||||
|
}
|
||||||
|
var list []Propagator
|
||||||
|
for _, v := range strings.Split(ps, ",") {
|
||||||
|
switch strings.ToLower(v) {
|
||||||
|
case "datadog":
|
||||||
|
list = append(list, dd)
|
||||||
|
case "b3":
|
||||||
|
list = append(list, &propagatorB3{})
|
||||||
|
default:
|
||||||
|
// TODO(cgilmour): consider logging something for invalid/unknown styles.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(list) == 0 {
|
||||||
|
// return the default
|
||||||
|
return []Propagator{dd}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
// Inject defines the Propagator to propagate SpanContext data
|
// Inject defines the Propagator to propagate SpanContext data
|
||||||
// out of the current process. The implementation propagates the
|
// out of the current process. The implementation propagates the
|
||||||
// TraceID and the current active SpanID, as well as the Span baggage.
|
// TraceID and the current active SpanID, as well as the Span baggage.
|
||||||
|
func (p *chainedPropagator) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error {
|
||||||
|
for _, v := range p.injectors {
|
||||||
|
err := v.Inject(spanCtx, carrier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract implements Propagator.
|
||||||
|
func (p *chainedPropagator) Extract(carrier interface{}) (ddtrace.SpanContext, error) {
|
||||||
|
for _, v := range p.extractors {
|
||||||
|
ctx, err := v.Extract(carrier)
|
||||||
|
if ctx != nil {
|
||||||
|
// first extractor returns
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
if err == ErrSpanContextNotFound {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, ErrSpanContextNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// propagator implements Propagator and injects/extracts span contexts
|
||||||
|
// using datadog headers. Only TextMap carriers are supported.
|
||||||
|
type propagator struct {
|
||||||
|
cfg *PropagatorConfig
|
||||||
|
}
|
||||||
|
|
||||||
func (p *propagator) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error {
|
func (p *propagator) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error {
|
||||||
switch v := carrier.(type) {
|
switch c := carrier.(type) {
|
||||||
case TextMapWriter:
|
case TextMapWriter:
|
||||||
return p.injectTextMap(spanCtx, v)
|
return p.injectTextMap(spanCtx, c)
|
||||||
default:
|
default:
|
||||||
return ErrInvalidCarrier
|
return ErrInvalidCarrier
|
||||||
}
|
}
|
||||||
|
@ -141,6 +217,9 @@ func (p *propagator) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWr
|
||||||
if ctx.hasSamplingPriority() {
|
if ctx.hasSamplingPriority() {
|
||||||
writer.Set(p.cfg.PriorityHeader, strconv.Itoa(ctx.samplingPriority()))
|
writer.Set(p.cfg.PriorityHeader, strconv.Itoa(ctx.samplingPriority()))
|
||||||
}
|
}
|
||||||
|
if ctx.origin != "" {
|
||||||
|
writer.Set(originHeader, ctx.origin)
|
||||||
|
}
|
||||||
// propagate OpenTracing baggage
|
// propagate OpenTracing baggage
|
||||||
for k, v := range ctx.baggage {
|
for k, v := range ctx.baggage {
|
||||||
writer.Set(p.cfg.BaggagePrefix+k, v)
|
writer.Set(p.cfg.BaggagePrefix+k, v)
|
||||||
|
@ -148,11 +227,10 @@ func (p *propagator) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract implements Propagator.
|
|
||||||
func (p *propagator) Extract(carrier interface{}) (ddtrace.SpanContext, error) {
|
func (p *propagator) Extract(carrier interface{}) (ddtrace.SpanContext, error) {
|
||||||
switch v := carrier.(type) {
|
switch c := carrier.(type) {
|
||||||
case TextMapReader:
|
case TextMapReader:
|
||||||
return p.extractTextMap(v)
|
return p.extractTextMap(c)
|
||||||
default:
|
default:
|
||||||
return nil, ErrInvalidCarrier
|
return nil, ErrInvalidCarrier
|
||||||
}
|
}
|
||||||
|
@ -180,6 +258,8 @@ func (p *propagator) extractTextMap(reader TextMapReader) (ddtrace.SpanContext,
|
||||||
return ErrSpanContextCorrupted
|
return ErrSpanContextCorrupted
|
||||||
}
|
}
|
||||||
ctx.setSamplingPriority(priority)
|
ctx.setSamplingPriority(priority)
|
||||||
|
case originHeader:
|
||||||
|
ctx.origin = v
|
||||||
default:
|
default:
|
||||||
if strings.HasPrefix(key, p.cfg.BaggagePrefix) {
|
if strings.HasPrefix(key, p.cfg.BaggagePrefix) {
|
||||||
ctx.setBaggageItem(strings.TrimPrefix(key, p.cfg.BaggagePrefix), v)
|
ctx.setBaggageItem(strings.TrimPrefix(key, p.cfg.BaggagePrefix), v)
|
||||||
|
@ -195,3 +275,83 @@ func (p *propagator) extractTextMap(reader TextMapReader) (ddtrace.SpanContext,
|
||||||
}
|
}
|
||||||
return &ctx, nil
|
return &ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
b3TraceIDHeader = "x-b3-traceid"
|
||||||
|
b3SpanIDHeader = "x-b3-spanid"
|
||||||
|
b3SampledHeader = "x-b3-sampled"
|
||||||
|
)
|
||||||
|
|
||||||
|
// propagatorB3 implements Propagator and injects/extracts span contexts
|
||||||
|
// using B3 headers. Only TextMap carriers are supported.
|
||||||
|
type propagatorB3 struct{}
|
||||||
|
|
||||||
|
func (p *propagatorB3) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error {
|
||||||
|
switch c := carrier.(type) {
|
||||||
|
case TextMapWriter:
|
||||||
|
return p.injectTextMap(spanCtx, c)
|
||||||
|
default:
|
||||||
|
return ErrInvalidCarrier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*propagatorB3) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWriter) error {
|
||||||
|
ctx, ok := spanCtx.(*spanContext)
|
||||||
|
if !ok || ctx.traceID == 0 || ctx.spanID == 0 {
|
||||||
|
return ErrInvalidSpanContext
|
||||||
|
}
|
||||||
|
writer.Set(b3TraceIDHeader, strconv.FormatUint(ctx.traceID, 16))
|
||||||
|
writer.Set(b3SpanIDHeader, strconv.FormatUint(ctx.spanID, 16))
|
||||||
|
if ctx.hasSamplingPriority() {
|
||||||
|
if ctx.samplingPriority() >= ext.PriorityAutoKeep {
|
||||||
|
writer.Set(b3SampledHeader, "1")
|
||||||
|
} else {
|
||||||
|
writer.Set(b3SampledHeader, "0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *propagatorB3) Extract(carrier interface{}) (ddtrace.SpanContext, error) {
|
||||||
|
switch c := carrier.(type) {
|
||||||
|
case TextMapReader:
|
||||||
|
return p.extractTextMap(c)
|
||||||
|
default:
|
||||||
|
return nil, ErrInvalidCarrier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*propagatorB3) extractTextMap(reader TextMapReader) (ddtrace.SpanContext, error) {
|
||||||
|
var ctx spanContext
|
||||||
|
err := reader.ForeachKey(func(k, v string) error {
|
||||||
|
var err error
|
||||||
|
key := strings.ToLower(k)
|
||||||
|
switch key {
|
||||||
|
case b3TraceIDHeader:
|
||||||
|
ctx.traceID, err = strconv.ParseUint(v, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ErrSpanContextCorrupted
|
||||||
|
}
|
||||||
|
case b3SpanIDHeader:
|
||||||
|
ctx.spanID, err = strconv.ParseUint(v, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ErrSpanContextCorrupted
|
||||||
|
}
|
||||||
|
case b3SampledHeader:
|
||||||
|
priority, err := strconv.Atoi(v)
|
||||||
|
if err != nil {
|
||||||
|
return ErrSpanContextCorrupted
|
||||||
|
}
|
||||||
|
ctx.setSamplingPriority(priority)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if ctx.traceID == 0 || ctx.spanID == 0 {
|
||||||
|
return nil, ErrSpanContextNotFound
|
||||||
|
}
|
||||||
|
return &ctx, nil
|
||||||
|
}
|
||||||
|
|
25
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go
generated
vendored
25
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go
generated
vendored
|
@ -44,6 +44,8 @@ type tracer struct {
|
||||||
|
|
||||||
// prioritySampling holds an instance of the priority sampler.
|
// prioritySampling holds an instance of the priority sampler.
|
||||||
prioritySampling *prioritySampler
|
prioritySampling *prioritySampler
|
||||||
|
// pid of the process
|
||||||
|
pid string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -131,6 +133,7 @@ func newTracer(opts ...StartOption) *tracer {
|
||||||
errorBuffer: make(chan error, errorBufferSize),
|
errorBuffer: make(chan error, errorBufferSize),
|
||||||
stopped: make(chan struct{}),
|
stopped: make(chan struct{}),
|
||||||
prioritySampling: newPrioritySampler(),
|
prioritySampling: newPrioritySampler(),
|
||||||
|
pid: strconv.Itoa(os.Getpid()),
|
||||||
}
|
}
|
||||||
|
|
||||||
go t.worker()
|
go t.worker()
|
||||||
|
@ -230,7 +233,10 @@ func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOpt
|
||||||
context = ctx
|
context = ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id := random.Uint64()
|
id := opts.SpanID
|
||||||
|
if id == 0 {
|
||||||
|
id = random.Uint64()
|
||||||
|
}
|
||||||
// span defaults
|
// span defaults
|
||||||
span := &span{
|
span := &span{
|
||||||
Name: operationName,
|
Name: operationName,
|
||||||
|
@ -248,19 +254,28 @@ func (t *tracer) StartSpan(operationName string, options ...ddtrace.StartSpanOpt
|
||||||
span.TraceID = context.traceID
|
span.TraceID = context.traceID
|
||||||
span.ParentID = context.spanID
|
span.ParentID = context.spanID
|
||||||
if context.hasSamplingPriority() {
|
if context.hasSamplingPriority() {
|
||||||
span.Metrics[samplingPriorityKey] = float64(context.samplingPriority())
|
span.Metrics[keySamplingPriority] = float64(context.samplingPriority())
|
||||||
}
|
}
|
||||||
if context.span != nil {
|
if context.span != nil {
|
||||||
// it has a local parent, inherit the service
|
// local parent, inherit service
|
||||||
context.span.RLock()
|
context.span.RLock()
|
||||||
span.Service = context.span.Service
|
span.Service = context.span.Service
|
||||||
context.span.RUnlock()
|
context.span.RUnlock()
|
||||||
|
} else {
|
||||||
|
// remote parent
|
||||||
|
if context.origin != "" {
|
||||||
|
// mark origin
|
||||||
|
span.Meta[keyOrigin] = context.origin
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span.context = newSpanContext(span, context)
|
span.context = newSpanContext(span, context)
|
||||||
if context == nil || context.span == nil {
|
if context == nil || context.span == nil {
|
||||||
// this is either a root span or it has a remote parent, we should add the PID.
|
// this is either a root span or it has a remote parent, we should add the PID.
|
||||||
span.SetTag(ext.Pid, strconv.Itoa(os.Getpid()))
|
span.SetTag(ext.Pid, t.pid)
|
||||||
|
if t.hostname != "" {
|
||||||
|
span.SetTag(keyHostname, t.hostname)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// add tags from options
|
// add tags from options
|
||||||
for k, v := range opts.Tags {
|
for k, v := range opts.Tags {
|
||||||
|
@ -361,7 +376,7 @@ const sampleRateMetricKey = "_sample_rate"
|
||||||
|
|
||||||
// Sample samples a span with the internal sampler.
|
// Sample samples a span with the internal sampler.
|
||||||
func (t *tracer) sample(span *span) {
|
func (t *tracer) sample(span *span) {
|
||||||
if span.context.hasPriority {
|
if span.context.hasSamplingPriority() {
|
||||||
// sampling decision was already made
|
// sampling decision was already made
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
2
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go
generated
vendored
2
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go
generated
vendored
|
@ -15,7 +15,7 @@ import (
|
||||||
var (
|
var (
|
||||||
// TODO(gbbr): find a more effective way to keep this up to date,
|
// TODO(gbbr): find a more effective way to keep this up to date,
|
||||||
// e.g. via `go generate`
|
// e.g. via `go generate`
|
||||||
tracerVersion = "v1.7.0"
|
tracerVersion = "v1.13.1"
|
||||||
|
|
||||||
// We copy the transport to avoid using the default one, as it might be
|
// We copy the transport to avoid using the default one, as it might be
|
||||||
// augmented with tracing and we don't want these calls to be recorded.
|
// augmented with tracing and we don't want these calls to be recorded.
|
||||||
|
|
28
vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go
generated
vendored
Normal file
28
vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Package globalconfig stores configuration which applies globally to both the tracer
|
||||||
|
// and integrations.
|
||||||
|
package globalconfig
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
var cfg = &config{}
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
analyticsRate float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnalyticsRate returns the sampling rate at which events should be marked. It uses
|
||||||
|
// synchronizing mechanisms, meaning that for optimal performance it's best to read it
|
||||||
|
// once and store it.
|
||||||
|
func AnalyticsRate() float64 {
|
||||||
|
cfg.mu.RLock()
|
||||||
|
defer cfg.mu.RUnlock()
|
||||||
|
return cfg.analyticsRate
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAnalyticsRate sets the given event sampling rate globally.
|
||||||
|
func SetAnalyticsRate(rate float64) {
|
||||||
|
cfg.mu.Lock()
|
||||||
|
cfg.analyticsRate = rate
|
||||||
|
cfg.mu.Unlock()
|
||||||
|
}
|
Loading…
Reference in a new issue