@@ -234,7 +234,13 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
234
234
e .perfEventArrayCollectors = append (e .perfEventArrayCollectors , perfSink )
235
235
}
236
236
237
- addDescs (cfg .Name , counter .Name , counter .Help , counter .Labels )
237
+ if counter .Values != nil {
238
+ for _ , value := range counter .Values {
239
+ addDescs (cfg .Name , value .Name , value .Help , counter .Labels )
240
+ }
241
+ } else {
242
+ addDescs (cfg .Name , counter .Name , counter .Help , counter .Labels )
243
+ }
238
244
}
239
245
240
246
for _ , histogram := range cfg .Metrics .Histograms {
@@ -303,10 +309,14 @@ func (e *Exporter) collectCounters(ch chan<- prometheus.Metric) {
303
309
304
310
aggregatedMapValues := aggregateMapValues (mapValues )
305
311
306
- desc := e.descs [cfg.Name ][counter.Name ]
307
-
308
312
for _ , metricValue := range aggregatedMapValues {
309
- ch <- prometheus .MustNewConstMetric (desc , prometheus .CounterValue , metricValue .value , metricValue .labels ... )
313
+ if counter .Values != nil {
314
+ for i , value := range counter .Values {
315
+ ch <- prometheus .MustNewConstMetric (e.descs [cfg.Name ][value.Name ], prometheus .CounterValue , metricValue .value [i ], metricValue .labels ... )
316
+ }
317
+ } else {
318
+ ch <- prometheus .MustNewConstMetric (e.descs [cfg.Name ][counter.Name ], prometheus .CounterValue , metricValue .value [0 ], metricValue .labels ... )
319
+ }
310
320
}
311
321
}
312
322
}
@@ -356,7 +366,7 @@ func (e *Exporter) collectHistograms(ch chan<- prometheus.Metric) {
356
366
break
357
367
}
358
368
359
- histograms [key ].buckets [float64 (leUint )] = uint64 (metricValue .value )
369
+ histograms [key ].buckets [float64 (leUint )] = uint64 (metricValue .value [ 0 ] )
360
370
}
361
371
362
372
if skip {
@@ -497,29 +507,33 @@ func (e *Exporter) MapsHandler(w http.ResponseWriter, r *http.Request) {
497
507
}
498
508
499
509
func validateMaps (module * libbpfgo.Module , cfg config.Config ) error {
500
- maps := [] string {}
510
+ sizes := map [ string ] int {}
501
511
502
512
for _ , counter := range cfg .Metrics .Counters {
503
513
if counter .Name != "" {
504
- maps = append (maps , counter .Name )
514
+ if counter .Values != nil {
515
+ sizes [counter .Name ] = len (counter .Values ) * 8
516
+ } else {
517
+ sizes [counter .Name ] = 8
518
+ }
505
519
}
506
520
}
507
521
508
522
for _ , histogram := range cfg .Metrics .Histograms {
509
523
if histogram .Name != "" {
510
- maps = append ( maps , histogram .Name )
524
+ sizes [ histogram .Name ] = 8
511
525
}
512
526
}
513
527
514
- for _ , name := range maps {
528
+ for name , expected := range sizes {
515
529
m , err := module .GetMap (name )
516
530
if err != nil {
517
531
return fmt .Errorf ("failed to get map %q: %v" , name , err )
518
532
}
519
533
520
534
valueSize := m .ValueSize ()
521
- if valueSize != 8 {
522
- return fmt .Errorf ("value size for map %q is not expected 8 bytes (u64), it is %d bytes" , name , valueSize )
535
+ if valueSize != expected {
536
+ 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 )
523
537
}
524
538
}
525
539
@@ -545,7 +559,9 @@ func aggregateMapValues(values []metricValue) []aggregatedMetricValue {
545
559
value : value .value ,
546
560
}
547
561
} else {
548
- existing .value += value .value
562
+ for i := range existing .value {
563
+ existing .value [i ] += value .value [i ]
564
+ }
549
565
}
550
566
}
551
567
@@ -609,17 +625,17 @@ func readMapValues(m *libbpfgo.BPFMap, labels []config.Label) ([]metricValue, er
609
625
return metricValues , nil
610
626
}
611
627
612
- func mapValue (m * libbpfgo.BPFMap , key []byte ) (float64 , error ) {
628
+ func mapValue (m * libbpfgo.BPFMap , key []byte ) ([] float64 , error ) {
613
629
v , err := m .GetValue (unsafe .Pointer (& key [0 ]))
614
630
if err != nil {
615
- return 0.0 , err
631
+ return [] float64 { 0.0 } , err
616
632
}
617
633
618
634
return decodeValue (v ), nil
619
635
}
620
636
621
- func mapValuePerCPU (m * libbpfgo.BPFMap , key []byte ) ([]float64 , error ) {
622
- values := []float64 {}
637
+ func mapValuePerCPU (m * libbpfgo.BPFMap , key []byte ) ([][] float64 , error ) {
638
+ values := [][] float64 {}
623
639
624
640
size := m .ValueSize ()
625
641
value := make ([]byte , size * runtime .NumCPU ())
@@ -636,8 +652,14 @@ func mapValuePerCPU(m *libbpfgo.BPFMap, key []byte) ([]float64, error) {
636
652
}
637
653
638
654
// Assuming counter's value type is always u64
639
- func decodeValue (value []byte ) float64 {
640
- return float64 (util .GetHostByteOrder ().Uint64 (value ))
655
+ func decodeValue (value []byte ) []float64 {
656
+ values := make ([]float64 , len (value )/ 8 )
657
+
658
+ for i := range values {
659
+ values [i ] = float64 (util .GetHostByteOrder ().Uint64 (value [i * 8 :]))
660
+ }
661
+
662
+ return values
641
663
}
642
664
643
665
// metricValue is a row in a kernel map
@@ -647,13 +669,13 @@ type metricValue struct {
647
669
// labels are decoded from the raw key
648
670
labels []string
649
671
// value is the kernel map value
650
- value float64
672
+ value [] float64
651
673
}
652
674
653
675
// aggregatedMetricValue is a value after aggregation of equal label sets
654
676
type aggregatedMetricValue struct {
655
677
// labels are decoded from the raw key
656
678
labels []string
657
679
// value is the kernel map value
658
- value float64
680
+ value [] float64
659
681
}
0 commit comments