/
sampler.go
72 lines (62 loc) · 1.95 KB
/
sampler.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
package opentelemetry
import (
"net/http"
"strings"
"flamingo.me/flamingo/v3/framework/config"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/trace"
)
type ConfiguredURLPrefixSampler struct {
Allowlist config.Slice
Blocklist config.Slice
AllowParentTrace bool
}
// Inject dependencies
func (c *ConfiguredURLPrefixSampler) Inject(
cfg *struct {
Allowlist config.Slice `inject:"config:flamingo.opentelemetry.tracing.sampler.allowlist,optional"`
Blocklist config.Slice `inject:"config:flamingo.opentelemetry.tracing.sampler.blocklist,optional"`
AllowParentTrace bool `inject:"config:flamingo.opentelemetry.tracing.sampler.allowParentTrace,optional"`
},
) *ConfiguredURLPrefixSampler {
if cfg != nil {
c.Allowlist = cfg.Allowlist
c.Blocklist = cfg.Blocklist
c.AllowParentTrace = cfg.AllowParentTrace
}
return c
}
func (c *ConfiguredURLPrefixSampler) GetFilterOption() otelhttp.Filter {
var allowed, blocked []string
_ = c.Allowlist.MapInto(&allowed)
_ = c.Blocklist.MapInto(&blocked)
return URLPrefixSampler(allowed, blocked, c.AllowParentTrace)
}
func URLPrefixSampler(allowed, blocked []string, allowParentTrace bool) otelhttp.Filter {
return func(request *http.Request) bool {
path := request.URL.Path
isParentSampled := trace.SpanContextFromContext(request.Context()).IsSampled()
// empty allowed means all
sample := len(allowed) == 0
// check allowed if len is > 0, and decide if we should sample
for _, p := range allowed {
if strings.HasPrefix(path, p) {
sample = true
break
}
}
// we do not sample, unless the parent is sampled
if !sample {
return !allowParentTrace && isParentSampled
}
// check sampling decision against blocked
for _, p := range blocked {
if strings.HasPrefix(path, p) {
sample = false
break
}
}
// we sample, or the parent sampled
return (!allowParentTrace && isParentSampled) || sample
}
}