125 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2020 Intel Corporation
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package rdt
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"sync"
 | 
						|
 | 
						|
	"github.com/prometheus/client_golang/prometheus"
 | 
						|
)
 | 
						|
 | 
						|
var customLabels []string = []string{}
 | 
						|
 | 
						|
// collector implements prometheus.Collector interface
 | 
						|
type collector struct {
 | 
						|
	descriptors map[string]*prometheus.Desc
 | 
						|
}
 | 
						|
 | 
						|
// NewCollector creates new Prometheus collector of RDT metrics
 | 
						|
func NewCollector() (prometheus.Collector, error) {
 | 
						|
	c := &collector{descriptors: make(map[string]*prometheus.Desc)}
 | 
						|
	return c, nil
 | 
						|
}
 | 
						|
 | 
						|
// RegisterCustomPrometheusLabels registers monitor group annotations to be
 | 
						|
// exported as Prometheus metrics labels
 | 
						|
func RegisterCustomPrometheusLabels(names ...string) {
 | 
						|
Names:
 | 
						|
	for _, n := range names {
 | 
						|
		for _, c := range customLabels {
 | 
						|
			if n == c {
 | 
						|
				break Names
 | 
						|
			}
 | 
						|
		}
 | 
						|
		customLabels = append(customLabels, n)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Describe method of the prometheus.Collector interface
 | 
						|
func (c *collector) Describe(ch chan<- *prometheus.Desc) {
 | 
						|
	for resource, features := range GetMonFeatures() {
 | 
						|
		switch resource {
 | 
						|
		case MonResourceL3:
 | 
						|
			for _, f := range features {
 | 
						|
				ch <- c.describeL3(f)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Collect method of the prometheus.Collector interface
 | 
						|
func (c collector) Collect(ch chan<- prometheus.Metric) {
 | 
						|
	var wg sync.WaitGroup
 | 
						|
 | 
						|
	for _, cls := range GetClasses() {
 | 
						|
		for _, monGrp := range cls.GetMonGroups() {
 | 
						|
			wg.Add(1)
 | 
						|
			g := monGrp
 | 
						|
			go func() {
 | 
						|
				defer wg.Done()
 | 
						|
				c.collectGroupMetrics(ch, g)
 | 
						|
			}()
 | 
						|
		}
 | 
						|
	}
 | 
						|
	wg.Wait()
 | 
						|
}
 | 
						|
 | 
						|
func (c *collector) describeL3(feature string) *prometheus.Desc {
 | 
						|
	d, ok := c.descriptors[feature]
 | 
						|
	if !ok {
 | 
						|
		name := "l3_" + feature
 | 
						|
		help := "L3 " + feature
 | 
						|
 | 
						|
		switch feature {
 | 
						|
		case "llc_occupancy":
 | 
						|
			help = "L3 (LLC) occupancy"
 | 
						|
		case "mbm_local_bytes":
 | 
						|
			help = "bytes transferred to/from local memory through LLC"
 | 
						|
		case "mbm_total_bytes":
 | 
						|
			help = "total bytes transferred to/from memory through LLC"
 | 
						|
		}
 | 
						|
		labels := append([]string{"rdt_class", "rdt_mon_group", "cache_id"}, customLabels...)
 | 
						|
		d = prometheus.NewDesc(name, help, labels, nil)
 | 
						|
		c.descriptors[feature] = d
 | 
						|
	}
 | 
						|
	return d
 | 
						|
}
 | 
						|
 | 
						|
func (c *collector) collectGroupMetrics(ch chan<- prometheus.Metric, mg MonGroup) {
 | 
						|
	allData := mg.GetMonData()
 | 
						|
 | 
						|
	annotations := mg.GetAnnotations()
 | 
						|
	customLabelValues := make([]string, len(customLabels))
 | 
						|
	for i, name := range customLabels {
 | 
						|
		customLabelValues[i] = annotations[name]
 | 
						|
	}
 | 
						|
 | 
						|
	for cacheID, data := range allData.L3 {
 | 
						|
		for feature, value := range data {
 | 
						|
			labels := append([]string{mg.Parent().Name(), mg.Name(), fmt.Sprint(cacheID)}, customLabelValues...)
 | 
						|
 | 
						|
			ch <- prometheus.MustNewConstMetric(
 | 
						|
				c.describeL3(feature),
 | 
						|
				prometheus.CounterValue,
 | 
						|
				float64(value),
 | 
						|
				labels...,
 | 
						|
			)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |