Skip to content

Commit

Permalink
Merge branch 'main' into mymain
Browse files Browse the repository at this point in the history
  • Loading branch information
hanyuancheung committed Apr 6, 2022
2 parents 6a5a79f + 8cf7954 commit e4f2246
Show file tree
Hide file tree
Showing 24 changed files with 4,791 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Expand Up @@ -586,6 +586,15 @@ updates:
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /samplers/aws/xray
labels:
- dependencies
- go
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /samplers/jaegerremote
labels:
Expand Down
102 changes: 102 additions & 0 deletions samplers/aws/xray/fallback_sampler.go
@@ -0,0 +1,102 @@
// 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"
)

// FallbackSampler does the sampling at a rate of 1 req/sec and 5% of additional requests.
type FallbackSampler struct {
lastTick time.Time
quotaBalance float64
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.
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.refreshQuotaBalanceLocked(now)

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

return false
}

// refreshQuotaBalanceLocked refreshes the quotaBalance considering elapsedTime.
// It is assumed the lock is held when calling this.
func (fs *FallbackSampler) refreshQuotaBalanceLocked(now time.Time) {
elapsedTime := now.Sub(fs.lastTick)
fs.lastTick = now

// 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)

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}")
}
13 changes: 13 additions & 0 deletions samplers/aws/xray/go.mod
@@ -0,0 +1,13 @@
module go.opentelemetry.io/contrib/samplers/aws/xray

go 1.16

require (
github.com/go-logr/logr v1.2.3
github.com/go-logr/stdr v1.2.2
github.com/stretchr/testify v1.7.1
go.opentelemetry.io/otel v1.6.0
go.opentelemetry.io/otel/sdk v1.6.0
go.opentelemetry.io/otel/trace v1.6.0
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
)
28 changes: 28 additions & 0 deletions samplers/aws/xray/go.sum
@@ -0,0 +1,28 @@
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/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/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/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.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io/otel v1.6.0 h1:YV6GkGe/Ag2PKsm4rjlqdSNs0w0A5ZzxeGkxhx1T+t4=
go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ=
go.opentelemetry.io/otel/sdk v1.6.0 h1:JoriAoiNENuxxIQApR1O0k2h1Md5QegZhbentcRJpWk=
go.opentelemetry.io/otel/sdk v1.6.0/go.mod h1:PjLRUfDsoPy0zl7yrDGSUqjj43tL7rEtFdCEiGlxXRM=
go.opentelemetry.io/otel/trace v1.6.0 h1:NDzPermp9ISkhxIaJXjBTi2O60xOSHDHP/EezjOL2wo=
go.opentelemetry.io/otel/trace v1.6.0/go.mod h1:qs7BrU5cZ8dXQHBGxHMOxwME/27YH2qEp4/+tZLLwJE=
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=

0 comments on commit e4f2246

Please sign in to comment.