Add rapl zone label option (#2401)

Add an optional flag to set the RAPL zone as a label, instead of as part
of the metric name.

Fixes: https://github.com/prometheus/node_exporter/issues/2299

Signed-off-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
Ben Kochie 2022-06-27 23:09:32 +02:00 committed by GitHub
parent b99f933713
commit d2b8ee8f20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 17 deletions

View File

@ -7,6 +7,8 @@
* [ENHANCEMENT] Add node_softirqs_total metric #2221 * [ENHANCEMENT] Add node_softirqs_total metric #2221
* [ENHANCEMENT] Add device filter flags to arp collector #2254 * [ENHANCEMENT] Add device filter flags to arp collector #2254
* [ENHANCEMENT] Add rapl zone name label option #2401
* [BUGFIX] Sanitize rapl zone names #2299
## 1.3.1 / 2021-12-01 ## 1.3.1 / 2021-12-01

View File

@ -26,17 +26,26 @@ import (
"github.com/go-kit/log/level" "github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs/sysfs" "github.com/prometheus/procfs/sysfs"
"gopkg.in/alecthomas/kingpin.v2"
) )
const raplCollectorSubsystem = "rapl"
type raplCollector struct { type raplCollector struct {
fs sysfs.FS fs sysfs.FS
logger log.Logger logger log.Logger
joulesMetricDesc *prometheus.Desc
} }
func init() { func init() {
registerCollector("rapl", defaultEnabled, NewRaplCollector) registerCollector(raplCollectorSubsystem, defaultEnabled, NewRaplCollector)
} }
var (
raplZoneLabel = kingpin.Flag("collector.rapl.enable-zone-label", "Enables service unit metric unit_start_time_seconds").Bool()
)
// NewRaplCollector returns a new Collector exposing RAPL metrics. // NewRaplCollector returns a new Collector exposing RAPL metrics.
func NewRaplCollector(logger log.Logger) (Collector, error) { func NewRaplCollector(logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*sysPath)
@ -45,9 +54,16 @@ func NewRaplCollector(logger log.Logger) (Collector, error) {
return nil, err return nil, err
} }
joulesMetricDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, raplCollectorSubsystem, "joules_total"),
"Current RAPL value in joules",
[]string{"index", "path", "rapl_zone"}, nil,
)
collector := raplCollector{ collector := raplCollector{
fs: fs, fs: fs,
logger: logger, logger: logger,
joulesMetricDesc: joulesMetricDesc,
} }
return &collector, nil return &collector, nil
} }
@ -69,7 +85,7 @@ func (c *raplCollector) Update(ch chan<- prometheus.Metric) error {
} }
for _, rz := range zones { for _, rz := range zones {
newMicrojoules, err := rz.GetEnergyMicrojoules() microJoules, err := rz.GetEnergyMicrojoules()
if err != nil { if err != nil {
if errors.Is(err, os.ErrPermission) { if errors.Is(err, os.ErrPermission) {
level.Debug(c.logger).Log("msg", "Can't access energy_uj file", "zone", rz, "err", err) level.Debug(c.logger).Log("msg", "Can't access energy_uj file", "zone", rz, "err", err)
@ -77,21 +93,48 @@ func (c *raplCollector) Update(ch chan<- prometheus.Metric) error {
} }
return err return err
} }
index := strconv.Itoa(rz.Index)
descriptor := prometheus.NewDesc( joules := float64(microJoules) / 1000000.0
prometheus.BuildFQName(namespace, "rapl", SanitizeMetricName(rz.Name+"_joules_total")),
"Current RAPL "+rz.Name+" value in joules",
[]string{"index", "path"}, nil,
)
ch <- prometheus.MustNewConstMetric( if *raplZoneLabel {
descriptor, ch <- c.joulesMetricWithZoneLabel(rz, joules)
prometheus.CounterValue, } else {
float64(newMicrojoules)/1000000.0, ch <- c.joulesMetric(rz, joules)
index, }
rz.Path,
)
} }
return nil return nil
} }
func (c *raplCollector) joulesMetric(z sysfs.RaplZone, v float64) prometheus.Metric {
index := strconv.Itoa(z.Index)
descriptor := prometheus.NewDesc(
prometheus.BuildFQName(
namespace,
raplCollectorSubsystem,
fmt.Sprintf("%s_joules_total", SanitizeMetricName(z.Name)),
),
fmt.Sprintf("Current RAPL %s value in joules", z.Name),
[]string{"index", "path"}, nil,
)
return prometheus.MustNewConstMetric(
descriptor,
prometheus.CounterValue,
v,
index,
z.Path,
)
}
func (c *raplCollector) joulesMetricWithZoneLabel(z sysfs.RaplZone, v float64) prometheus.Metric {
index := strconv.Itoa(z.Index)
return prometheus.MustNewConstMetric(
c.joulesMetricDesc,
prometheus.CounterValue,
v,
index,
z.Path,
z.Name,
)
}