@@ -11,8 +11,6 @@ import (
11
11
"slices"
12
12
"strings"
13
13
"sync"
14
- "unicode"
15
- "unicode/utf8"
16
14
17
15
"github.com/prometheus/client_golang/prometheus"
18
16
dto "github.com/prometheus/client_model/go"
@@ -318,7 +316,7 @@ func getAttrs(attrs attribute.Set, ks, vs [2]string, resourceKV keyVals) ([]stri
318
316
keysMap := make (map [string ][]string )
319
317
for itr .Next () {
320
318
kv := itr .Attribute ()
321
- key := strings . Map ( sanitizeRune , string (kv .Key ))
319
+ key := model . EscapeName ( string (kv .Key ), model . NameEscapingScheme )
322
320
if _ , ok := keysMap [key ]; ! ok {
323
321
keysMap [key ] = []string {kv .Value .Emit ()}
324
322
} else {
@@ -358,13 +356,6 @@ func createScopeInfoMetric(scope instrumentation.Scope) (prometheus.Metric, erro
358
356
return prometheus .NewConstMetric (desc , prometheus .GaugeValue , float64 (1 ), scope .Name , scope .Version )
359
357
}
360
358
361
- func sanitizeRune (r rune ) rune {
362
- if unicode .IsLetter (r ) || unicode .IsDigit (r ) || r == ':' || r == '_' {
363
- return r
364
- }
365
- return '_'
366
- }
367
-
368
359
var unitSuffixes = map [string ]string {
369
360
// Time
370
361
"d" : "_days" ,
@@ -406,7 +397,7 @@ func (c *collector) getName(m metricdata.Metrics, typ *dto.MetricType) string {
406
397
name := m .Name
407
398
if model .NameValidationScheme != model .UTF8Validation {
408
399
// Only sanitize if prometheus does not support UTF-8.
409
- name = sanitizeName ( m . Name )
400
+ name = model . EscapeName ( name , model . NameEscapingScheme )
410
401
}
411
402
addCounterSuffix := ! c .withoutCounterSuffixes && * typ == dto .MetricType_COUNTER
412
403
if addCounterSuffix {
@@ -426,59 +417,6 @@ func (c *collector) getName(m metricdata.Metrics, typ *dto.MetricType) string {
426
417
return name
427
418
}
428
419
429
- func sanitizeName (n string ) string {
430
- // This algorithm is based on strings.Map from Go 1.19.
431
- const replacement = '_'
432
-
433
- valid := func (i int , r rune ) bool {
434
- // Taken from
435
- // https://github.com/prometheus/common/blob/dfbc25bd00225c70aca0d94c3c4bb7744f28ace0/model/metric.go#L92-L102
436
- if (r >= 'a' && r <= 'z' ) || (r >= 'A' && r <= 'Z' ) || r == '_' || r == ':' || (r >= '0' && r <= '9' && i > 0 ) {
437
- return true
438
- }
439
- return false
440
- }
441
-
442
- // This output buffer b is initialized on demand, the first time a
443
- // character needs to be replaced.
444
- var b strings.Builder
445
- for i , c := range n {
446
- if valid (i , c ) {
447
- continue
448
- }
449
-
450
- if i == 0 && c >= '0' && c <= '9' {
451
- // Prefix leading number with replacement character.
452
- b .Grow (len (n ) + 1 )
453
- _ = b .WriteByte (byte (replacement ))
454
- break
455
- }
456
- b .Grow (len (n ))
457
- _ , _ = b .WriteString (n [:i ])
458
- _ = b .WriteByte (byte (replacement ))
459
- width := utf8 .RuneLen (c )
460
- n = n [i + width :]
461
- break
462
- }
463
-
464
- // Fast path for unchanged input.
465
- if b .Cap () == 0 { // b.Grow was not called above.
466
- return n
467
- }
468
-
469
- for _ , c := range n {
470
- // Due to inlining, it is more performant to invoke WriteByte rather then
471
- // WriteRune.
472
- if valid (1 , c ) { // We are guaranteed to not be at the start.
473
- _ = b .WriteByte (byte (c ))
474
- } else {
475
- _ = b .WriteByte (byte (replacement ))
476
- }
477
- }
478
-
479
- return b .String ()
480
- }
481
-
482
420
func (c * collector ) metricType (m metricdata.Metrics ) * dto.MetricType {
483
421
switch v := m .Data .(type ) {
484
422
case metricdata.Histogram [int64 ], metricdata.Histogram [float64 ]:
0 commit comments