...
1
2
3
4 package otelhttp
5
6 import (
7 "context"
8 "net/http"
9 "net/http/httptrace"
10
11 "go.opentelemetry.io/otel"
12 "go.opentelemetry.io/otel/metric"
13 "go.opentelemetry.io/otel/propagation"
14 "go.opentelemetry.io/otel/trace"
15 )
16
17
18 const ScopeName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
19
20
21
22 type config struct {
23 ServerName string
24 Tracer trace.Tracer
25 Meter metric.Meter
26 Propagators propagation.TextMapPropagator
27 SpanStartOptions []trace.SpanStartOption
28 PublicEndpoint bool
29 PublicEndpointFn func(*http.Request) bool
30 ReadEvent bool
31 WriteEvent bool
32 Filters []Filter
33 SpanNameFormatter func(string, *http.Request) string
34 ClientTrace func(context.Context) *httptrace.ClientTrace
35
36 TracerProvider trace.TracerProvider
37 MeterProvider metric.MeterProvider
38 }
39
40
41 type Option interface {
42 apply(*config)
43 }
44
45 type optionFunc func(*config)
46
47 func (o optionFunc) apply(c *config) {
48 o(c)
49 }
50
51
52 func newConfig(opts ...Option) *config {
53 c := &config{
54 Propagators: otel.GetTextMapPropagator(),
55 MeterProvider: otel.GetMeterProvider(),
56 }
57 for _, opt := range opts {
58 opt.apply(c)
59 }
60
61
62 if c.TracerProvider != nil {
63 c.Tracer = newTracer(c.TracerProvider)
64 }
65
66 c.Meter = c.MeterProvider.Meter(
67 ScopeName,
68 metric.WithInstrumentationVersion(Version()),
69 )
70
71 return c
72 }
73
74
75
76 func WithTracerProvider(provider trace.TracerProvider) Option {
77 return optionFunc(func(cfg *config) {
78 if provider != nil {
79 cfg.TracerProvider = provider
80 }
81 })
82 }
83
84
85
86 func WithMeterProvider(provider metric.MeterProvider) Option {
87 return optionFunc(func(cfg *config) {
88 if provider != nil {
89 cfg.MeterProvider = provider
90 }
91 })
92 }
93
94
95
96
97 func WithPublicEndpoint() Option {
98 return optionFunc(func(c *config) {
99 c.PublicEndpoint = true
100 })
101 }
102
103
104
105
106
107
108 func WithPublicEndpointFn(fn func(*http.Request) bool) Option {
109 return optionFunc(func(c *config) {
110 c.PublicEndpointFn = fn
111 })
112 }
113
114
115
116 func WithPropagators(ps propagation.TextMapPropagator) Option {
117 return optionFunc(func(c *config) {
118 if ps != nil {
119 c.Propagators = ps
120 }
121 })
122 }
123
124
125
126 func WithSpanOptions(opts ...trace.SpanStartOption) Option {
127 return optionFunc(func(c *config) {
128 c.SpanStartOptions = append(c.SpanStartOptions, opts...)
129 })
130 }
131
132
133
134
135
136
137
138 func WithFilter(f Filter) Option {
139 return optionFunc(func(c *config) {
140 c.Filters = append(c.Filters, f)
141 })
142 }
143
144 type event int
145
146
147 const (
148 ReadEvents event = iota
149 WriteEvents
150 )
151
152
153
154
155
156
157
158
159
160
161 func WithMessageEvents(events ...event) Option {
162 return optionFunc(func(c *config) {
163 for _, e := range events {
164 switch e {
165 case ReadEvents:
166 c.ReadEvent = true
167 case WriteEvents:
168 c.WriteEvent = true
169 }
170 }
171 })
172 }
173
174
175
176 func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option {
177 return optionFunc(func(c *config) {
178 c.SpanNameFormatter = f
179 })
180 }
181
182
183
184 func WithClientTrace(f func(context.Context) *httptrace.ClientTrace) Option {
185 return optionFunc(func(c *config) {
186 c.ClientTrace = f
187 })
188 }
189
190
191
192 func WithServerName(server string) Option {
193 return optionFunc(func(c *config) {
194 c.ServerName = server
195 })
196 }
197
View as plain text