@@ -157,6 +157,7 @@ func newCompiledMetric(m Metric) (compiledMetric, error) {
157
157
compiledCommon : * cc ,
158
158
ValueFrom : valueFromPath ,
159
159
NilIsZero : m .Gauge .NilIsZero ,
160
+ labelFromKey : m .Gauge .LabelFromKey ,
160
161
}, nil
161
162
case MetricTypeInfo :
162
163
if m .Info == nil {
@@ -168,6 +169,7 @@ func newCompiledMetric(m Metric) (compiledMetric, error) {
168
169
}
169
170
return & compiledInfo {
170
171
compiledCommon : * cc ,
172
+ labelFromKey : m .Info .LabelFromKey ,
171
173
}, nil
172
174
case MetricTypeStateSet :
173
175
if m .StateSet == nil {
@@ -195,23 +197,8 @@ func newCompiledMetric(m Metric) (compiledMetric, error) {
195
197
type compiledGauge struct {
196
198
compiledCommon
197
199
ValueFrom valuePath
198
- LabelFromKey string
199
200
NilIsZero bool
200
- }
201
-
202
- func newCompiledGauge (m * MetricGauge ) (* compiledGauge , error ) {
203
- cc , err := compileCommon (m .MetricMeta )
204
- if err != nil {
205
- return nil , fmt .Errorf ("compile common: %w" , err )
206
- }
207
- valueFromPath , err := compilePath (m .ValueFrom )
208
- if err != nil {
209
- return nil , fmt .Errorf ("compile path ValueFrom: %w" , err )
210
- }
211
- return & compiledGauge {
212
- compiledCommon : * cc ,
213
- ValueFrom : valueFromPath ,
214
- }, nil
201
+ labelFromKey string
215
202
}
216
203
217
204
func (c * compiledGauge ) Values (v interface {}) (result []eachValue , errs []error ) {
@@ -227,8 +214,8 @@ func (c *compiledGauge) Values(v interface{}) (result []eachValue, errs []error)
227
214
onError (fmt .Errorf ("[%s]: %w" , key , err ))
228
215
continue
229
216
}
230
- if key != "" && c .LabelFromKey != "" {
231
- ev .Labels [c .LabelFromKey ] = key
217
+ if key != "" && c .labelFromKey != "" {
218
+ ev .Labels [c .labelFromKey ] = key
232
219
}
233
220
addPathLabels (it , c .LabelFromPath (), ev .Labels )
234
221
result = append (result , * ev )
@@ -257,22 +244,54 @@ func (c *compiledGauge) Values(v interface{}) (result []eachValue, errs []error)
257
244
258
245
type compiledInfo struct {
259
246
compiledCommon
247
+ labelFromKey string
260
248
}
261
249
262
250
func (c * compiledInfo ) Values (v interface {}) (result []eachValue , errs []error ) {
263
- if vs , isArray := v .([]interface {}); isArray {
264
- for _ , obj := range vs {
251
+ onError := func (err ... error ) {
252
+ errs = append (errs , fmt .Errorf ("%s: %v" , c .Path (), err ))
253
+ }
254
+
255
+ switch iter := v .(type ) {
256
+ case []interface {}:
257
+ for _ , obj := range iter {
265
258
ev , err := c .values (obj )
266
259
if len (err ) > 0 {
267
- errs = append ( errs , err ... )
260
+ onError ( err ... )
268
261
continue
269
262
}
270
263
result = append (result , ev ... )
271
264
}
272
- return
265
+ default :
266
+ value , err := c .values (v )
267
+ if err != nil {
268
+ onError (err ... )
269
+ break
270
+ }
271
+ // labelFromKey logic
272
+ if vv , ok := v .(map [string ]interface {}); ok {
273
+ for key , val := range vv {
274
+ if key != "" && c .labelFromKey != "" {
275
+ n , err := toFloat64 (val , false )
276
+ if err != nil {
277
+ onError (err )
278
+ continue
279
+ }
280
+ result = append (result , eachValue {
281
+ Labels : map [string ]string {
282
+ c .labelFromKey : key ,
283
+ },
284
+ Value : n ,
285
+ })
286
+ }
287
+ }
288
+ }
289
+ if len (result ) == 0 {
290
+ result = value
291
+ }
273
292
}
274
293
275
- return c . values ( v )
294
+ return
276
295
}
277
296
278
297
func (c * compiledInfo ) values (v interface {}) (result []eachValue , err []error ) {
@@ -355,7 +374,7 @@ func less(a, b map[string]string) bool {
355
374
356
375
func (c compiledGauge ) value (it interface {}) (* eachValue , error ) {
357
376
labels := make (map [string ]string )
358
- value , err := getNum (c .ValueFrom .Get (it ), c .NilIsZero )
377
+ value , err := toFloat64 (c .ValueFrom .Get (it ), c .NilIsZero )
359
378
if err != nil {
360
379
return nil , fmt .Errorf ("%s: %w" , c .ValueFrom , err )
361
380
}
@@ -478,7 +497,7 @@ func compilePath(path []string) (out valuePath, _ error) {
478
497
return nil , fmt .Errorf ("invalid list lookup: %s" , part )
479
498
}
480
499
key , val := eq [0 ], eq [1 ]
481
- num , notNum := getNum (val , false )
500
+ num , notNum := toFloat64 (val , false )
482
501
boolVal , notBool := strconv .ParseBool (val )
483
502
out = append (out , pathOp {
484
503
part : part ,
@@ -496,7 +515,7 @@ func compilePath(path []string) (out valuePath, _ error) {
496
515
}
497
516
498
517
if notNum == nil {
499
- if i , err := getNum (candidate , false ); err == nil && num == i {
518
+ if i , err := toFloat64 (candidate , false ); err == nil && num == i {
500
519
return m
501
520
}
502
521
}
@@ -522,13 +541,14 @@ func compilePath(path []string) (out valuePath, _ error) {
522
541
} else if s , ok := m .([]interface {}); ok {
523
542
i , err := strconv .Atoi (part )
524
543
if err != nil {
525
- return nil
544
+ return fmt . Errorf ( "invalid list index: %s" , part )
526
545
}
527
546
if i < 0 {
547
+ // negative index
528
548
i += len (s )
529
549
}
530
550
if ! (0 <= i && i < len (s )) {
531
- return nil
551
+ return fmt . Errorf ( "list index out of range: %s" , part )
532
552
}
533
553
return s [i ]
534
554
}
@@ -544,6 +564,7 @@ func famGen(f compiledFamily) generator.FamilyGenerator {
544
564
errLog := klog .V (f .ErrorLogV )
545
565
return generator.FamilyGenerator {
546
566
Name : f .Name ,
567
+ // TODO(@rexagod): This should be dynamic.
547
568
Type : metric .Gauge ,
548
569
Help : f .Help ,
549
570
GenerateFunc : func (obj interface {}) * metric.Family {
@@ -585,8 +606,8 @@ func scrapeValuesFor(e compiledEach, obj map[string]interface{}) ([]eachValue, [
585
606
return result , errs
586
607
}
587
608
588
- // getNum converts the value to a float64 which is the value type for any metric.
589
- func getNum (value interface {}, nilIsZero bool ) (float64 , error ) {
609
+ // toFloat64 converts the value to a float64 which is the value type for any metric.
610
+ func toFloat64 (value interface {}, nilIsZero bool ) (float64 , error ) {
590
611
var v float64
591
612
// same as bool==false but for bool pointers
592
613
if value == nil {
0 commit comments