node_exporter/collector/cpu_vulnerabilities_linux.go
João Pedro Lima 16f7122d31
Add mitigation information to the linux vulnerabilities collector (#2806)
While the CPU vulnerabilities collector has been added in https://github.com/prometheus/node_exporter/pull/2721 , it's currently not including information regarding the mitigation strategy used for a given vulnerability.

This information can be quite valuable, as often times different mitigation strategies come with a different performance impact.

This commit adds a third label to the cpu_vulnerabilities_info metric, to include the "mitigation" used for a given vulnerability - if a given vulnerability is not affecting a node or the node is still vulnerable, the mitigation is expected to be empty.

Signed-off-by: João Lima <jlima@cloudflare.com>
2023-12-14 13:15:27 +01:00

70 lines
2 KiB
Go

// Copyright 2023 The Prometheus Authors
// 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 collector
import (
"fmt"
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs/sysfs"
)
const (
cpuVulerabilitiesCollector = "cpu_vulnerabilities"
)
var (
vulnerabilityDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuVulerabilitiesCollector, "info"),
"Details of each CPU vulnerability reported by sysfs. The value of the series is an int encoded state of the vulnerability. The same state is stored as a string in the label",
[]string{"codename", "state", "mitigation"},
nil,
)
)
type cpuVulnerabilitiesCollector struct{}
func init() {
registerCollector(cpuVulerabilitiesCollector, defaultDisabled, NewVulnerabilitySysfsCollector)
}
func NewVulnerabilitySysfsCollector(logger log.Logger) (Collector, error) {
return &cpuVulnerabilitiesCollector{}, nil
}
func (v *cpuVulnerabilitiesCollector) Update(ch chan<- prometheus.Metric) error {
fs, err := sysfs.NewFS(*sysPath)
if err != nil {
return fmt.Errorf("failed to open sysfs: %w", err)
}
vulnerabilities, err := fs.CPUVulnerabilities()
if err != nil {
return fmt.Errorf("failed to get vulnerabilities: %w", err)
}
for _, vulnerability := range vulnerabilities {
ch <- prometheus.MustNewConstMetric(
vulnerabilityDesc,
prometheus.GaugeValue,
1.0,
vulnerability.CodeName,
sysfs.VulnerabilityHumanEncoding[vulnerability.State],
vulnerability.Mitigation,
)
}
return nil
}