@@ -229,7 +229,13 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
229
229
e .perfEventArrayCollectors = append (e .perfEventArrayCollectors , perfSink )
230
230
}
231
231
232
- addDescs (cfg .Name , counter .Name , counter .Help , counter .Labels )
232
+ if counter .Values != nil {
233
+ for _ , value := range counter .Values {
234
+ addDescs (cfg .Name , value .Name , value .Help , counter .Labels )
235
+ }
236
+ } else {
237
+ addDescs (cfg .Name , counter .Name , counter .Help , counter .Labels )
238
+ }
233
239
}
234
240
235
241
for _ , histogram := range cfg .Metrics .Histograms {
@@ -298,10 +304,14 @@ func (e *Exporter) collectCounters(ch chan<- prometheus.Metric) {
298
304
299
305
aggregatedMapValues := aggregateMapValues (mapValues )
300
306
301
- desc := e.descs [cfg.Name ][counter.Name ]
302
-
303
307
for _ , metricValue := range aggregatedMapValues {
304
- ch <- prometheus .MustNewConstMetric (desc , prometheus .CounterValue , metricValue .value , metricValue .labels ... )
308
+ if counter .Values != nil {
309
+ for i , value := range counter .Values {
310
+ ch <- prometheus .MustNewConstMetric (e.descs [cfg.Name ][value.Name ], prometheus .CounterValue , metricValue .value [i ], metricValue .labels ... )
311
+ }
312
+ } else {
313
+ ch <- prometheus .MustNewConstMetric (e.descs [cfg.Name ][counter.Name ], prometheus .CounterValue , metricValue .value [0 ], metricValue .labels ... )
314
+ }
305
315
}
306
316
}
307
317
}
@@ -351,7 +361,7 @@ func (e *Exporter) collectHistograms(ch chan<- prometheus.Metric) {
351
361
break
352
362
}
353
363
354
- histograms [key ].buckets [float64 (leUint )] = uint64 (metricValue .value )
364
+ histograms [key ].buckets [float64 (leUint )] = uint64 (metricValue .value [ 0 ] )
355
365
}
356
366
357
367
if skip {
@@ -492,29 +502,33 @@ func (e *Exporter) MapsHandler(w http.ResponseWriter, r *http.Request) {
492
502
}
493
503
494
504
func validateMaps (module * libbpfgo.Module , cfg config.Config ) error {
495
- maps := [] string {}
505
+ sizes := map [ string ] int {}
496
506
497
507
for _ , counter := range cfg .Metrics .Counters {
498
508
if counter .Name != "" {
499
- maps = append (maps , counter .Name )
509
+ if counter .Values != nil {
510
+ sizes [counter .Name ] = len (counter .Values ) * 8
511
+ } else {
512
+ sizes [counter .Name ] = 8
513
+ }
500
514
}
501
515
}
502
516
503
517
for _ , histogram := range cfg .Metrics .Histograms {
504
518
if histogram .Name != "" {
505
- maps = append ( maps , histogram .Name )
519
+ sizes [ histogram .Name ] = 8
506
520
}
507
521
}
508
522
509
- for _ , name := range maps {
523
+ for name , expected := range sizes {
510
524
m , err := module .GetMap (name )
511
525
if err != nil {
512
526
return fmt .Errorf ("failed to get map %q: %v" , name , err )
513
527
}
514
528
515
529
valueSize := m .ValueSize ()
516
- if valueSize != 8 {
517
- return fmt .Errorf ("value size for map %q is not expected 8 bytes (u64), it is %d bytes" , name , valueSize )
530
+ if valueSize != expected {
531
+ return fmt .Errorf ("value size for map %q is not expected %d bytes (8 bytes per u64 value ), it is %d bytes" , name , expected , valueSize )
518
532
}
519
533
}
520
534
@@ -540,7 +554,9 @@ func aggregateMapValues(values []metricValue) []aggregatedMetricValue {
540
554
value : value .value ,
541
555
}
542
556
} else {
543
- existing .value += value .value
557
+ for i := range existing .value {
558
+ existing .value [i ] += value .value [i ]
559
+ }
544
560
}
545
561
}
546
562
@@ -604,17 +620,17 @@ func readMapValues(m *libbpfgo.BPFMap, labels []config.Label) ([]metricValue, er
604
620
return metricValues , nil
605
621
}
606
622
607
- func mapValue (m * libbpfgo.BPFMap , key []byte ) (float64 , error ) {
623
+ func mapValue (m * libbpfgo.BPFMap , key []byte ) ([] float64 , error ) {
608
624
v , err := m .GetValue (unsafe .Pointer (& key [0 ]))
609
625
if err != nil {
610
- return 0.0 , err
626
+ return [] float64 { 0.0 } , err
611
627
}
612
628
613
629
return decodeValue (v ), nil
614
630
}
615
631
616
- func mapValuePerCPU (m * libbpfgo.BPFMap , key []byte ) ([]float64 , error ) {
617
- values := []float64 {}
632
+ func mapValuePerCPU (m * libbpfgo.BPFMap , key []byte ) ([][] float64 , error ) {
633
+ values := [][] float64 {}
618
634
619
635
size := m .ValueSize ()
620
636
value := make ([]byte , size * runtime .NumCPU ())
@@ -631,8 +647,14 @@ func mapValuePerCPU(m *libbpfgo.BPFMap, key []byte) ([]float64, error) {
631
647
}
632
648
633
649
// Assuming counter's value type is always u64
634
- func decodeValue (value []byte ) float64 {
635
- return float64 (util .GetHostByteOrder ().Uint64 (value ))
650
+ func decodeValue (value []byte ) []float64 {
651
+ values := make ([]float64 , len (value )/ 8 )
652
+
653
+ for i := range values {
654
+ values [i ] = float64 (util .GetHostByteOrder ().Uint64 (value [i * 8 :]))
655
+ }
656
+
657
+ return values
636
658
}
637
659
638
660
// metricValue is a row in a kernel map
@@ -642,13 +664,13 @@ type metricValue struct {
642
664
// labels are decoded from the raw key
643
665
labels []string
644
666
// value is the kernel map value
645
- value float64
667
+ value [] float64
646
668
}
647
669
648
670
// aggregatedMetricValue is a value after aggregation of equal label sets
649
671
type aggregatedMetricValue struct {
650
672
// labels are decoded from the raw key
651
673
labels []string
652
674
// value is the kernel map value
653
- value float64
675
+ value [] float64
654
676
}
0 commit comments