Skip to content

Commit 1e72b51

Browse files
authored
Add example test for a custom SpanProcessor (#1196)
* Add example test for a custom SpanProcessor * Use existing test framework exporter * Update example * Add fixes from upstream
1 parent b97533a commit 1e72b51

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package trace
16+
17+
import (
18+
"time"
19+
20+
export "go.opentelemetry.io/otel/sdk/export/trace"
21+
"go.opentelemetry.io/otel/sdk/export/trace/tracetest"
22+
)
23+
24+
// DurationFilter is a SpanProcessor that filters spans that have lifetimes
25+
// outside of a defined range.
26+
type DurationFilter struct {
27+
// Next is the next SpanProcessor in the chain.
28+
Next SpanProcessor
29+
30+
// Min is the duration under which spans are dropped.
31+
Min time.Duration
32+
// Max is the duration over which spans are dropped.
33+
Max time.Duration
34+
}
35+
36+
func (f DurationFilter) OnStart(sd *export.SpanData) { f.Next.OnStart(sd) }
37+
func (f DurationFilter) Shutdown() { f.Next.Shutdown() }
38+
func (f DurationFilter) ForceFlush() { f.Next.ForceFlush() }
39+
func (f DurationFilter) OnEnd(sd *export.SpanData) {
40+
if f.Min > 0 && sd.EndTime.Sub(sd.StartTime) < f.Min {
41+
// Drop short lived spans.
42+
return
43+
}
44+
if f.Max > 0 && sd.EndTime.Sub(sd.StartTime) > f.Max {
45+
// Drop long lived spans.
46+
return
47+
}
48+
f.Next.OnEnd(sd)
49+
}
50+
51+
// InstrumentationBlacklist is a SpanProcessor that drops all spans from
52+
// certain instrumentation.
53+
type InstrumentationBlacklist struct {
54+
// Next is the next SpanProcessor in the chain.
55+
Next SpanProcessor
56+
57+
// Blacklist is the set of instrumentation names for which spans will be
58+
// dropped.
59+
Blacklist map[string]bool
60+
}
61+
62+
func (f InstrumentationBlacklist) OnStart(sd *export.SpanData) { f.Next.OnStart(sd) }
63+
func (f InstrumentationBlacklist) Shutdown() { f.Next.Shutdown() }
64+
func (f InstrumentationBlacklist) ForceFlush() { f.Next.ForceFlush() }
65+
func (f InstrumentationBlacklist) OnEnd(sd *export.SpanData) {
66+
if f.Blacklist != nil && f.Blacklist[sd.InstrumentationLibrary.Name] {
67+
// Drop spans from this instrumentation
68+
return
69+
}
70+
f.Next.OnEnd(sd)
71+
}
72+
73+
func ExampleSpanProcessor() {
74+
exportSP := NewSimpleSpanProcessor(tracetest.NewNoopExporter())
75+
76+
// Build a SpanProcessor chain to filter out all spans from the pernicious
77+
// "naughty-instrumentation" dependency and only allow spans shorter than
78+
// an minute and longer than a second to be exported with the exportSP.
79+
filter := DurationFilter{
80+
Next: InstrumentationBlacklist{
81+
Next: exportSP,
82+
Blacklist: map[string]bool{
83+
"naughty-instrumentation": true,
84+
},
85+
},
86+
Min: time.Second,
87+
Max: time.Minute,
88+
}
89+
90+
_ = NewTracerProvider(WithSpanProcessor(filter))
91+
// ...
92+
}

0 commit comments

Comments
 (0)