github.com/rudderlabs/rudder-go-kit@v0.30.0/stats/internal/otel/prometheus/config.go (about) 1 package prometheus 2 3 import ( 4 "strings" 5 6 "github.com/prometheus/client_golang/prometheus" 7 "go.opentelemetry.io/otel/sdk/metric" 8 ) 9 10 type logger interface { 11 Info(args ...interface{}) 12 Error(args ...interface{}) 13 } 14 15 // config contains options for the exporter. 16 type config struct { 17 registerer prometheus.Registerer 18 disableTargetInfo bool 19 withoutUnits bool 20 aggregation metric.AggregationSelector 21 namespace string 22 logger logger 23 } 24 25 // newConfig creates a validated config configured with options. 26 func newConfig(opts ...Option) config { 27 cfg := config{} 28 for _, opt := range opts { 29 cfg = opt.apply(cfg) 30 } 31 32 if cfg.registerer == nil { 33 cfg.registerer = prometheus.DefaultRegisterer 34 } 35 if cfg.logger == nil { 36 cfg.logger = nopLogger{} 37 } 38 39 return cfg 40 } 41 42 func (cfg config) manualReaderOptions() []metric.ManualReaderOption { 43 if cfg.aggregation != nil { 44 return []metric.ManualReaderOption{ 45 metric.WithAggregationSelector(cfg.aggregation), 46 } 47 } 48 return nil 49 } 50 51 // Option sets exporter option values. 52 type Option interface { 53 apply(config) config 54 } 55 56 type optionFunc func(config) config 57 58 func (fn optionFunc) apply(cfg config) config { 59 return fn(cfg) 60 } 61 62 // WithRegisterer configures which prometheus Registerer the Exporter will 63 // register with. If no registerer is used the prometheus DefaultRegisterer is 64 // used. 65 func WithRegisterer(reg prometheus.Registerer) Option { 66 return optionFunc(func(cfg config) config { 67 cfg.registerer = reg 68 return cfg 69 }) 70 } 71 72 // WithAggregationSelector configure the Aggregation Selector the exporter will 73 // use. If no AggregationSelector is provided the DefaultAggregationSelector is 74 // used. 75 func WithAggregationSelector(agg metric.AggregationSelector) Option { 76 return optionFunc(func(cfg config) config { 77 cfg.aggregation = agg 78 return cfg 79 }) 80 } 81 82 // WithoutTargetInfo configures the Exporter to not export the resource target_info metric. 83 // If not specified, the Exporter will create a target_info metric containing 84 // the metrics' resource.Resource attributes. 85 func WithoutTargetInfo() Option { 86 return optionFunc(func(cfg config) config { 87 cfg.disableTargetInfo = true 88 return cfg 89 }) 90 } 91 92 // WithoutUnits disables exporter's addition of unit suffixes to metric names, 93 // and will also prevent unit comments from being added in OpenMetrics once 94 // unit comments are supported. 95 // 96 // By default, metric names include a unit suffix to follow Prometheus naming 97 // conventions. For example, the counter metric request.duration, with unit 98 // milliseconds would become request_duration_milliseconds_total. 99 // With this option set, the name would instead be request_duration_total. 100 func WithoutUnits() Option { 101 return optionFunc(func(cfg config) config { 102 cfg.withoutUnits = true 103 return cfg 104 }) 105 } 106 107 // WithNamespace configures the Exporter to prefix metric with the given namespace. 108 // Metadata metrics such as target_info and otel_scope_info are not prefixed since these 109 // have special behavior based on their name. 110 func WithNamespace(ns string) Option { 111 return optionFunc(func(cfg config) config { 112 ns = sanitizeName(ns) 113 if !strings.HasSuffix(ns, "_") { 114 // namespace and metric names should be separated with an underscore, 115 // adds a trailing underscore if there is not one already. 116 ns = ns + "_" 117 } 118 119 cfg.namespace = ns 120 return cfg 121 }) 122 } 123 124 // WithLogger enables the logger 125 func WithLogger(l logger) Option { 126 return optionFunc(func(cfg config) config { 127 cfg.logger = l 128 return cfg 129 }) 130 } 131 132 type nopLogger struct{} 133 134 func (nopLogger) Info(...interface{}) {} 135 func (nopLogger) Error(...interface{}) {}