diff --git a/internal/sampling/samplingstrategy/adaptive/aggregator.go b/internal/sampling/samplingstrategy/adaptive/aggregator.go index 9a15a4e87b5..dd4f53a1e65 100644 --- a/internal/sampling/samplingstrategy/adaptive/aggregator.go +++ b/internal/sampling/samplingstrategy/adaptive/aggregator.go @@ -4,6 +4,7 @@ package adaptive import ( + "strconv" "sync" "time" @@ -150,9 +151,42 @@ func (a *aggregator) HandleRootSpan(span *span_model.Span) { if service == "" || span.OperationName == "" { return } - samplerType, samplerParam := span.GetSamplerParams(a.postAggregator.logger) + samplerType, samplerParam := getSamplerParams(span, a.postAggregator.logger) if samplerType == span_model.SamplerTypeUnrecognized { return } a.RecordThroughput(service, span.OperationName, samplerType, samplerParam) } + +// GetSamplerParams returns the sampler.type and sampler.param value if they are valid. +func getSamplerParams(s *span_model.Span, logger *zap.Logger) (span_model.SamplerType, float64) { + samplerType := s.GetSamplerType() + if samplerType == span_model.SamplerTypeUnrecognized { + return span_model.SamplerTypeUnrecognized, 0 + } + tag, ok := span_model.KeyValues(s.Tags).FindByKey(span_model.SamplerParamKey) + if !ok { + return span_model.SamplerTypeUnrecognized, 0 + } + samplerParam, err := samplerParamToFloat(tag) + if err != nil { + logger. + With(zap.String("traceID", s.TraceID.String())). + With(zap.String("spanID", s.SpanID.String())). + Warn("sampler.param tag is not a number", zap.Any("tag", tag)) + return span_model.SamplerTypeUnrecognized, 0 + } + return samplerType, samplerParam +} + +func samplerParamToFloat(samplerParamTag span_model.KeyValue) (float64, error) { + // The param could be represented as a string, an int, or a float + switch samplerParamTag.VType { + case span_model.Float64Type: + return samplerParamTag.Float64(), nil + case span_model.Int64Type: + return float64(samplerParamTag.Int64()), nil + default: + return strconv.ParseFloat(samplerParamTag.AsString(), 64) + } +} diff --git a/internal/sampling/samplingstrategy/adaptive/aggregator_test.go b/internal/sampling/samplingstrategy/adaptive/aggregator_test.go index a1736df5949..b1c36960c90 100644 --- a/internal/sampling/samplingstrategy/adaptive/aggregator_test.go +++ b/internal/sampling/samplingstrategy/adaptive/aggregator_test.go @@ -5,6 +5,7 @@ package adaptive import ( "net/http" + "strconv" "testing" "time" @@ -186,3 +187,124 @@ func TestRecordThroughputFunc(t *testing.T) { a.HandleRootSpan(span) assert.EqualValues(t, 1, a.(*aggregator).currentThroughput["A"][http.MethodGet].Count) } + +func TestGetSamplerParams(t *testing.T) { + logger := zap.NewNop() + + tests := []struct { + tags model.KeyValues + expectedType model.SamplerType + expectedParam float64 + }{ + { + tags: model.KeyValues{ + model.String("sampler.type", "probabilistic"), + model.String("sampler.param", "1e-05"), + }, + expectedType: model.SamplerTypeProbabilistic, + expectedParam: 0.00001, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "probabilistic"), + model.Float64("sampler.param", 0.10404450002098709), + }, + expectedType: model.SamplerTypeProbabilistic, + expectedParam: 0.10404450002098709, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "probabilistic"), + model.String("sampler.param", "0.10404450002098709"), + }, + expectedType: model.SamplerTypeProbabilistic, + expectedParam: 0.10404450002098709, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "probabilistic"), + model.Int64("sampler.param", 1), + }, + expectedType: model.SamplerTypeProbabilistic, + expectedParam: 1.0, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "ratelimiting"), + model.String("sampler.param", "1"), + }, + expectedType: model.SamplerTypeRateLimiting, + expectedParam: 1, + }, + { + tags: model.KeyValues{ + model.Float64("sampler.type", 1.5), + }, + expectedType: model.SamplerTypeUnrecognized, + expectedParam: 0, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "probabilistic"), + }, + expectedType: model.SamplerTypeUnrecognized, + expectedParam: 0, + }, + { + tags: model.KeyValues{}, + expectedType: model.SamplerTypeUnrecognized, + expectedParam: 0, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "lowerbound"), + model.String("sampler.param", "1"), + }, + expectedType: model.SamplerTypeLowerBound, + expectedParam: 1, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "lowerbound"), + model.Int64("sampler.param", 1), + }, + expectedType: model.SamplerTypeLowerBound, + expectedParam: 1, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "lowerbound"), + model.Float64("sampler.param", 0.5), + }, + expectedType: model.SamplerTypeLowerBound, + expectedParam: 0.5, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "lowerbound"), + model.String("sampler.param", "not_a_number"), + }, + expectedType: model.SamplerTypeUnrecognized, + expectedParam: 0, + }, + { + tags: model.KeyValues{ + model.String("sampler.type", "not_a_type"), + model.String("sampler.param", "not_a_number"), + }, + expectedType: model.SamplerTypeUnrecognized, + expectedParam: 0, + }, + } + + for i, test := range tests { + tt := test + t.Run(strconv.Itoa(i), func(t *testing.T) { + span := &model.Span{} + span.Tags = tt.tags + actualType, actualParam := getSamplerParams(span, logger) + assert.Equal(t, tt.expectedType, actualType) + assert.InDelta(t, tt.expectedParam, actualParam, 0.01) + }) + } +} diff --git a/model/span.go b/model/span.go index b5d037b9ea2..1e5d4aa9265 100644 --- a/model/span.go +++ b/model/span.go @@ -7,9 +7,6 @@ package model import ( "encoding/gob" "io" - "strconv" - - "go.uber.org/zap" ) type SamplerType int @@ -142,36 +139,3 @@ func (s *Span) ReplaceParentID(newParentID SpanID) { } s.References = MaybeAddParentSpanID(s.TraceID, newParentID, s.References) } - -// GetSamplerParams returns the sampler.type and sampler.param value if they are valid. -func (s *Span) GetSamplerParams(logger *zap.Logger) (SamplerType, float64) { - samplerType := s.GetSamplerType() - if samplerType == SamplerTypeUnrecognized { - return SamplerTypeUnrecognized, 0 - } - tag, ok := KeyValues(s.Tags).FindByKey(SamplerParamKey) - if !ok { - return SamplerTypeUnrecognized, 0 - } - samplerParam, err := samplerParamToFloat(tag) - if err != nil { - logger. - With(zap.String("traceID", s.TraceID.String())). - With(zap.String("spanID", s.SpanID.String())). - Warn("sampler.param tag is not a number", zap.Any("tag", tag)) - return SamplerTypeUnrecognized, 0 - } - return samplerType, samplerParam -} - -func samplerParamToFloat(samplerParamTag KeyValue) (float64, error) { - // The param could be represented as a string, an int, or a float - switch samplerParamTag.VType { - case Float64Type: - return samplerParamTag.Float64(), nil - case Int64Type: - return float64(samplerParamTag.Int64()), nil - default: - return strconv.ParseFloat(samplerParamTag.AsString(), 64) - } -} diff --git a/model/span_test.go b/model/span_test.go index bd11cae5043..69016ad3df6 100644 --- a/model/span_test.go +++ b/model/span_test.go @@ -7,7 +7,6 @@ package model_test import ( "bytes" "fmt" - "strconv" "testing" "time" @@ -15,8 +14,6 @@ import ( "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" "github.com/jaegertracing/jaeger/model" ) @@ -165,7 +162,7 @@ func TestSpanIDUnmarshalJSONErrors(t *testing.T) { func TestIsRPCClientServer(t *testing.T) { span1 := &model.Span{ Tags: model.KeyValues{ - model.String(model.SpanKindKey, trace.SpanKindClient.String()), + model.String(model.SpanKindKey, "client"), }, } assert.True(t, span1.IsRPCClient()) @@ -335,123 +332,3 @@ func BenchmarkBatchSerialization(b *testing.B) { } }) } - -func TestGetSamplerParams(t *testing.T) { - logger := zap.NewNop() - tests := []struct { - tags model.KeyValues - expectedType model.SamplerType - expectedParam float64 - }{ - { - tags: model.KeyValues{ - model.String("sampler.type", "probabilistic"), - model.String("sampler.param", "1e-05"), - }, - expectedType: model.SamplerTypeProbabilistic, - expectedParam: 0.00001, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "probabilistic"), - model.Float64("sampler.param", 0.10404450002098709), - }, - expectedType: model.SamplerTypeProbabilistic, - expectedParam: 0.10404450002098709, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "probabilistic"), - model.String("sampler.param", "0.10404450002098709"), - }, - expectedType: model.SamplerTypeProbabilistic, - expectedParam: 0.10404450002098709, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "probabilistic"), - model.Int64("sampler.param", 1), - }, - expectedType: model.SamplerTypeProbabilistic, - expectedParam: 1.0, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "ratelimiting"), - model.String("sampler.param", "1"), - }, - expectedType: model.SamplerTypeRateLimiting, - expectedParam: 1, - }, - { - tags: model.KeyValues{ - model.Float64("sampler.type", 1.5), - }, - expectedType: model.SamplerTypeUnrecognized, - expectedParam: 0, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "probabilistic"), - }, - expectedType: model.SamplerTypeUnrecognized, - expectedParam: 0, - }, - { - tags: model.KeyValues{}, - expectedType: model.SamplerTypeUnrecognized, - expectedParam: 0, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "lowerbound"), - model.String("sampler.param", "1"), - }, - expectedType: model.SamplerTypeLowerBound, - expectedParam: 1, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "lowerbound"), - model.Int64("sampler.param", 1), - }, - expectedType: model.SamplerTypeLowerBound, - expectedParam: 1, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "lowerbound"), - model.Float64("sampler.param", 0.5), - }, - expectedType: model.SamplerTypeLowerBound, - expectedParam: 0.5, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "lowerbound"), - model.String("sampler.param", "not_a_number"), - }, - expectedType: model.SamplerTypeUnrecognized, - expectedParam: 0, - }, - { - tags: model.KeyValues{ - model.String("sampler.type", "not_a_type"), - model.String("sampler.param", "not_a_number"), - }, - expectedType: model.SamplerTypeUnrecognized, - expectedParam: 0, - }, - } - - for i, test := range tests { - tt := test - t.Run(strconv.Itoa(i), func(t *testing.T) { - span := &model.Span{} - span.Tags = tt.tags - actualType, actualParam := span.GetSamplerParams(logger) - assert.Equal(t, tt.expectedType, actualType) - assert.InDelta(t, tt.expectedParam, actualParam, 0.01) - }) - } -}