8000 Add the SampledFilter exemplar Reservoir impl (#4851) · open-telemetry/opentelemetry-go@79371c1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 79371c1

Browse files
MrAliaspellared
andauthored
Add the SampledFilter exemplar Reservoir impl (#4851)
This Reservoir implementaiton is used at the MeterProvider level to pre-filter measurements offered to a wrapped Reservoir. Co-authored-by: Robert Pająk <pellared@hotmail.com>
1 parent 08beb8b commit 79371c1

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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 exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
16+
17+
import (
18+
"context"
19+
"time"
20+
21+
"go.opentelemetry.io/otel/attribute"
22+
"go.opentelemetry.io/otel/trace"
23+
)
24+
25+
// SampledFilter returns a [Reservoir] wrapping r that will only offer measurements
26+
// to r if the passed context associated with the measurement contains a sampled
27+
// [go.opentelemetry.io/otel/trace.SpanContext].
28+
func SampledFilter[N int64 | float64](r Reservoir[N]) Reservoir[N] {
29+
return filtered[N]{Reservoir: r}
30+
}
31+
32+
type filtered[N int64 | float64] struct {
33+
Reservoir[N]
34+
}
35+
36+
func (f filtered[N]) Offer(ctx context.Context, t time.Time, n N, a []attribute.KeyValue) {
37+
if trace.SpanContextFromContext(ctx).IsSampled() {
38+
f.Reservoir.Offer(ctx, t, n, a)
39+
}
40+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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 exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
16+
17+
import (
18+
"context"
19+
"testing"
20+
"time"
21+
22+
"github.com/stretchr/testify/assert"
23+
24+
"go.opentelemetry.io/otel/attribute"
25+
"go.opentelemetry.io/otel/sdk/metric/metricdata"
26+
"go.opentelemetry.io/otel/trace"
27+
)
28+
29+
func TestSampledFilter(t *testing.T) {
30+
t.Run("Int64", testSampledFiltered[int64])
31+
t.Run("Float64", testSampledFiltered[float64])
32+
}
33+
34+
func testSampledFiltered[N int64 | float64](t *testing.T) {
35+
under := &res[N]{}
36+
37+
r := SampledFilter[N](under)
38+
39+
ctx := context.Background()
40+
r.Offer(ctx, staticTime, 0, nil)
41+
assert.False(t, under.OfferCalled, "underlying Reservoir Offer called")
42+
r.Offer(sample(ctx), staticTime, 0, nil)
43+
assert.True(t, under.OfferCalled, "underlying Reservoir Offer not called")
44+
45+
r.Collect(nil)
46+
assert.True(t, under.CollectCalled, "underlying Reservoir Collect not called")
47+
48+
r.Flush(nil)
49+
assert.True(t, under.FlushCalled, "underlying Reservoir Flush not called")
50+
}
51+
52+
func sample(parent context.Context) context.Context {
53+
sc := trace.NewSpanContext(trace.SpanContextConfig{
54+
TraceID: trace.TraceID{0x01},
55+
SpanID: trace.SpanID{0x01},
56+
TraceFlags: trace.FlagsSampled,
57+
})
58+
return trace.ContextWithSpanContext(parent, sc)
59+
}
60+
61+
type res[N int64 | float64] struct {
62+
OfferCalled bool
63+
CollectCalled bool
64+
FlushCalled bool
65+
}
66+
67+
func (r *res[N]) Offer(context.Context, time.Time, N, []attribute.KeyValue) {
68+
r.OfferCalled = true
69+
}
70+
71+
func (r *res[N]) Collect(*[]metricdata.Exemplar[N]) {
72+
r.CollectCalled = true
73+
}
74+
75+
func (r *res[N]) Flush(*[]metricdata.Exemplar[N]) {
76+
r.FlushCalled = true
77+
}

0 commit comments

Comments
 (0)
0