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...,
|
|
)
|
|
}
|
|
}
|
|
}
|