/
string_tag_filter.go
93 lines (84 loc) · 2.96 KB
/
string_tag_filter.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
// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sampling
import (
tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
"go.uber.org/zap"
)
type stringAttributeFilter struct {
key string
values map[string]struct{}
logger *zap.Logger
}
var _ PolicyEvaluator = (*stringAttributeFilter)(nil)
// NewStringAttributeFilter creates a policy evaluator that samples all traces with
// the given attribute in the given numeric range.
func NewStringAttributeFilter(logger *zap.Logger, key string, values []string) PolicyEvaluator {
valuesMap := make(map[string]struct{})
for _, value := range values {
if value != "" {
valuesMap[value] = struct{}{}
}
}
return &stringAttributeFilter{
key: key,
values: valuesMap,
logger: logger,
}
}
// OnLateArrivingSpans notifies the evaluator that the given list of spans arrived
// after the sampling decision was already taken for the trace.
// This gives the evaluator a chance to log any message/metrics and/or update any
// related internal state.
func (saf *stringAttributeFilter) OnLateArrivingSpans(earlyDecision Decision, spans []*tracepb.Span) error {
saf.logger.Debug("Triggering action for late arriving spans in string-tag filter")
return nil
}
// Evaluate looks at the trace data and returns a corresponding SamplingDecision.
func (saf *stringAttributeFilter) Evaluate(traceID []byte, trace *TraceData) (Decision, error) {
saf.logger.Debug("Evaluting spans in string-tag filter")
trace.Lock()
batches := trace.ReceivedBatches
trace.Unlock()
for _, batch := range batches {
node := batch.Node
if node != nil && node.Attributes != nil {
if v, ok := node.Attributes[saf.key]; ok {
if _, ok := saf.values[v]; ok {
return Sampled, nil
}
}
}
for _, span := range batch.Spans {
if span == nil || span.Attributes == nil {
continue
}
if v, ok := span.Attributes.AttributeMap[saf.key]; ok {
truncableStr := v.GetStringValue()
if truncableStr != nil {
if _, ok := saf.values[truncableStr.Value]; ok {
return Sampled, nil
}
}
}
}
}
return NotSampled, nil
}
// OnDroppedSpans is called when the trace needs to be dropped, due to memory
// pressure, before the decision_wait time has been reached.
func (saf *stringAttributeFilter) OnDroppedSpans(traceID []byte, trace *TraceData) (Decision, error) {
saf.logger.Debug("Triggering action for dropped spans in string-tag filter")
return NotSampled, nil
}