TraceView: Add scope attributes to span details (#103173)

* Add scope attributes to span details

* Tests
pull/104486/head
Joey 4 months ago committed by GitHub
parent feadd37f27
commit 4689b7c0cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 23
      pkg/tsdb/tempo/trace_transform.go
  2. 79
      pkg/tsdb/tempo/trace_transform_test.go

@ -143,7 +143,12 @@ func spanToSpanRow(span *tracev11.Span, libraryTags *commonv11.InstrumentationSc
return nil, fmt.Errorf("failed to marshal service tags: %w", err)
}
spanTags, err := json.Marshal(getSpanTags(span))
// Get both span tags and scope tags and combine them
spanTagsList := getSpanTags(span)
scopeTagsList := getScopeTags(libraryTags)
spanTagsList = append(spanTagsList, scopeTagsList...)
spanTags, err := json.Marshal(spanTagsList)
if err != nil {
return nil, fmt.Errorf("failed to marshal span tags: %w", err)
}
@ -270,6 +275,22 @@ func getSpanTags(span *tracev11.Span) []*KeyValue {
return tags
}
func getScopeTags(scope *commonv11.InstrumentationScope) []*KeyValue {
if scope == nil || len(scope.Attributes) == 0 {
return nil
}
tags := make([]*KeyValue, len(scope.Attributes))
for i, attr := range scope.Attributes {
val, err := getAttributeVal(attr.Value)
if err != nil {
logger.Debug("error transforming scope attributes", "err", err)
}
tags[i] = &KeyValue{Key: attr.Key, Value: val}
}
return tags
}
func getSpanKind(spanKind tracev11.Span_SpanKind) string {
var tagStr string
switch spanKind {

@ -10,6 +10,8 @@ import (
"github.com/golang/protobuf/jsonpb"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/tempo/pkg/tempopb"
commonv11 "github.com/grafana/tempo/pkg/tempopb/common/v1"
resourcev1 "github.com/grafana/tempo/pkg/tempopb/resource/v1"
v1 "github.com/grafana/tempo/pkg/tempopb/trace/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -117,6 +119,83 @@ func TestTraceToFrame(t *testing.T) {
})
}
func TestScopeAttributesAddedToTags(t *testing.T) {
span := &v1.Span{
TraceId: []byte{0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7},
SpanId: []byte{0, 1, 2, 3, 4, 5, 6, 7},
ParentSpanId: []byte{0, 0, 0, 0, 0, 0, 0, 0},
Name: "test-span",
StartTimeUnixNano: 1616072924070497000,
EndTimeUnixNano: 1616072924078918000,
Attributes: []*commonv11.KeyValue{
{
Key: "span.attribute",
Value: &commonv11.AnyValue{
Value: &commonv11.AnyValue_StringValue{
StringValue: "span-value",
},
},
},
},
Status: &v1.Status{},
}
// Create instrumentation scope with attributes
scope := &commonv11.InstrumentationScope{
Name: "my.library",
Version: "1.0.0",
Attributes: []*commonv11.KeyValue{
{
Key: "scope.attribute",
Value: &commonv11.AnyValue{
Value: &commonv11.AnyValue_StringValue{
StringValue: "scope-value",
},
},
},
},
}
resource := &resourcev1.Resource{
Attributes: []*commonv11.KeyValue{
{
Key: "service.name",
Value: &commonv11.AnyValue{
Value: &commonv11.AnyValue_StringValue{
StringValue: "test-service",
},
},
},
},
}
row, err := spanToSpanRow(span, scope, resource)
require.NoError(t, err)
// Check that both span and scope attributes are in tags
// Tags are at index 16 in the row (based on frame field ordering)
tagsJson := row[16].(json.RawMessage)
var tags []*KeyValue
err = json.Unmarshal(tagsJson, &tags)
require.NoError(t, err)
foundSpanAttr := false
foundScopeAttr := false
for _, tag := range tags {
if tag.Key == "span.attribute" && tag.Value == "span-value" {
foundSpanAttr = true
}
if tag.Key == "scope.attribute" && tag.Value == "scope-value" {
foundScopeAttr = true
}
}
assert.True(t, foundSpanAttr, "Span attribute should be present in tags")
assert.True(t, foundScopeAttr, "Scope attribute should be present in tags")
}
type Row map[string]any
type BetterFrame struct {
frame *data.Frame

Loading…
Cancel
Save