Added integration support for DataDog APM Tracing
This commit is contained in:
parent
ba8c9295ac
commit
3192307d59
61 changed files with 9999 additions and 5 deletions
198
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go
generated
vendored
Normal file
198
vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go
generated
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
package tracer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
|
||||
)
|
||||
|
||||
// HTTPHeadersCarrier wraps an http.Header as a TextMapWriter and TextMapReader, allowing
|
||||
// it to be used using the provided Propagator implementation.
|
||||
type HTTPHeadersCarrier http.Header
|
||||
|
||||
var _ TextMapWriter = (*HTTPHeadersCarrier)(nil)
|
||||
var _ TextMapReader = (*HTTPHeadersCarrier)(nil)
|
||||
|
||||
// Set implements TextMapWriter.
|
||||
func (c HTTPHeadersCarrier) Set(key, val string) {
|
||||
h := http.Header(c)
|
||||
h.Add(key, val)
|
||||
}
|
||||
|
||||
// ForeachKey implements TextMapReader.
|
||||
func (c HTTPHeadersCarrier) ForeachKey(handler func(key, val string) error) error {
|
||||
for k, vals := range c {
|
||||
for _, v := range vals {
|
||||
if err := handler(k, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TextMapCarrier allows the use of a regular map[string]string as both TextMapWriter
|
||||
// and TextMapReader, making it compatible with the provided Propagator.
|
||||
type TextMapCarrier map[string]string
|
||||
|
||||
var _ TextMapWriter = (*TextMapCarrier)(nil)
|
||||
var _ TextMapReader = (*TextMapCarrier)(nil)
|
||||
|
||||
// Set implements TextMapWriter.
|
||||
func (c TextMapCarrier) Set(key, val string) {
|
||||
c[key] = val
|
||||
}
|
||||
|
||||
// ForeachKey conforms to the TextMapReader interface.
|
||||
func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error {
|
||||
for k, v := range c {
|
||||
if err := handler(k, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
// DefaultBaggageHeaderPrefix specifies the prefix that will be used in
|
||||
// HTTP headers or text maps to prefix baggage keys.
|
||||
DefaultBaggageHeaderPrefix = "ot-baggage-"
|
||||
|
||||
// DefaultTraceIDHeader specifies the key that will be used in HTTP headers
|
||||
// or text maps to store the trace ID.
|
||||
DefaultTraceIDHeader = "x-datadog-trace-id"
|
||||
|
||||
// DefaultParentIDHeader specifies the key that will be used in HTTP headers
|
||||
// or text maps to store the parent ID.
|
||||
DefaultParentIDHeader = "x-datadog-parent-id"
|
||||
|
||||
// DefaultPriorityHeader specifies the key that will be used in HTTP headers
|
||||
// or text maps to store the sampling priority value.
|
||||
DefaultPriorityHeader = "x-datadog-sampling-priority"
|
||||
)
|
||||
|
||||
// PropagatorConfig defines the configuration for initializing a propagator.
|
||||
type PropagatorConfig struct {
|
||||
// BaggagePrefix specifies the prefix that will be used to store baggage
|
||||
// items in a map. It defaults to DefaultBaggageHeaderPrefix.
|
||||
BaggagePrefix string
|
||||
|
||||
// TraceHeader specifies the map key that will be used to store the trace ID.
|
||||
// It defaults to DefaultTraceIDHeader.
|
||||
TraceHeader string
|
||||
|
||||
// ParentHeader specifies the map key that will be used to store the parent ID.
|
||||
// It defaults to DefaultParentIDHeader.
|
||||
ParentHeader string
|
||||
|
||||
// PriorityHeader specifies the map key that will be used to store the sampling priority.
|
||||
// It deafults to DefaultPriorityHeader.
|
||||
PriorityHeader string
|
||||
}
|
||||
|
||||
// NewPropagator returns a new propagator which uses TextMap to inject
|
||||
// and extract values. It propagates trace and span IDs and baggage.
|
||||
// To use the defaults, nil may be provided in place of the config.
|
||||
func NewPropagator(cfg *PropagatorConfig) Propagator {
|
||||
if cfg == nil {
|
||||
cfg = new(PropagatorConfig)
|
||||
}
|
||||
if cfg.BaggagePrefix == "" {
|
||||
cfg.BaggagePrefix = DefaultBaggageHeaderPrefix
|
||||
}
|
||||
if cfg.TraceHeader == "" {
|
||||
cfg.TraceHeader = DefaultTraceIDHeader
|
||||
}
|
||||
if cfg.ParentHeader == "" {
|
||||
cfg.ParentHeader = DefaultParentIDHeader
|
||||
}
|
||||
if cfg.PriorityHeader == "" {
|
||||
cfg.PriorityHeader = DefaultPriorityHeader
|
||||
}
|
||||
return &propagator{cfg}
|
||||
}
|
||||
|
||||
// propagator implements a propagator which uses TextMap internally.
|
||||
// It propagates the trace and span IDs, as well as the baggage from the
|
||||
// context.
|
||||
type propagator struct{ cfg *PropagatorConfig }
|
||||
|
||||
// Inject defines the Propagator to propagate SpanContext data
|
||||
// out of the current process. The implementation propagates the
|
||||
// TraceID and the current active SpanID, as well as the Span baggage.
|
||||
func (p *propagator) Inject(spanCtx ddtrace.SpanContext, carrier interface{}) error {
|
||||
switch v := carrier.(type) {
|
||||
case TextMapWriter:
|
||||
return p.injectTextMap(spanCtx, v)
|
||||
default:
|
||||
return ErrInvalidCarrier
|
||||
}
|
||||
}
|
||||
|
||||
func (p *propagator) injectTextMap(spanCtx ddtrace.SpanContext, writer TextMapWriter) error {
|
||||
ctx, ok := spanCtx.(*spanContext)
|
||||
if !ok || ctx.traceID == 0 || ctx.spanID == 0 {
|
||||
return ErrInvalidSpanContext
|
||||
}
|
||||
// propagate the TraceID and the current active SpanID
|
||||
writer.Set(p.cfg.TraceHeader, strconv.FormatUint(ctx.traceID, 10))
|
||||
writer.Set(p.cfg.ParentHeader, strconv.FormatUint(ctx.spanID, 10))
|
||||
if ctx.hasSamplingPriority() {
|
||||
writer.Set(p.cfg.PriorityHeader, strconv.Itoa(ctx.samplingPriority()))
|
||||
}
|
||||
// propagate OpenTracing baggage
|
||||
for k, v := range ctx.baggage {
|
||||
writer.Set(p.cfg.BaggagePrefix+k, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Extract implements Propagator.
|
||||
func (p *propagator) Extract(carrier interface{}) (ddtrace.SpanContext, error) {
|
||||
switch v := carrier.(type) {
|
||||
case TextMapReader:
|
||||
return p.extractTextMap(v)
|
||||
default:
|
||||
return nil, ErrInvalidCarrier
|
||||
}
|
||||
}
|
||||
|
||||
func (p *propagator) 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 p.cfg.TraceHeader:
|
||||
ctx.traceID, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return ErrSpanContextCorrupted
|
||||
}
|
||||
case p.cfg.ParentHeader:
|
||||
ctx.spanID, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return ErrSpanContextCorrupted
|
||||
}
|
||||
case p.cfg.PriorityHeader:
|
||||
ctx.priority, err = strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return ErrSpanContextCorrupted
|
||||
}
|
||||
ctx.hasPriority = true
|
||||
default:
|
||||
if strings.HasPrefix(key, p.cfg.BaggagePrefix) {
|
||||
ctx.setBaggageItem(strings.TrimPrefix(key, p.cfg.BaggagePrefix), v)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ctx.traceID == 0 || ctx.spanID == 0 {
|
||||
return nil, ErrSpanContextNotFound
|
||||
}
|
||||
return &ctx, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue