@@ -28,8 +28,7 @@ type metric interface {
2828 expose () string
2929}
3030
31- // Label represents an arbitrary information which will be attached to all
32- // metrics managed by the registry.
31+ // Label represents an arbitrary information attached to the metrics.
3332type Label struct {
3433 name string
3534 value string
@@ -54,11 +53,24 @@ func NewRegistry(
5453 application , identifier string ,
5554 additionalLabels ... Label ,
5655) * Registry {
57- labels := map [string ]string {
58- "application" : application ,
59- "identifier" : identifier ,
56+ labels := mergeLabels (
57+ map [string ]string {
58+ "application" : application ,
59+ "identifier" : identifier ,
60+ },
61+ additionalLabels ,
62+ )
63+
64+ return & Registry {
65+ labels : labels ,
66+ metrics : make (map [string ]metric ),
6067 }
68+ }
6169
70+ func mergeLabels (
71+ labels map [string ]string ,
72+ additionalLabels []Label ,
73+ ) map [string ]string {
6274 for _ , additionalLabel := range additionalLabels {
6375 if additionalLabel .name == "" || additionalLabel .value == "" {
6476 continue
@@ -71,10 +83,7 @@ func NewRegistry(
7183 labels [additionalLabel .name ] = additionalLabel .value
7284 }
7385
74- return & Registry {
75- labels : labels ,
76- metrics : make (map [string ]metric ),
77- }
86+ return labels
7887}
7988
8089// EnableServer enables the metrics server on the given port. Data will
@@ -111,28 +120,35 @@ func (r *Registry) exposeMetrics() string {
111120// NewGauge creates and registers a new gauge metric which will be exposed
112121// through the metrics server. In case a metric already exists, an error
113122// will be returned.
114- func (r * Registry ) NewGauge (name string ) (* Gauge , error ) {
123+ func (r * Registry ) NewGauge (
124+ name string ,
125+ additionalLabels ... Label ,
126+ ) (* Gauge , error ) {
115127 r .metricsMutex .Lock ()
116128 defer r .metricsMutex .Unlock ()
117129
118130 if _ , exists := r .metrics [name ]; exists {
119- return nil , fmt .Errorf ("gauge [%v] already exists" , name )
131+ return nil , fmt .Errorf ("metric [%v] already exists" , name )
120132 }
121133
122134 gauge := & Gauge {
123135 name : name ,
124- labels : r .labels ,
136+ labels : mergeLabels ( r .labels , additionalLabels ) ,
125137 }
126138
127139 r .metrics [name ] = gauge
128140 return gauge , nil
129141}
130142
143+ // NewGaugeObserver creates and registers a gauge just like `NewGauge` method
144+ // and wrap it with a ready to use observer of the provided input. This allows
145+ // to easily create self-refreshing metrics.
131146func (r * Registry ) NewGaugeObserver (
132147 name string ,
133148 input ObserverInput ,
149+ additionalLabels ... Label ,
134150) (* Observer , error ) {
135- gauge , err := r .NewGauge (name )
151+ gauge , err := r .NewGauge (name , additionalLabels ... )
136152 if err != nil {
137153 return nil , err
138154 }
@@ -142,3 +158,26 @@ func (r *Registry) NewGaugeObserver(
142158 output : gauge ,
143159 }, nil
144160}
161+
162+ // NewInfo creates and registers a new info metric which will be exposed
163+ // through the metrics server. In case a metric already exists, an error
164+ // will be returned.
165+ func (r * Registry ) NewInfo (
166+ name string ,
167+ additionalLabels ... Label ,
168+ ) (* Info , error ) {
169+ r .metricsMutex .Lock ()
170+ defer r .metricsMutex .Unlock ()
171+
172+ if _ , exists := r .metrics [name ]; exists {
173+ return nil , fmt .Errorf ("metric [%v] already exists" , name )
174+ }
175+
176+ info := & Info {
177+ name : name ,
178+ labels : mergeLabels (r .labels , additionalLabels ),
179+ }
180+
181+ r .metrics [name ] = info
182+ return info , nil
183+ }
0 commit comments