forked from DataDog/dd-trace-go
/
tracer.go
81 lines (73 loc) · 3.11 KB
/
tracer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Package opentracer provides a wrapper on top of the Datadog tracer that can be used with Opentracing.
// It also provides a set of opentracing.StartSpanOption that are specific to Datadog's APM product.
// To use it, simply call "New".
//
// Note that there are currently some small incompatibilities between the Opentracing spec and the Datadog
// APM product, which we are in the process of addressing on the long term. When using Datadog, the
// Opentracing operation name is what is called resource in Datadog's terms and the Opentracing "component"
// tag is Datadog's operation name. Meaning that in order to define (in Opentracing terms) a span that
// has the operation name "/user/profile" and the component "http.request", one would do:
// opentracing.StartSpan("http.request", opentracer.ResourceName("/user/profile"))
//
// Some libraries and frameworks are supported out-of-the-box by using our integrations. You can see a list
// of supported integrations here: https://godoc.org/gopkg.in/DataDog/dd-trace-go.v1/contrib. They are fully
// compatible with the Opentracing implementation.
package opentracer
import (
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/internal"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
opentracing "github.com/opentracing/opentracing-go"
)
// New creates, instantiates and returns an Opentracing compatible version of the
// Datadog tracer using the provided set of options.
func New(opts ...tracer.StartOption) opentracing.Tracer {
tracer.Start(opts...)
return &opentracer{internal.GetGlobalTracer()}
}
var _ opentracing.Tracer = (*opentracer)(nil)
// opentracer implements opentracing.Tracer on top of ddtrace.Tracer.
type opentracer struct{ ddtrace.Tracer }
// StartSpan implements opentracing.Tracer.
func (t *opentracer) StartSpan(operationName string, options ...opentracing.StartSpanOption) opentracing.Span {
var sso opentracing.StartSpanOptions
for _, o := range options {
o.Apply(&sso)
}
opts := []ddtrace.StartSpanOption{tracer.StartTime(sso.StartTime)}
for _, ref := range sso.References {
if v, ok := ref.ReferencedContext.(ddtrace.SpanContext); ok && ref.Type == opentracing.ChildOfRef {
opts = append(opts, tracer.ChildOf(v))
break // can only have one parent
}
}
for k, v := range sso.Tags {
opts = append(opts, tracer.Tag(k, v))
}
return &span{
Span: t.Tracer.StartSpan(operationName, opts...),
opentracer: t,
}
}
// Inject implements opentracing.Tracer.
func (t *opentracer) Inject(ctx opentracing.SpanContext, format interface{}, carrier interface{}) error {
sctx, ok := ctx.(ddtrace.SpanContext)
if !ok {
return opentracing.ErrUnsupportedFormat
}
switch format {
case opentracing.TextMap, opentracing.HTTPHeaders:
return t.Tracer.Inject(sctx, carrier)
default:
return opentracing.ErrUnsupportedFormat
}
}
// Extract implements opentracing.Tracer.
func (t *opentracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
switch format {
case opentracing.TextMap, opentracing.HTTPHeaders:
return t.Tracer.Extract(carrier)
default:
return nil, opentracing.ErrUnsupportedFormat
}
}