@@ -130,7 +130,14 @@ func addExemplar(tsMap map[string]*prompb.TimeSeries, bucketBounds []bucketBound
130
130
// the label slice should not contain duplicate label names; this method sorts the slice by label name before creating
131
131
// the signature.
132
132
func timeSeriesSignature (datatype string , labels * []prompb.Label ) string {
133
+ length := len (datatype )
134
+
135
+ for _ , lb := range * labels {
136
+ length += 2 + len (lb .GetName ()) + len (lb .GetValue ())
137
+ }
138
+
133
139
b := strings.Builder {}
140
+ b .Grow (length )
134
141
b .WriteString (datatype )
135
142
136
143
sort .Sort (ByLabelName (* labels ))
@@ -149,8 +156,22 @@ func timeSeriesSignature(datatype string, labels *[]prompb.Label) string {
149
156
// Unpaired string value is ignored. String pairs overwrites OTLP labels if collision happens, and the overwrite is
150
157
// logged. Resultant label names are sanitized.
151
158
func createAttributes (resource pcommon.Resource , attributes pcommon.Map , externalLabels map [string ]string , extras ... string ) []prompb.Label {
159
+ serviceName , haveServiceName := resource .Attributes ().Get (conventions .AttributeServiceName )
160
+ instance , haveInstanceID := resource .Attributes ().Get (conventions .AttributeServiceInstanceID )
161
+
162
+ // Calculate the maximum possible number of labels we could return so we can preallocate l
163
+ maxLabelCount := attributes .Len () + len (externalLabels ) + len (extras )/ 2
164
+
165
+ if haveServiceName {
166
+ maxLabelCount ++
167
+ }
168
+
169
+ if haveInstanceID {
170
+ maxLabelCount ++
171
+ }
172
+
152
173
// map ensures no duplicate label name
153
- l := map [string ]prompb. Label {}
174
+ l := make ( map [string ]string , maxLabelCount )
154
175
155
176
// Ensure attributes are sorted by key for consistent merging of keys which
156
177
// collide when sanitized.
@@ -164,44 +185,31 @@ func createAttributes(resource pcommon.Resource, attributes pcommon.Map, externa
164
185
for _ , label := range labels {
165
186
var finalKey = prometheustranslator .NormalizeLabel (label .Name )
166
187
if existingLabel , alreadyExists := l [finalKey ]; alreadyExists {
167
- existingLabel .Value = existingLabel .Value + ";" + label .Value
168
- l [finalKey ] = existingLabel
188
+ l [finalKey ] = existingLabel + ";" + label .Value
169
189
} else {
170
- l [finalKey ] = prompb.Label {
171
- Name : finalKey ,
172
- Value : label .Value ,
173
- }
190
+ l [finalKey ] = label .Value
174
191
}
175
192
}
176
193
177
194
// Map service.name + service.namespace to job
178
- if serviceName , ok := resource . Attributes (). Get ( conventions . AttributeServiceName ); ok {
195
+ if haveServiceName {
179
196
val := serviceName .AsString ()
180
197
if serviceNamespace , ok := resource .Attributes ().Get (conventions .AttributeServiceNamespace ); ok {
181
198
val = fmt .Sprintf ("%s/%s" , serviceNamespace .AsString (), val )
182
199
}
183
- l [model .JobLabel ] = prompb.Label {
184
- Name : model .JobLabel ,
185
- Value : val ,
186
- }
200
+ l [model .JobLabel ] = val
187
201
}
188
202
// Map service.instance.id to instance
189
- if instance , ok := resource .Attributes ().Get (conventions .AttributeServiceInstanceID ); ok {
190
- l [model .InstanceLabel ] = prompb.Label {
191
- Name : model .InstanceLabel ,
192
- Value : instance .AsString (),
193
- }
203
+ if haveInstanceID {
204
+ l [model .InstanceLabel ] = instance .AsString ()
194
205
}
195
206
for key , value := range externalLabels {
196
207
// External labels have already been sanitized
197
208
if _ , alreadyExists := l [key ]; alreadyExists {
198
209
// Skip external labels if they are overridden by metric attributes
199
210
continue
200
211
}
201
- l [key ] = prompb.Label {
202
- Name : key ,
203
- Value : value ,
204
- }
212
+ l [key ] = value
205
213
}
206
214
207
215
for i := 0 ; i < len (extras ); i += 2 {
@@ -217,15 +225,12 @@ func createAttributes(resource pcommon.Resource, attributes pcommon.Map, externa
217
225
if ! (len (name ) > 4 && name [:2 ] == "__" && name [len (name )- 2 :] == "__" ) {
218
226
name = prometheustranslator .NormalizeLabel (name )
219
227
}
220
- l [name ] = prompb.Label {
221
- Name : name ,
222
- Value : extras [i + 1 ],
223
- }
228
+ l [name ] = extras [i + 1 ]
224
229
}
225
230
226
231
s := make ([]prompb.Label , 0 , len (l ))
227
- for _ , lb := range l {
228
- s = append (s , lb )
232
+ for k , v := range l {
233
+ s = append (s , prompb. Label { Name : k , Value : v } )
229
234
}
230
235
231
236
return s
@@ -253,6 +258,21 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
253
258
timestamp := convertTimeStamp (pt .Timestamp ())
254
259
// sum, count, and buckets of the histogram should append suffix to baseName
255
260
baseName := prometheustranslator .BuildCompliantName (metric , settings .Namespace , settings .AddMetricSuffixes )
261
+ baseLabels := createAttributes (resource , pt .Attributes (), settings .ExternalLabels )
262
+
263
+ createLabels := func (nameSuffix string , extras ... string ) []prompb.Label {
264
+ extraLabelCount := len (extras ) / 2
265
+ labels := make ([]prompb.Label , len (baseLabels ), len (baseLabels )+ extraLabelCount + 1 ) // +1 for name
266
+ copy (labels , baseLabels )
267
+
268
+ for extrasIdx := 0 ; extrasIdx < extraLabelCount ; extrasIdx ++ {
269
+ labels = append (labels , prompb.Label {Name : extras [extrasIdx ], Value : extras [extrasIdx + 1 ]})
270
+ }
271
+
272
+ labels = append (labels , prompb.Label {Name : nameStr , Value : baseName + nameSuffix })
273
+
274
+ return labels
275
+ }
256
276
257
277
// If the sum is unset, it indicates the _sum metric point should be
258
278
// omitted
@@ -266,7 +286,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
266
286
sum .Value = math .Float64frombits (value .StaleNaN )
267
287
}
268
288
269
- sumlabels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName + sumStr )
289
+ sumlabels := createLabels ( sumStr )
270
290
addSample (tsMap , sum , sumlabels , metric .Type ().String ())
271
291
272
292
}
@@ -280,7 +300,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
280
300
count .Value = math .Float64frombits (value .StaleNaN )
281
301
}
282
302
283
- countlabels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName + countStr )
303
+ countlabels := createLabels ( countStr )
284
304
addSample (tsMap , count , countlabels , metric .Type ().String ())
285
305
286
306
// cumulative count for conversion to cumulative histogram
@@ -302,7 +322,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
302
322
bucket .Value = math .Float64frombits (value .StaleNaN )
303
323
}
304
324
boundStr := strconv .FormatFloat (bound , 'f' , - 1 , 64 )
305
- labels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName + bucketStr , leStr , boundStr )
325
+ labels := createLabels ( bucketStr , leStr , boundStr )
306
326
sig := addSample (tsMap , bucket , labels , metric .Type ().String ())
307
327
308
328
bucketBounds = append (bucketBounds , bucketBoundsData {sig : sig , bound : bound })
@@ -316,7 +336,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
316
336
} else {
317
337
infBucket .Value = float64 (pt .Count ())
318
338
}
319
- infLabels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName + bucketStr , leStr , pInfStr )
339
+ infLabels := createLabels ( bucketStr , leStr , pInfStr )
320
340
sig := addSample (tsMap , infBucket , infLabels , metric .Type ().String ())
321
341
322
342
bucketBounds = append (bucketBounds , bucketBoundsData {sig : sig , bound : math .Inf (1 )})
@@ -325,14 +345,8 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
325
345
// add _created time series if needed
326
346
startTimestamp := pt .StartTimestamp ()
327
347
if settings .ExportCreatedMetric && startTimestamp != 0 {
328
- createdLabels := createAttributes (
329
- resource ,
330
- pt .Attributes (),
331
- settings .ExternalLabels ,
332
- nameStr ,
333
- baseName + createdSuffix ,
334
- )
335
- addCreatedTimeSeriesIfNeeded (tsMap , createdLabels , startTimestamp , metric .Type ().String ())
348
+ labels := createLabels (createdSuffix )
349
+ addCreatedTimeSeriesIfNeeded (tsMap , labels , startTimestamp , metric .Type ().String ())
336
350
}
337
351
}
338
352
@@ -443,6 +457,22 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
443
457
timestamp := convertTimeStamp (pt .Timestamp ())
444
458
// sum and count of the summary should append suffix to baseName
445
459
baseName := prometheustranslator .BuildCompliantName (metric , settings .Namespace , settings .AddMetricSuffixes )
460
+ baseLabels := createAttributes (resource , pt .Attributes (), settings .ExternalLabels )
461
+
462
+ createLabels := func (name string , extras ... string ) []prompb.Label {
463
+ extraLabelCount := len (extras ) / 2
464
+ labels := make ([]prompb.Label , len (baseLabels ), len (baseLabels )+ extraLabelCount + 1 ) // +1 for name
465
+ copy (labels , baseLabels )
466
+
467
+ for extrasIdx := 0 ; extrasIdx < extraLabelCount ; extrasIdx ++ {
468
+ labels = append (labels , prompb.Label {Name : extras [extrasIdx ], Value : extras [extrasIdx + 1 ]})
469
+ }
470
+
471
+ labels = append (labels , prompb.Label {Name : nameStr , Value : name })
472
+
473
+ return labels
474
+ }
475
+
446
476
// treat sum as a sample in an individual TimeSeries
447
477
sum := & prompb.Sample {
448
478
Value : pt .Sum (),
@@ -451,7 +481,7 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
451
481
if pt .Flags ().NoRecordedValue () {
452
482
sum .Value = math .Float64frombits (value .StaleNaN )
453
483
}
454
- sumlabels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName + sumStr )
484
+ sumlabels := createLabels ( baseName + sumStr )
455
485
addSample (tsMap , sum , sumlabels , metric .Type ().String ())
456
486
457
487
// treat count as a sample in an individual TimeSeries
@@ -462,7 +492,7 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
462
492
if pt .Flags ().NoRecordedValue () {
463
493
count .Value = math .Float64frombits (value .StaleNaN )
464
494
}
465
- countlabels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName + countStr )
495
+ countlabels := createLabels ( baseName + countStr )
466
496
addSample (tsMap , count , countlabels , metric .Type ().String ())
467
497
468
498
// process each percentile/quantile
@@ -476,20 +506,14 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
476
506
quantile .Value = math .Float64frombits (value .StaleNaN )
477
507
}
478
508
percentileStr := strconv .FormatFloat (qt .Quantile (), 'f' , - 1 , 64 )
479
- qtlabels := createAttributes ( resource , pt . Attributes (), settings . ExternalLabels , nameStr , baseName , quantileStr , percentileStr )
509
+ qtlabels := createLabels ( baseName , quantileStr , percentileStr )
480
510
addSample (tsMap , quantile , qtlabels , metric .Type ().String ())
481
511
}
482
512
483
513
// add _created time series if needed
484
514
startTimestamp := pt .StartTimestamp ()
485
515
if settings .ExportCreatedMetric && startTimestamp != 0 {
486
- createdLabels := createAttributes (
487
- resource ,
488
- pt .Attributes (),
489
- settings .ExternalLabels ,
490
- nameStr ,
491
- baseName + createdSuffix ,
492
- )
516
+ createdLabels := createLabels (baseName + createdSuffix )
493
517
addCreatedTimeSeriesIfNeeded (tsMap , createdLabels , startTimestamp , metric .Type ().String ())
494
518
}
495
519
}
0 commit comments