Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote sampling support - AWS X-Ray #1859

Merged
merged 53 commits into from Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
5d26be1
added dependabot for sampler module and util dir
bhautikpip Feb 22, 2022
cfcf1a7
initial code commit: getSamplingRules, getSamplingTargets and busines…
bhautikpip Feb 23, 2022
762ee2c
remove debugging logic
bhautikpip Feb 23, 2022
43d432b
fix clientID generation bug
bhautikpip Feb 23, 2022
3565ccf
added unit testing for remote sampling
bhautikpip Feb 25, 2022
7108aca
fixed minor issues and ran precommit
bhautikpip Feb 26, 2022
27567e0
Relayout reservoir and rule struct to ensure int64s are 8-byte aligned
bhautikpip Feb 28, 2022
d4ee60e
removed flaky test
bhautikpip Feb 28, 2022
02eb8a9
debugging upstream test failure
bhautikpip Feb 28, 2022
edc424a
fix data race failures in some tests
bhautikpip Feb 28, 2022
8551568
fix bug in attribute matching and minor changes
bhautikpip Mar 1, 2022
85a7548
addressed review comments: 1
bhautikpip Mar 2, 2022
755073c
Merge branch 'main' into remote-sampling-xray
hanyuancheung Mar 2, 2022
828627c
added use of montonic time and minor changes
bhautikpip Mar 2, 2022
31231d6
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
bhautikpip Mar 2, 2022
92ad67b
Merge branch 'remote-sampling-xray' of https://github.com/bhautikpip/…
bhautikpip Mar 2, 2022
0736097
fix flaky remote sampling test
bhautikpip Mar 2, 2022
bc0f85f
relayout the struct to fix unaligned atomic op issue
bhautikpip Mar 2, 2022
ff14fae
added leaky bucket logic for reservoir
bhautikpip Mar 8, 2022
1ce4b85
Merge branch 'main' into remote-sampling-xray
hanyuancheung Mar 8, 2022
3f7d44d
minor changes to fix some issues
bhautikpip Mar 8, 2022
47c8b79
Merge branch 'remote-sampling-xray' of https://github.com/bhautikpip/…
bhautikpip Mar 8, 2022
84730a1
fix test failures
bhautikpip Mar 8, 2022
629d1de
Merge branch 'main' into remote-sampling-xray
hanyuancheung Mar 9, 2022
98df8a4
removed epoch based logic when borrowing
bhautikpip Mar 9, 2022
83dba7b
Merge branch 'remote-sampling-xray' of https://github.com/bhautikpip/…
bhautikpip Mar 9, 2022
0737cbd
remove debugging lines
bhautikpip Mar 9, 2022
560ade1
Merge branch 'main' into remote-sampling-xray
bhautikpip Mar 10, 2022
7500f1e
address review comments
bhautikpip Mar 13, 2022
8a4c1dd
changed endpoint to be url.URL instead of string
bhautikpip Mar 14, 2022
0cf3224
added validate config inside new config and minor change
bhautikpip Mar 17, 2022
24bc286
removed util package and address minor comments
bhautikpip Mar 18, 2022
78874a9
moved timer and rand to xray package, minor changes
bhautikpip Mar 18, 2022
765f300
added more tests
bhautikpip Mar 18, 2022
47684c5
Merge branch 'main' into remote-sampling-xray
hanyuancheung Mar 21, 2022
cc384b8
improved testing from codecov/patch annotations
bhautikpip Mar 21, 2022
6da8e6f
Merge branch 'remote-sampling-xray' of https://github.com/bhautikpip/…
bhautikpip Mar 21, 2022
f8ab56e
Merge branch 'main' into remote-sampling-xray
bhautikpip Mar 21, 2022
cc7901c
addressed review comment
bhautikpip Mar 23, 2022
67caa10
Merge branch 'main' into remote-sampling-xray
bhautikpip Mar 23, 2022
1a07f6d
remove unnecessary config validation code and minor changes
bhautikpip Mar 24, 2022
50c1f3d
aaded race test and review comments changes
bhautikpip Mar 25, 2022
b0edd36
added custom deep copy implementation
bhautikpip Mar 25, 2022
b456c49
Merge branch 'main' into remote-sampling-xray
bhautikpip Mar 26, 2022
0bad9a6
update depandabot config
bhautikpip Mar 26, 2022
94cb0b7
added fallback sampler in case of rule match error and minor changes
bhautikpip Mar 28, 2022
6bfaa57
fix test failure
bhautikpip Mar 28, 2022
9adbf5a
Update samplers/aws/xray/internal/manifest.go
bhautikpip Mar 28, 2022
dfd0272
added API description: minor change
bhautikpip Mar 29, 2022
779e93f
Merge branch 'remote-sampling-xray' of https://github.com/bhautikpip/…
bhautikpip Mar 29, 2022
7626b7e
Merge branch 'main' into remote-sampling-xray
bhautikpip Mar 29, 2022
1c77778
Update samplers/aws/xray/remote_sampler.go
bhautikpip Mar 29, 2022
1fc8df8
minor change: modified matchers to return true directly
bhautikpip Mar 29, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Expand Up @@ -723,3 +723,13 @@ updates:
schedule:
interval: "weekly"
day: "sunday"
-
package-ecosystem: "gomod"
directory: "/samplers/aws/xray"
labels:
- dependencies
- go
- "Skip Changelog"
schedule:
interval: "weekly"
day: "sunday"
101 changes: 101 additions & 0 deletions samplers/aws/xray/fallback_sampler.go
@@ -0,0 +1,101 @@
// Copyright The 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 xray // import "go.opentelemetry.io/contrib/samplers/aws/xray"

import (
"sync"
"time"

sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/trace"
)

type FallbackSampler struct {
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
lastTick time.Time
quotaBalance float64
Aneurysm9 marked this conversation as resolved.
Show resolved Hide resolved
defaultSampler sdktrace.Sampler
mu sync.RWMutex
}

// Compile time assertion that remoteSampler implements the Sampler interface.
var _ sdktrace.Sampler = (*FallbackSampler)(nil)

// NewFallbackSampler returns a FallbackSampler which samples 1 req/sec and additional 5% of requests using traceIDRatioBasedSampler.
func NewFallbackSampler() *FallbackSampler {
return &FallbackSampler{
defaultSampler: sdktrace.TraceIDRatioBased(0.05),
quotaBalance: 1.0,
}
}

// ShouldSample implements the logic of borrowing 1 req/sec and then use traceIDRatioBasedSampler to sample 5% of additional requests.
func (fs *FallbackSampler) ShouldSample(parameters sdktrace.SamplingParameters) sdktrace.SamplingResult {
// borrowing one request every second
if fs.take(time.Now(), 1.0) {
return sdktrace.SamplingResult{
Tracestate: trace.SpanContextFromContext(parameters.ParentContext).TraceState(),
Decision: sdktrace.RecordAndSample,
}
}

// traceIDRatioBasedSampler to sample 5% of additional requests every second
return fs.defaultSampler.ShouldSample(parameters)
}

// Description returns description of the sampler being used
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
func (fs *FallbackSampler) Description() string {
return "FallbackSampler{fallback sampling with sampling config of 1 req/sec and 5% of additional requests}"
}

// take consumes quota from reservoir, if any remains, then returns true. False otherwise.
func (fs *FallbackSampler) take(now time.Time, itemCost float64) bool {
fs.mu.Lock()
defer fs.mu.Unlock()

if fs.lastTick.IsZero() {
fs.lastTick = now
}

if fs.quotaBalance >= itemCost {
fs.quotaBalance -= itemCost
return true
}

// update quota balance based on elapsed time
fs.refreshQuotaBalance(now)

if fs.quotaBalance >= itemCost {
fs.quotaBalance -= itemCost
return true
}

return false
}

// refreshQuotaBalance refreshes the quotaBalance considering elapsedTime.
func (fs *FallbackSampler) refreshQuotaBalance(now time.Time) {
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
currentTime := now
elapsedTime := currentTime.Sub(fs.lastTick)
fs.lastTick = currentTime
MrAlias marked this conversation as resolved.
Show resolved Hide resolved

// when elapsedTime is higher than 1 even then we need to keep quotaBalance
// near to 1 so making elapsedTime to 1 for only borrowing 1 per second case
if elapsedTime.Seconds() > 1.0 {
fs.quotaBalance += 1.0
} else {
// calculate how much credit have we accumulated since the last tick
fs.quotaBalance += elapsedTime.Seconds()
}
}
74 changes: 74 additions & 0 deletions samplers/aws/xray/fallback_sampler_test.go
@@ -0,0 +1,74 @@
// Copyright The 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 xray

import (
"testing"
"time"

"github.com/stretchr/testify/assert"

"go.opentelemetry.io/otel/sdk/trace"
)

// assert sampling using fallback sampler.
func TestSampleUsingFallbackSampler(t *testing.T) {
fs := NewFallbackSampler()
assert.NotEmpty(t, fs.defaultSampler)
assert.Equal(t, fs.quotaBalance, 1.0)

sd := fs.ShouldSample(trace.SamplingParameters{})
assert.Equal(t, trace.RecordAndSample, sd.Decision)
}

// assert that we only borrow 1 req/sec.
func TestBorrowOnePerSecond(t *testing.T) {
fs := NewFallbackSampler()
borrowed := fs.take(time.Unix(1500000000, 0), 1.0)

// assert that borrowing one per second
assert.True(t, borrowed)

borrowed = fs.take(time.Unix(1500000000, 0), 1.0)

// assert that borrowing again is false during that second
assert.False(t, borrowed)
bhautikpip marked this conversation as resolved.
Show resolved Hide resolved

borrowed = fs.take(time.Unix(1500000001, 0), 1.0)

// assert that borrowing again in next second
assert.True(t, borrowed)
}

// assert that when elapsedTime is high quotaBalance should still be close to 1.
func TestBorrowWithLargeElapsedTime(t *testing.T) {
fs := NewFallbackSampler()
borrowed := fs.take(time.Unix(1500000000, 0), 1.0)

// assert that borrowing one per second
assert.True(t, borrowed)

// Increase the time by 9 seconds
borrowed = fs.take(time.Unix(1500000009, 0), 1.0)
assert.True(t, borrowed)
assert.Equal(t, fs.quotaBalance, 0.0)
}

// assert fallback sampling description.
func TestFallbackSamplerDescription(t *testing.T) {
fs := NewFallbackSampler()
s := fs.Description()
assert.Equal(t, s, "FallbackSampler{fallback sampling with sampling config of 1 req/sec and 5% of additional requests}")
}
14 changes: 14 additions & 0 deletions samplers/aws/xray/go.mod
@@ -0,0 +1,14 @@
module go.opentelemetry.io/contrib/samplers/aws/xray

go 1.16

require (
github.com/go-logr/logr v1.2.2
github.com/go-logr/stdr v1.2.2
github.com/jinzhu/copier v0.3.5
github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel v1.4.0
go.opentelemetry.io/otel/sdk v1.4.0
go.opentelemetry.io/otel/trace v1.4.0
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
)
29 changes: 29 additions & 0 deletions samplers/aws/xray/go.sum
@@ -0,0 +1,29 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io/otel v1.4.0 h1:7ESuKPq6zpjRaY5nvVDGiuwK7VAJ8MwkKnmNJ9whNZ4=
go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk=
go.opentelemetry.io/otel/sdk v1.4.0 h1:LJE4SW3jd4lQTESnlpQZcBhQ3oci0U2MLR5uhicfTHQ=
go.opentelemetry.io/otel/sdk v1.4.0/go.mod h1:71GJPNJh4Qju6zJuYl1CrYtXbrgfau/M9UAggqiy1UE=
go.opentelemetry.io/otel/trace v1.4.0 h1:4OOUrPZdVFQkbzl/JSdvGCWIdw5ONXXxzHlaLlWppmo=
go.opentelemetry.io/otel/trace v1.4.0/go.mod h1:uc3eRsqDfWs9R7b92xbQbU42/eTNz4N+gLP8qJCi4aE=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=