@@ -8,6 +8,7 @@ package tracestore
8
8
9
9
import (
10
10
"encoding/hex"
11
+ "strings"
11
12
12
13
"go.opentelemetry.io/collector/pdata/pcommon"
13
14
"go.opentelemetry.io/collector/pdata/ptrace"
@@ -29,7 +30,12 @@ const (
29
30
30
31
// ToDBModel translates internal trace data into the DB Spans.
31
32
// Returns slice of translated DB Spans and error if translation failed.
32
- func ToDBModel (td ptrace.Traces ) []dbmodel.Span {
33
+ func ToDBModel (td ptrace.Traces , allTagsAsObject bool , tagKeysAsFields []string , tagDotReplacement string ) []dbmodel.Span {
34
+ tags := map [string ]bool {}
35
+ for _ , k := range tagKeysAsFields {
36
+ tags [k ] = true
37
+ }
38
+ toDb := newToDBModel (allTagsAsObject , tags , tagDotReplacement )
33
39
resourceSpans := td .ResourceSpans ()
34
40
35
41
if resourceSpans .Len () == 0 {
@@ -39,7 +45,7 @@ func ToDBModel(td ptrace.Traces) []dbmodel.Span {
39
45
batches := make ([]dbmodel.Span , 0 , resourceSpans .Len ())
40
46
for i := 0 ; i < resourceSpans .Len (); i ++ {
41
47
rs := resourceSpans .At (i )
42
- batch := resourceSpansToDbSpans (rs )
48
+ batch := toDb . resourceSpansToDbSpans (rs )
43
49
if batch != nil {
44
50
batches = append (batches , batch ... )
45
51
}
@@ -48,31 +54,45 @@ func ToDBModel(td ptrace.Traces) []dbmodel.Span {
48
54
return batches
49
55
}
50
56
51
- func resourceSpansToDbSpans (resourceSpans ptrace.ResourceSpans ) []dbmodel.Span {
57
+ type toDBModel struct {
58
+ allTagsAsFields bool
59
+ tagKeysAsFields map [string ]bool
60
+ tagDotReplacement string
61
+ }
62
+
63
+ func newToDBModel (allTagsAsFields bool , tagKeysAsFields map [string ]bool , tagDotReplacement string ) * toDBModel {
64
+ return & toDBModel {
65
+ allTagsAsFields : allTagsAsFields ,
66
+ tagKeysAsFields : tagKeysAsFields ,
67
+ tagDotReplacement : tagDotReplacement ,
68
+ }
69
+ }
70
+
71
+ func (t * toDBModel ) resourceSpansToDbSpans (resourceSpans ptrace.ResourceSpans ) []dbmodel.Span {
52
72
resource := resourceSpans .Resource ()
53
73
scopeSpans := resourceSpans .ScopeSpans ()
54
74
55
75
if scopeSpans .Len () == 0 {
56
76
return []dbmodel.Span {}
57
77
}
58
78
59
- process := resourceToDbProcess (resource )
79
+ process := t . resourceToDbProcess (resource )
60
80
61
81
// Approximate the number of the spans as the number of the spans in the first
62
82
// instrumentation library info.
63
83
dbSpans := make ([]dbmodel.Span , 0 , scopeSpans .At (0 ).Spans ().Len ())
64
84
65
85
for _ , scopeSpan := range scopeSpans .All () {
66
86
for _ , span := range scopeSpan .Spans ().All () {
67
- dbSpan := spanToDbSpan (span , scopeSpan .Scope (), process )
87
+ dbSpan := t . spanToDbSpan (span , scopeSpan .Scope (), process )
68
88
dbSpans = append (dbSpans , dbSpan )
69
89
}
70
90
}
71
91
72
92
return dbSpans
73
93
}
74
94
75
- func resourceToDbProcess (resource pcommon.Resource ) dbmodel.Process {
95
+ func ( t * toDBModel ) resourceToDbProcess (resource pcommon.Resource ) dbmodel.Process {
76
96
process := dbmodel.Process {}
77
97
attrs := resource .Attributes ()
78
98
if attrs .Len () == 0 {
@@ -87,10 +107,31 @@ func resourceToDbProcess(resource pcommon.Resource) dbmodel.Process {
87
107
}
88
108
tags = append (tags , attributeToDbTag (key , attr ))
89
109
}
90
- process .Tags = tags
110
+ tagSlice , tagMap := t .embedTagDotReplacement (tags )
111
+ process .Tags = tagSlice
112
+ process .Tag = tagMap
91
113
return process
92
114
}
93
115
116
+ func (t * toDBModel ) embedTagDotReplacement (keyValues []dbmodel.KeyValue ) ([]dbmodel.KeyValue , map [string ]any ) {
117
+ var tagsMap map [string ]any
118
+ var kvs []dbmodel.KeyValue
119
+ for _ , kv := range keyValues {
120
+ if kv .Type != dbmodel .BinaryType && (t .allTagsAsFields || t .tagKeysAsFields [kv .Key ]) {
121
+ if tagsMap == nil {
122
+ tagsMap = map [string ]any {}
123
+ }
124
+ tagsMap [strings .ReplaceAll (kv .Key , "." , t .tagDotReplacement )] = kv .Value
125
+ } else {
126
+ kvs = append (kvs , kv )
127
+ }
128
+ }
129
+ if kvs == nil {
130
+ kvs = make ([]dbmodel.KeyValue , 0 )
131
+ }
132
+ return kvs , tagsMap
133
+ }
134
+
94
135
func appendTagsFromAttributes (dest []dbmodel.KeyValue , attrs pcommon.Map ) []dbmodel.KeyValue {
95
136
for key , attr := range attrs .All () {
96
137
dest = append (dest , attributeToDbTag (key , attr ))
@@ -123,10 +164,12 @@ func attributeToDbTag(key string, attr pcommon.Value) dbmodel.KeyValue {
123
164
return tag
124
165
}
125
166
126
- func spanToDbSpan (span ptrace.Span , libraryTags pcommon.InstrumentationScope , process dbmodel.Process ) dbmodel.Span {
167
+ func ( t * toDBModel ) spanToDbSpan (span ptrace.Span , libraryTags pcommon.InstrumentationScope , process dbmodel.Process ) dbmodel.Span {
127
168
traceID := dbmodel .TraceID (span .TraceID ().String ())
128
169
parentSpanID := dbmodel .SpanID (span .ParentSpanID ().String ())
129
170
startTime := span .StartTimestamp ().AsTime ()
171
+ tags := getDbSpanTags (span , libraryTags )
172
+ tagSlice , tagMap := t .embedTagDotReplacement (tags )
130
173
return dbmodel.Span {
131
174
TraceID : traceID ,
132
175
SpanID : dbmodel .SpanID (span .SpanID ().String ()),
@@ -135,7 +178,8 @@ func spanToDbSpan(span ptrace.Span, libraryTags pcommon.InstrumentationScope, pr
135
178
StartTime : model .TimeAsEpochMicroseconds (startTime ),
136
179
StartTimeMillis : model .TimeAsEpochMicroseconds (startTime ) / 1000 ,
137
180
Duration : model .DurationAsMicroseconds (span .EndTimestamp ().AsTime ().Sub (startTime )),
138
- Tags : getDbSpanTags (span , libraryTags ),
181
+ Tags : tagSlice ,
182
+ Tag : tagMap ,
139
183
Logs : spanEventsToDbSpanLogs (span .Events ()),
140
184
Process : process ,
141
185
Flags : span .Flags (),
0 commit comments