/
option.go
180 lines (156 loc) · 5.08 KB
/
option.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016 Datadog, Inc.
package http
import (
"math"
"net/http"
"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/tracer"
"gopkg.in/DataDog/dd-trace-go.v1/internal"
"gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
)
type config struct {
serviceName string
analyticsRate float64
spanOpts []ddtrace.StartSpanOption
finishOpts []ddtrace.FinishOption
}
// MuxOption has been deprecated in favor of Option.
type MuxOption = Option
// Option represents an option that can be passed to NewServeMux or WrapHandler.
type Option func(*config)
func defaults(cfg *config) {
if internal.BoolEnv("DD_TRACE_HTTP_ANALYTICS_ENABLED", false) {
cfg.analyticsRate = 1.0
} else {
cfg.analyticsRate = globalconfig.AnalyticsRate()
}
cfg.serviceName = "http.router"
if svc := globalconfig.ServiceName(); svc != "" {
cfg.serviceName = svc
}
cfg.spanOpts = []ddtrace.StartSpanOption{tracer.Measured()}
if !math.IsNaN(cfg.analyticsRate) {
cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate))
}
}
// WithServiceName sets the given service name for the returned ServeMux.
func WithServiceName(name string) MuxOption {
return func(cfg *config) {
cfg.serviceName = name
}
}
// WithAnalytics enables Trace Analytics for all started spans.
func WithAnalytics(on bool) MuxOption {
return func(cfg *config) {
if on {
cfg.analyticsRate = 1.0
cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate))
} else {
cfg.analyticsRate = math.NaN()
}
}
}
// WithAnalyticsRate sets the sampling rate for Trace Analytics events
// correlated to started spans.
func WithAnalyticsRate(rate float64) MuxOption {
return func(cfg *config) {
if rate >= 0.0 && rate <= 1.0 {
cfg.analyticsRate = rate
cfg.spanOpts = append(cfg.spanOpts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate))
} else {
cfg.analyticsRate = math.NaN()
}
}
}
// WithSpanOptions defines a set of additional ddtrace.StartSpanOption to be added
// to spans started by the integration.
func WithSpanOptions(opts ...ddtrace.StartSpanOption) Option {
return func(cfg *config) {
cfg.spanOpts = append(cfg.spanOpts, opts...)
}
}
// NoDebugStack prevents stack traces from being attached to spans finishing
// with an error. This is useful in situations where errors are frequent and
// performance is critical.
func NoDebugStack() Option {
return func(cfg *config) {
cfg.finishOpts = append(cfg.finishOpts, tracer.NoDebugStack())
}
}
// A RoundTripperBeforeFunc can be used to modify a span before an http
// RoundTrip is made.
type RoundTripperBeforeFunc func(*http.Request, ddtrace.Span)
// A RoundTripperAfterFunc can be used to modify a span after an http
// RoundTrip is made. It is possible for the http Response to be nil.
type RoundTripperAfterFunc func(*http.Response, ddtrace.Span)
type roundTripperConfig struct {
before RoundTripperBeforeFunc
after RoundTripperAfterFunc
analyticsRate float64
serviceName string
resourceNamer func(req *http.Request) string
}
func newRoundTripperConfig() *roundTripperConfig {
return &roundTripperConfig{
analyticsRate: globalconfig.AnalyticsRate(),
resourceNamer: defaultResourceNamer,
}
}
// A RoundTripperOption represents an option that can be passed to
// WrapRoundTripper.
type RoundTripperOption func(*roundTripperConfig)
// WithBefore adds a RoundTripperBeforeFunc to the RoundTripper
// config.
func WithBefore(f RoundTripperBeforeFunc) RoundTripperOption {
return func(cfg *roundTripperConfig) {
cfg.before = f
}
}
// WithAfter adds a RoundTripperAfterFunc to the RoundTripper
// config.
func WithAfter(f RoundTripperAfterFunc) RoundTripperOption {
return func(cfg *roundTripperConfig) {
cfg.after = f
}
}
// RTWithResourceNamer specifies a function which will be used to
// obtain the resource name for a given request.
func RTWithResourceNamer(namer func(req *http.Request) string) RoundTripperOption {
return func(cfg *roundTripperConfig) {
cfg.resourceNamer = namer
}
}
func defaultResourceNamer(_ *http.Request) string {
return "http.request"
}
// RTWithServiceName sets the given service name for the RoundTripper.
func RTWithServiceName(name string) RoundTripperOption {
return func(cfg *roundTripperConfig) {
cfg.serviceName = name
}
}
// RTWithAnalytics enables Trace Analytics for all started spans.
func RTWithAnalytics(on bool) RoundTripperOption {
return func(cfg *roundTripperConfig) {
if on {
cfg.analyticsRate = 1.0
} else {
cfg.analyticsRate = math.NaN()
}
}
}
// RTWithAnalyticsRate sets the sampling rate for Trace Analytics events
// correlated to started spans.
func RTWithAnalyticsRate(rate float64) RoundTripperOption {
return func(cfg *roundTripperConfig) {
if rate >= 0.0 && rate <= 1.0 {
cfg.analyticsRate = rate
} else {
cfg.analyticsRate = math.NaN()
}
}
}