diff --git a/sample/dynamic_test.go b/sample/dynamic_test.go index 94823044f7..358d8d6f0e 100644 --- a/sample/dynamic_test.go +++ b/sample/dynamic_test.go @@ -19,7 +19,8 @@ func TestDynamicAddSampleRateKeyToTrace(t *testing.T) { sampler := &DynamicSampler{ Config: &config.DynamicSamplerConfig{ - FieldList: []string{"http.status_code"}, + FieldList: []string{"http.status_code", "root.service_name", "root.url"}, + SampleRate: 1, }, Logger: &logger.NullLogger{}, Metrics: &metrics, @@ -27,17 +28,32 @@ func TestDynamicAddSampleRateKeyToTrace(t *testing.T) { trace := &types.Trace{} for i := 0; i < spanCount; i++ { + if i == spanCount-1 { + trace.RootSpan = &types.Span{ + Event: types.Event{ + Data: map[string]interface{}{ + "http.status_code": "200", + "service_name": "test", + }, + }, + } + } trace.AddSpan(&types.Span{ Event: types.Event{ Data: map[string]interface{}{ "http.status_code": "200", + "url": "/test", }, }, }) } sampler.Start() - sampler.GetSampleRate(trace) + rate, keep, reason, key := sampler.GetSampleRate(trace) spans := trace.GetSpans() assert.Len(t, spans, spanCount, "should have the same number of spans as input") + assert.Equal(t, uint(1), rate) + assert.True(t, keep) + assert.Equal(t, "dynamic", reason) + assert.Equal(t, "200•,test,", key) } diff --git a/sample/trace_key.go b/sample/trace_key.go index da65fefa3f..7683397dd3 100644 --- a/sample/trace_key.go +++ b/sample/trace_key.go @@ -4,20 +4,34 @@ import ( "fmt" "sort" "strconv" + "strings" "github.com/honeycombio/refinery/types" ) type traceKey struct { fields []string + rootOnlyFields []string useTraceLength bool } func newTraceKey(fields []string, useTraceLength bool) *traceKey { // always put the field list in sorted order for easier comparison sort.Strings(fields) + rootOnlyFields := make([]string, 0, len(fields)/2) + nonRootFields := make([]string, 0, len(fields)/2) + for _, field := range fields { + if strings.HasPrefix(field, RootPrefix) { + rootOnlyFields = append(rootOnlyFields, field[len(RootPrefix):]) + continue + } + + nonRootFields = append(nonRootFields, field) + } + return &traceKey{ - fields: fields, + fields: nonRootFields, + rootOnlyFields: rootOnlyFields, useTraceLength: useTraceLength, } } @@ -26,7 +40,7 @@ func newTraceKey(fields []string, useTraceLength bool) *traceKey { func (d *traceKey) build(trace *types.Trace) string { // fieldCollector gets all values from the fields listed in the config, even // if they happen multiple times. - fieldCollector := map[string][]string{} + fieldCollector := make(map[string][]string) // for each field, for each span, get the value of that field spans := trace.GetSpans() @@ -54,6 +68,15 @@ func (d *traceKey) build(trace *types.Trace) string { key += "," } + if trace.RootSpan != nil { + for _, field := range d.rootOnlyFields { + + if val, ok := trace.RootSpan.Data[field]; ok { + key += fmt.Sprintf("%v,", val) + } + } + } + if d.useTraceLength { key += strconv.FormatInt(int64(len(spans)), 10) } diff --git a/sample/trace_key_test.go b/sample/trace_key_test.go index e7a3bfec65..b9e29ba25c 100644 --- a/sample/trace_key_test.go +++ b/sample/trace_key_test.go @@ -117,8 +117,9 @@ func TestKeyGeneration(t *testing.T) { assert.Equal(t, expected, generator.build(trace)) - // now test that multiple values across spans in a different order are condensed the same - fields = []string{"http.status_code"} + // test field list with root prefix, only include the field from on the root span + // if it exists + fields = []string{"http.status_code", "root.service_name", "root.another_field"} useTraceLength = true generator = newTraceKey(fields, useTraceLength) @@ -133,31 +134,24 @@ func TestKeyGeneration(t *testing.T) { }, }) - trace.AddSpan(&types.Span{ - Event: types.Event{ - Data: map[string]interface{}{ - "http.status_code": 404, - }, - }, - }) - trace.AddSpan(&types.Span{ Event: types.Event{ Data: map[string]interface{}{ "http.status_code": 200, + "service_name": "another", }, }, }) - trace.AddSpan(&types.Span{ + trace.RootSpan = &types.Span{ Event: types.Event{ Data: map[string]interface{}{ - "http.status_code": 200, + "service_name": "test", }, }, - }) + } - expected = "200•404•,4" + expected = "200•404•,test,2" assert.Equal(t, expected, generator.build(trace)) }