@@ -31,6 +31,7 @@ import (
3131 "github.com/cespare/xxhash/v2"
3232 dto "github.com/prometheus/client_model/go"
3333 "github.com/prometheus/common/expfmt"
34+ "github.com/prometheus/common/model"
3435 "google.golang.org/protobuf/proto"
3536)
3637
@@ -62,14 +63,27 @@ func init() {
6263 MustRegister (NewGoCollector ())
6364}
6465
66+ type RegistryOption func (* Registry )
67+
68+ func WithNameValidationScheme (scheme model.ValidationScheme ) RegistryOption {
69+ return func (r * Registry ) {
70+ r .nameValidationScheme = scheme
71+ }
72+ }
73+
6574// NewRegistry creates a new vanilla Registry without any Collectors
6675// pre-registered.
67- func NewRegistry () * Registry {
68- return & Registry {
69- collectorsByID : map [uint64 ]Collector {},
70- descIDs : map [uint64 ]struct {}{},
71- dimHashesByName : map [string ]uint64 {},
76+ func NewRegistry (opts ... RegistryOption ) * Registry {
77+ reg := & Registry {
78+ collectorsByID : map [uint64 ]Collector {},
79+ descIDs : map [uint64 ]struct {}{},
80+ dimHashesByName : map [string ]uint64 {},
81+ nameValidationScheme : model .UTF8Validation ,
82+ }
83+ for _ , opt := range opts {
84+ opt (reg )
7285 }
86+ return reg
7387}
7488
7589// NewPedanticRegistry returns a registry that checks during collection if each
@@ -264,6 +278,7 @@ type Registry struct {
264278 dimHashesByName map [string ]uint64
265279 uncheckedCollectors []Collector
266280 pedanticChecksEnabled bool
281+ nameValidationScheme model.ValidationScheme
267282}
268283
269284// Register implements Registerer.
@@ -503,6 +518,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
503518 metric , metricFamiliesByName ,
504519 metricHashes ,
505520 registeredDescIDs ,
521+ r .nameValidationScheme ,
506522 ))
507523 case metric , ok := <- umc :
508524 if ! ok {
@@ -513,6 +529,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
513529 metric , metricFamiliesByName ,
514530 metricHashes ,
515531 nil ,
532+ r .nameValidationScheme ,
516533 ))
517534 default :
518535 if goroutineBudget <= 0 || len (checkedCollectors )+ len (uncheckedCollectors ) == 0 {
@@ -530,6 +547,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
530547 metric , metricFamiliesByName ,
531548 metricHashes ,
532549 registeredDescIDs ,
550+ r .nameValidationScheme ,
533551 ))
534552 case metric , ok := <- umc :
535553 if ! ok {
@@ -540,6 +558,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
540558 metric , metricFamiliesByName ,
541559 metricHashes ,
542560 nil ,
561+ r .nameValidationScheme ,
543562 ))
544563 }
545564 break
@@ -622,6 +641,7 @@ func processMetric(
622641 metricFamiliesByName map [string ]* dto.MetricFamily ,
623642 metricHashes map [uint64 ]struct {},
624643 registeredDescIDs map [uint64 ]struct {},
644+ nameValidationScheme model.ValidationScheme ,
625645) error {
626646 desc := metric .Desc ()
627647 // Wrapped metrics collected by an unchecked Collector can have an
@@ -705,7 +725,7 @@ func processMetric(
705725 }
706726 metricFamiliesByName [desc .fqName ] = metricFamily
707727 }
708- if err := checkMetricConsistency (metricFamily , dtoMetric , metricHashes ); err != nil {
728+ if err := checkMetricConsistency (metricFamily , dtoMetric , metricHashes , nameValidationScheme ); err != nil {
709729 return err
710730 }
711731 if registeredDescIDs != nil {
@@ -791,7 +811,8 @@ func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) {
791811 metricFamiliesByName [mf .GetName ()] = existingMF
792812 }
793813 for _ , m := range mf .Metric {
794- if err := checkMetricConsistency (existingMF , m , metricHashes ); err != nil {
814+ // TODO(juliusmh): hardcoded UTF8 validation
815+ if err := checkMetricConsistency (existingMF , m , metricHashes , model .UTF8Validation ); err != nil {
795816 errs = append (errs , err )
796817 continue
797818 }
@@ -870,6 +891,7 @@ func checkMetricConsistency(
870891 metricFamily * dto.MetricFamily ,
871892 dtoMetric * dto.Metric ,
872893 metricHashes map [uint64 ]struct {},
894+ nameValidationScheme model.ValidationScheme ,
873895) error {
874896 name := metricFamily .GetName ()
875897
@@ -894,7 +916,7 @@ func checkMetricConsistency(
894916 name , dtoMetric , labelName ,
895917 )
896918 }
897- if ! checkLabelName (labelName ) {
919+ if ! checkLabelName (labelName , nameValidationScheme ) {
898920 return fmt .Errorf (
899921 "collected metric %q { %s} has a label with an invalid name: %s" ,
900922 name , dtoMetric , labelName ,
0 commit comments