diff --git a/enrichments/trace/config/config.go b/enrichments/trace/config/config.go index 9d9a948..f28a99d 100644 --- a/enrichments/trace/config/config.go +++ b/enrichments/trace/config/config.go @@ -40,26 +40,28 @@ type ScopeConfig struct { // ElasticTransactionConfig configures the enrichment attributes for the // spans which are identified as elastic transaction. type ElasticTransactionConfig struct { - ID AttributeConfig `mapstructure:"id"` - Root AttributeConfig `mapstructure:"root"` - Name AttributeConfig `mapstructure:"name"` - ProcessorEvent AttributeConfig `mapstructure:"processor_event"` - DurationUs AttributeConfig `mapstructure:"duration_us"` - Type AttributeConfig `mapstructure:"type"` - Result AttributeConfig `mapstructure:"result"` - EventOutcome AttributeConfig `mapstructure:"event_outcome"` + ID AttributeConfig `mapstructure:"id"` + Root AttributeConfig `mapstructure:"root"` + Name AttributeConfig `mapstructure:"name"` + ProcessorEvent AttributeConfig `mapstructure:"processor_event"` + RepresentativeCount AttributeConfig `mapstructure:"representative_count"` + DurationUs AttributeConfig `mapstructure:"duration_us"` + Type AttributeConfig `mapstructure:"type"` + Result AttributeConfig `mapstructure:"result"` + EventOutcome AttributeConfig `mapstructure:"event_outcome"` } // ElasticSpanConfig configures the enrichment attributes for the spans // which are NOT identified as elastic transaction. type ElasticSpanConfig struct { - Name AttributeConfig `mapstructure:"name"` - ProcessorEvent AttributeConfig `mapstructure:"processor_event"` - TypeSubtype AttributeConfig `mapstructure:"type_subtype"` - DurationUs AttributeConfig `mapstructure:"duration_us"` - EventOutcome AttributeConfig `mapstructure:"event_outcome"` - ServiceTarget AttributeConfig `mapstructure:"service_target"` - DestinationService AttributeConfig `mapstructure:"destination_service"` + Name AttributeConfig `mapstructure:"name"` + ProcessorEvent AttributeConfig `mapstructure:"processor_event"` + RepresentativeCount AttributeConfig `mapstructure:"representative_count"` + TypeSubtype AttributeConfig `mapstructure:"type_subtype"` + DurationUs AttributeConfig `mapstructure:"duration_us"` + EventOutcome AttributeConfig `mapstructure:"event_outcome"` + ServiceTarget AttributeConfig `mapstructure:"service_target"` + DestinationService AttributeConfig `mapstructure:"destination_service"` } // AttributeConfig is the configuration options for each attribute. @@ -79,23 +81,25 @@ func Enabled() Config { ServiceFrameworkVersion: AttributeConfig{Enabled: true}, }, Transaction: ElasticTransactionConfig{ - ID: AttributeConfig{Enabled: true}, - Root: AttributeConfig{Enabled: true}, - Name: AttributeConfig{Enabled: true}, - ProcessorEvent: AttributeConfig{Enabled: true}, - DurationUs: AttributeConfig{Enabled: true}, - Type: AttributeConfig{Enabled: true}, - Result: AttributeConfig{Enabled: true}, - EventOutcome: AttributeConfig{Enabled: true}, + ID: AttributeConfig{Enabled: true}, + Root: AttributeConfig{Enabled: true}, + Name: AttributeConfig{Enabled: true}, + ProcessorEvent: AttributeConfig{Enabled: true}, + DurationUs: AttributeConfig{Enabled: true}, + Type: AttributeConfig{Enabled: true}, + Result: AttributeConfig{Enabled: true}, + EventOutcome: AttributeConfig{Enabled: true}, + RepresentativeCount: AttributeConfig{Enabled: true}, }, Span: ElasticSpanConfig{ - Name: AttributeConfig{Enabled: true}, - ProcessorEvent: AttributeConfig{Enabled: true}, - TypeSubtype: AttributeConfig{Enabled: true}, - DurationUs: AttributeConfig{Enabled: true}, - EventOutcome: AttributeConfig{Enabled: true}, - ServiceTarget: AttributeConfig{Enabled: true}, - DestinationService: AttributeConfig{Enabled: true}, + Name: AttributeConfig{Enabled: true}, + ProcessorEvent: AttributeConfig{Enabled: true}, + TypeSubtype: AttributeConfig{Enabled: true}, + DurationUs: AttributeConfig{Enabled: true}, + EventOutcome: AttributeConfig{Enabled: true}, + ServiceTarget: AttributeConfig{Enabled: true}, + DestinationService: AttributeConfig{Enabled: true}, + RepresentativeCount: AttributeConfig{Enabled: true}, }, } } diff --git a/enrichments/trace/internal/elastic/attributes.go b/enrichments/trace/internal/elastic/attributes.go index 76d771b..c8be4f2 100644 --- a/enrichments/trace/internal/elastic/attributes.go +++ b/enrichments/trace/internal/elastic/attributes.go @@ -34,6 +34,7 @@ const ( AttributeTransactionType = "transaction.type" AttributeTransactionDurationUs = "transaction.duration.us" AttributeTransactionResult = "transaction.result" + AttributeTransactionRepresentativeCount = "transaction.representative_count" AttributeSpanName = "span.name" AttributeSpanType = "span.type" AttributeSpanSubtype = "span.subtype" @@ -43,4 +44,5 @@ const ( AttributeServiceTargetName = "service.target.name" AttributeSpanDestinationServiceResource = "span.destination.service.resource" AttributeSpanDurationUs = "span.duration.us" + AttributeSpanRepresentativeCount = "span.representative_count" ) diff --git a/enrichments/trace/internal/elastic/span.go b/enrichments/trace/internal/elastic/span.go index 273ed46..708f191 100644 --- a/enrichments/trace/internal/elastic/span.go +++ b/enrichments/trace/internal/elastic/span.go @@ -19,10 +19,12 @@ package elastic import ( "fmt" + "math" "net" "net/http" "net/url" "strconv" + "strings" "github.com/elastic/opentelemetry-lib/enrichments/trace/config" "go.opentelemetry.io/collector/pdata/pcommon" @@ -173,6 +175,10 @@ func (s *spanEnrichmentContext) enrichTransaction( if cfg.ProcessorEvent.Enabled { span.Attributes().PutStr(AttributeProcessorEvent, "transaction") } + if cfg.RepresentativeCount.Enabled { + repCount := getRepresentativeCount(span.TraceState().AsRaw()) + span.Attributes().PutDouble(AttributeTransactionRepresentativeCount, repCount) + } if cfg.DurationUs.Enabled { span.Attributes().PutInt(AttributeTransactionDurationUs, getDurationUs(span)) } @@ -197,6 +203,10 @@ func (s *spanEnrichmentContext) enrichSpan( if cfg.ProcessorEvent.Enabled { span.Attributes().PutStr(AttributeProcessorEvent, "span") } + if cfg.RepresentativeCount.Enabled { + repCount := getRepresentativeCount(span.TraceState().AsRaw()) + span.Attributes().PutDouble(AttributeSpanRepresentativeCount, repCount) + } if cfg.TypeSubtype.Enabled { s.setSpanTypeSubtype(span) } @@ -391,6 +401,37 @@ func (s *spanEnrichmentContext) setDestinationService(span ptrace.Span) { } } +// getRepresentativeCount returns the number of spans represented by an +// individually sampled span as per the passed tracestate header. +// +// Representative count is similar to the OTel adjusted count definition +// with a difference that representative count can also include +// dynamically calculated representivity for non-probabilistic sampling. +// In addition, the representative count defaults to 1 if the adjusted +// count is UNKNOWN or the p-value is invalid. +// +// Def: https://opentelemetry.io/docs/specs/otel/trace/tracestate-probability-sampling/#adjusted-count) +// +// The count is calculated by using p-value: +// https://opentelemetry.io/docs/reference/specification/trace/tracestate-probability-sampling/#p-value +func getRepresentativeCount(tracestate string) float64 { + var p uint64 + otValue := getValueForKeyInString(tracestate, "ot", ',', '=') + if otValue != "" { + pValue := getValueForKeyInString(otValue, "p", ';', ':') + + if pValue != "" { + p, _ = strconv.ParseUint(pValue, 10, 6) + } + } + + if p == 63 { + // p-value == 63 represents zero adjusted count + return 0.0 + } + return math.Pow(2, float64(p)) +} + func getDurationUs(span ptrace.Span) int64 { return int64(span.EndTimestamp()-span.StartTimestamp()) / 1000 } @@ -414,6 +455,29 @@ func isElasticTransaction(span ptrace.Span) bool { return false } +// parses string format `=val` +func getValueForKeyInString(str string, key string, separator rune, assignChar rune) string { + for { + str = strings.TrimSpace(str) + if str == "" { + break + } + kv := str + if sepIdx := strings.IndexRune(str, separator); sepIdx != -1 { + kv = strings.TrimSpace(str[:sepIdx]) + str = str[sepIdx+1:] + } else { + str = "" + } + equal := strings.IndexRune(kv, assignChar) + if equal != -1 && kv[:equal] == key { + return kv[equal+1:] + } + } + + return "" +} + // getHostPort derives the host:port value from url.* attributes. Unlike // apm-data, the current code does NOT fallback to net.* or http.* // attributes as most of these are now deprecated. diff --git a/enrichments/trace/internal/elastic/span_test.go b/enrichments/trace/internal/elastic/span_test.go index 1f2eb24..15b0796 100644 --- a/enrichments/trace/internal/elastic/span_test.go +++ b/enrichments/trace/internal/elastic/span_test.go @@ -57,15 +57,16 @@ func TestElasticTransactionEnrich(t *testing.T) { input: ptrace.NewSpan(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "", - AttributeTransactionName: "", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: int64(0), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "Success", - AttributeTransactionType: "unknown", + AttributeTransactionRoot: true, + AttributeTransactionID: "", + AttributeTransactionName: "", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: int64(0), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "Success", + AttributeTransactionType: "unknown", }, }, { @@ -73,6 +74,27 @@ func TestElasticTransactionEnrich(t *testing.T) { input: getElasticTxn(), enrichedAttrs: map[string]any{}, }, + { + name: "with_pvalue", + input: func() ptrace.Span { + span := ptrace.NewSpan() + span.TraceState().FromRaw("ot=p:8;") + return span + }(), + config: config.Enabled().Transaction, + enrichedAttrs: map[string]any{ + AttributeTransactionRoot: true, + AttributeTransactionID: "", + AttributeTransactionName: "", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(256), + AttributeTransactionDurationUs: int64(0), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "Success", + AttributeTransactionType: "unknown", + }, + }, { name: "http_status_ok", input: func() ptrace.Span { @@ -83,15 +105,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "HTTP 2xx", - AttributeTransactionType: "request", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "HTTP 2xx", + AttributeTransactionType: "request", }, }, { @@ -110,15 +133,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "HTTP 1xx", - AttributeTransactionType: "request", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "HTTP 1xx", + AttributeTransactionType: "request", }, }, { @@ -136,15 +160,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "HTTP 5xx", - AttributeTransactionType: "request", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "HTTP 5xx", + AttributeTransactionType: "request", }, }, { @@ -163,15 +188,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "OK", - AttributeTransactionType: "request", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "OK", + AttributeTransactionType: "request", }, }, { @@ -190,15 +216,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "Internal", - AttributeTransactionType: "request", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "Internal", + AttributeTransactionType: "request", }, }, { @@ -212,15 +239,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "Success", - AttributeTransactionType: "unknown", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "Success", + AttributeTransactionType: "unknown", }, }, { @@ -234,15 +262,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "failure", - AttributeSuccessCount: int64(0), - AttributeTransactionResult: "Error", - AttributeTransactionType: "unknown", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "failure", + AttributeSuccessCount: int64(0), + AttributeTransactionResult: "Error", + AttributeTransactionType: "unknown", }, }, { @@ -256,15 +285,16 @@ func TestElasticTransactionEnrich(t *testing.T) { }(), config: config.Enabled().Transaction, enrichedAttrs: map[string]any{ - AttributeTransactionRoot: true, - AttributeTransactionID: "0100000000000000", - AttributeTransactionName: "testtxn", - AttributeProcessorEvent: "transaction", - AttributeTransactionDurationUs: expectedDuration.Microseconds(), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), - AttributeTransactionResult: "Success", - AttributeTransactionType: "messaging", + AttributeTransactionRoot: true, + AttributeTransactionID: "0100000000000000", + AttributeTransactionName: "testtxn", + AttributeProcessorEvent: "transaction", + AttributeTransactionRepresentativeCount: float64(1), + AttributeTransactionDurationUs: expectedDuration.Microseconds(), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), + AttributeTransactionResult: "Success", + AttributeTransactionType: "messaging", }, }, } { @@ -314,12 +344,13 @@ func TestElasticSpanEnrich(t *testing.T) { }(), config: config.Enabled().Span, enrichedAttrs: map[string]any{ - AttributeSpanName: "", - AttributeProcessorEvent: "span", - AttributeSpanType: "unknown", - AttributeSpanDurationUs: int64(0), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), + AttributeSpanName: "", + AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), + AttributeSpanType: "unknown", + AttributeSpanDurationUs: int64(0), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), }, }, { @@ -337,13 +368,14 @@ func TestElasticSpanEnrich(t *testing.T) { }(), config: config.Enabled().Span, enrichedAttrs: map[string]any{ - AttributeSpanName: "", - AttributeProcessorEvent: "span", - AttributeSpanType: "app", - AttributeSpanSubtype: "internal", - AttributeSpanDurationUs: int64(0), - AttributeEventOutcome: "success", - AttributeSuccessCount: int64(1), + AttributeSpanName: "", + AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), + AttributeSpanType: "app", + AttributeSpanSubtype: "internal", + AttributeSpanDurationUs: int64(0), + AttributeEventOutcome: "success", + AttributeSuccessCount: int64(1), }, }, { @@ -358,6 +390,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "unknown", AttributeSpanDurationUs: expectedDuration.Microseconds(), AttributeEventOutcome: "success", @@ -383,6 +416,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "external", AttributeSpanSubtype: "http", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -415,6 +449,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "external", AttributeSpanSubtype: "http", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -445,6 +480,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "external", AttributeSpanSubtype: "http", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -471,6 +507,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "external", AttributeSpanSubtype: "grpc", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -494,6 +531,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "external", AttributeSpanSubtype: "xmlrpc", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -519,6 +557,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "external", AttributeSpanDurationUs: expectedDuration.Microseconds(), AttributeEventOutcome: "success", @@ -541,6 +580,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "messaging", AttributeSpanSubtype: "kafka", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -564,6 +604,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "messaging", AttributeSpanDurationUs: expectedDuration.Microseconds(), AttributeEventOutcome: "success", @@ -587,6 +628,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "messaging", AttributeSpanDurationUs: expectedDuration.Microseconds(), AttributeEventOutcome: "success", @@ -616,6 +658,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "db", AttributeSpanSubtype: "elasticsearch", AttributeSpanDurationUs: expectedDuration.Microseconds(), @@ -651,6 +694,7 @@ func TestElasticSpanEnrich(t *testing.T) { enrichedAttrs: map[string]any{ AttributeSpanName: "testspan", AttributeProcessorEvent: "span", + AttributeSpanRepresentativeCount: float64(1), AttributeSpanType: "db", AttributeSpanSubtype: "cassandra", AttributeSpanDurationUs: expectedDuration.Microseconds(),