diff --git a/pkg/drivers/redfish/metrics/metrics.go b/pkg/drivers/redfish/metrics/metrics.go index 23162b3..4cdd517 100644 --- a/pkg/drivers/redfish/metrics/metrics.go +++ b/pkg/drivers/redfish/metrics/metrics.go @@ -10,6 +10,12 @@ import ( "github.com/stmcginnis/gofish/redfish" ) +const ( + Byte = 1 + KiB = 1024 * Byte + MiB = 1024 * KiB +) + type Metrics struct { base.Metrics @@ -18,7 +24,8 @@ type Metrics struct { func NewMetrics(gofish *gofish.APIClient) *Metrics { return &Metrics{ - api: gofish, + api: gofish, + Metrics: base.NewMetrics(), } } @@ -31,18 +38,24 @@ func (m *Metrics) Collect() error { } for _, system := range systems { - m.With(base.WithRedfishHealthMetric(convertHealthStatus(system.Status.Health), map[string]string{ + m.WithRedfishHealthMetric(convertHealthStatus(system.Status.Health), map[string]string{ "system_id": system.ID, - }), base.WithRedfishPowerStateMetric(convertPowerState(system.PowerState), map[string]string{ + }) + + m.WithRedfishPowerStateMetric(convertPowerState(system.PowerState), map[string]string{ "system_id": system.ID, - })) + }) if memory, err := system.Memory(); err == nil { for _, mem := range memory { - m.With(base.WithRedfishMemoryHealthMetric(convertHealthStatus(mem.Status.Health), map[string]string{ + m.WithRedfishMemoryHealthMetric(convertHealthStatus(mem.Status.Health), map[string]string{ + "system_id": system.ID, + "memory_id": mem.ID, + }) + m.WithRedfishMemoryCapacityMetric(mem.CapacityMiB, map[string]string{ "system_id": system.ID, "memory_id": mem.ID, - })) + }) } } else { log.Printf("error getting memory: %s", err) @@ -50,18 +63,23 @@ func (m *Metrics) Collect() error { if storage, err := system.Storage(); err == nil { for _, store := range storage { - m.With(base.WithRedfishStorageHealthMetric(convertHealthStatus(store.Status.Health), map[string]string{ + m.WithRedfishStorageHealthMetric(convertHealthStatus(store.Status.Health), map[string]string{ "system_id": system.ID, "storage_id": store.ID, - })) + }) if drives, err := store.Drives(); err == nil { for _, drive := range drives { - m.With(base.WithRedfishDriveHealthMetric(convertHealthStatus(drive.Status.Health), map[string]string{ + m.WithRedfishDriveHealthMetric(convertHealthStatus(drive.Status.Health), map[string]string{ + "system_id": system.ID, + "storage_id": store.ID, + "drive_id": drive.ID, + }) + m.WithRedfishDriveCapacityMetric(float64(drive.CapacityBytes)/MiB, map[string]string{ "system_id": system.ID, "storage_id": store.ID, "drive_id": drive.ID, - })) + }) } } else { log.Printf("error getting drives: %s", err) @@ -73,20 +91,20 @@ func (m *Metrics) Collect() error { if cpus, err := system.Processors(); err == nil { for _, cpu := range cpus { - m.With(base.WithRedfishProcessorHealthMetric(convertHealthStatus(cpu.Status.Health), map[string]string{ + m.WithRedfishProcessorHealthMetric(convertHealthStatus(cpu.Status.Health), map[string]string{ "system_id": system.ID, "cpu_id": cpu.ID, - })) + }) } } else { log.Printf("error getting processors: %s", err) } if system.BIOSVersion != "" { - m.With(base.WithRedfishBiosVersionMetric(map[string]string{ + m.WithRedfishBiosVersionMetric(map[string]string{ "system_id": system.ID, "version": system.BIOSVersion, - })) + }) } } diff --git a/pkg/metric/base/bios_version.go b/pkg/metric/base/bios_version.go index 151ba61..0b36a3e 100644 --- a/pkg/metric/base/bios_version.go +++ b/pkg/metric/base/bios_version.go @@ -5,21 +5,11 @@ import ( ) const ( - BiosVersion ID = "redfish_bios_version" + RedfishBiosVersion ID = "redfish_bios_version" ) var RedfishBiosVersionLabels = []string{"system_id", "version"} -func WithRedfishBiosVersionMetric(labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: BiosVersion, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(BiosVersion), - Help: "Indicates the BIOS version of the system.", - }, RedfishBiosVersionLabels).With(labels), - } - - metric.Set(1) - - return metric +func (b *Metrics) WithRedfishBiosVersionMetric(labels prometheus.Labels) { + b.SetGauge(RedfishBiosVersion, labels, 1.0) } diff --git a/pkg/metric/base/metric.go b/pkg/metric/base/metric.go index ac6bc4e..06e834f 100644 --- a/pkg/metric/base/metric.go +++ b/pkg/metric/base/metric.go @@ -4,7 +4,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -type MetricCollection map[ID]Metric +type MetricCollection []Metric type Metric interface { GetID() ID diff --git a/pkg/metric/base/metric_drive_capacity.go b/pkg/metric/base/metric_drive_capacity.go new file mode 100644 index 0000000..3a5b478 --- /dev/null +++ b/pkg/metric/base/metric_drive_capacity.go @@ -0,0 +1,15 @@ +package base + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +const ( + RedfishDriveCapacity ID = "redfish_drive_capacity" +) + +var RedfishDriveCapacityLabels = []string{"system_id", "drive_id", "storage_id"} + +func (b *Metrics) WithRedfishDriveCapacityMetric(size float64, labels prometheus.Labels) { + b.SetGauge(RedfishDriveCapacity, labels, size) +} diff --git a/pkg/metric/base/metric_drive_health.go b/pkg/metric/base/metric_drive_health.go index 99e8fe5..af1aecc 100644 --- a/pkg/metric/base/metric_drive_health.go +++ b/pkg/metric/base/metric_drive_health.go @@ -8,18 +8,8 @@ const ( RedfishDriveHealth ID = "redfish_drive_health" ) -var RedfishDriveStateLabels = []string{"system_id", "drive_id", "storage_id"} +var RedfishDriveHealthLabels = []string{"system_id", "drive_id", "storage_id"} -func WithRedfishDriveHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: RedfishDriveHealth, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(RedfishDriveHealth), - Help: "Indicates the health status of the drive. 1 = OK, 2 = Warning, 3 = Critical.", - }, RedfishDriveStateLabels).With(labels), - } - - metric.Set(float64(health)) - - return metric +func (b *Metrics) WithRedfishDriveHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) { + b.SetGauge(RedfishDriveHealth, labels, float64(health)) } diff --git a/pkg/metric/base/metric_gauges.go b/pkg/metric/base/metric_gauges.go index baa7e53..4c2ba3d 100644 --- a/pkg/metric/base/metric_gauges.go +++ b/pkg/metric/base/metric_gauges.go @@ -1,6 +1,8 @@ package base -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" +) type GaugeMetric struct { ID ID diff --git a/pkg/metric/base/metric_health.go b/pkg/metric/base/metric_health.go index a5aaa3f..52dfc05 100644 --- a/pkg/metric/base/metric_health.go +++ b/pkg/metric/base/metric_health.go @@ -18,16 +18,6 @@ const ( RedfishHealthCritical RedfishHealthStatus = 3 ) -func WithRedfishHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: RedfishHealth, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(RedfishHealth), - Help: "Indicates the health status of the system. 1 = OK, 2 = Warning, 3 = Critical.", - }, RedfishHealthLabels).With(labels), - } - - metric.Set(float64(health)) - - return metric +func (b *Metrics) WithRedfishHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) { + b.SetGauge(RedfishHealth, labels, float64(health)) } diff --git a/pkg/metric/base/metric_memory_capacity.go b/pkg/metric/base/metric_memory_capacity.go new file mode 100644 index 0000000..dadca58 --- /dev/null +++ b/pkg/metric/base/metric_memory_capacity.go @@ -0,0 +1,15 @@ +package base + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +const ( + RedfishMemoryCapacity ID = "redfish_memory_capacity" +) + +var RedfishMemoryCapacityLabels = []string{"system_id", "memory_id"} + +func (b *Metrics) WithRedfishMemoryCapacityMetric(size int, labels prometheus.Labels) { + b.SetGauge(RedfishMemoryCapacity, labels, float64(size)) +} diff --git a/pkg/metric/base/metric_memory_health.go b/pkg/metric/base/metric_memory_health.go index 1f5c829..40ba0ae 100644 --- a/pkg/metric/base/metric_memory_health.go +++ b/pkg/metric/base/metric_memory_health.go @@ -8,18 +8,8 @@ const ( RedfishMemoryHealth ID = "redfish_memory_health" ) -var RedfishMemoryStateLabels = []string{"system_id", "memory_id"} +var RedfishMemoryHealthLabels = []string{"system_id", "memory_id"} -func WithRedfishMemoryHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: RedfishMemoryHealth, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(RedfishMemoryHealth), - Help: "Indicates the health status of the memory. 1 = OK, 2 = Warning, 3 = Critical.", - }, RedfishMemoryStateLabels).With(labels), - } - - metric.Set(float64(health)) - - return metric +func (b *Metrics) WithRedfishMemoryHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) { + b.SetGauge(RedfishMemoryHealth, labels, float64(health)) } diff --git a/pkg/metric/base/metric_power_state.go b/pkg/metric/base/metric_power_state.go index 916fd7f..a15f0e7 100644 --- a/pkg/metric/base/metric_power_state.go +++ b/pkg/metric/base/metric_power_state.go @@ -17,16 +17,6 @@ const ( RedfishPowerStateOFF RedfishPowerStateType = 2 ) -func WithRedfishPowerStateMetric(state RedfishPowerStateType, labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: RedfishPowerState, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(RedfishPowerState), - Help: "Indicates the power state of the system. 1 = ON, 2 = OFF.", - }, RedfishPowerStateLabels).With(labels), - } - - metric.Set(float64(state)) - - return metric +func (b *Metrics) WithRedfishPowerStateMetric(state RedfishPowerStateType, labels prometheus.Labels) { + b.SetGauge(RedfishPowerState, labels, float64(state)) } diff --git a/pkg/metric/base/metric_processor_health.go b/pkg/metric/base/metric_processor_health.go index d8ab8c4..4786edd 100644 --- a/pkg/metric/base/metric_processor_health.go +++ b/pkg/metric/base/metric_processor_health.go @@ -10,16 +10,6 @@ const ( var RedfishProcessorStateLabels = []string{"system_id", "processor_id"} -func WithRedfishProcessorHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: RedfishProcessorHealth, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(RedfishProcessorHealth), - Help: "Indicates the health status of the processor. 1 = OK, 2 = Warning, 3 = Critical.", - }, RedfishProcessorStateLabels).With(labels), - } - - metric.Set(float64(health)) - - return metric +func (b *Metrics) WithRedfishProcessorHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) { + b.SetGauge(RedfishProcessorHealth, labels, float64(health)) } diff --git a/pkg/metric/base/metric_storage_health.go b/pkg/metric/base/metric_storage_health.go index 35b7af8..93b79fe 100644 --- a/pkg/metric/base/metric_storage_health.go +++ b/pkg/metric/base/metric_storage_health.go @@ -8,18 +8,8 @@ const ( RedfishStorageHealth ID = "redfish_storage_health" ) -var RedfishStorageStateLabels = []string{"system_id", "storage_id"} +var RedfishStorageHealthLabels = []string{"system_id", "storage_id"} -func WithRedfishStorageHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) Metric { - metric := &GaugeMetric{ - ID: RedfishStorageHealth, - Gauge: prometheus.NewGaugeVec(prometheus.GaugeOpts{ - Name: string(RedfishStorageHealth), - Help: "Indicates the health status of the storage. 1 = OK, 2 = Warning, 3 = Critical.", - }, RedfishStorageStateLabels).With(labels), - } - - metric.Set(float64(health)) - - return metric +func (b *Metrics) WithRedfishStorageHealthMetric(health RedfishHealthStatus, labels prometheus.Labels) { + b.SetGauge(RedfishStorageHealth, labels, float64(health)) } diff --git a/pkg/metric/base/metrics.go b/pkg/metric/base/metrics.go index a5b1f4d..669d663 100644 --- a/pkg/metric/base/metrics.go +++ b/pkg/metric/base/metrics.go @@ -1,28 +1,73 @@ package base import ( + "log" + "github.com/prometheus/client_golang/prometheus" ) type ID string type Metrics struct { - metrics MetricCollection + collectors map[ID]prometheus.Collector } -func (b *Metrics) With(metrics ...Metric) { - if b.metrics == nil { - b.metrics = make(MetricCollection) +func NewMetrics() Metrics { + return Metrics{ + collectors: map[ID]prometheus.Collector{ + RedfishBiosVersion: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishBiosVersion), + Help: "Indicates the BIOS version of the system.", + }, RedfishBiosVersionLabels), + RedfishDriveCapacity: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishDriveCapacity), + Help: "Indicates the capacity of the drive in MiB.", + }, RedfishDriveCapacityLabels), + RedfishDriveHealth: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishDriveHealth), + Help: "Indicates the health status of the drive. 1 = OK, 2 = Warning, 3 = Critical.", + }, RedfishDriveHealthLabels), + RedfishHealth: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishHealth), + Help: "Indicates the health status of the system. 1 = OK, 2 = Warning, 3 = Critical.", + }, RedfishHealthLabels), + RedfishMemoryCapacity: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishMemoryCapacity), + Help: "Indicates the capacity of the memory in MiB.", + }, RedfishMemoryCapacityLabels), + RedfishMemoryHealth: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishMemoryHealth), + Help: "Indicates the health status of the memory. 1 = OK, 2 = Warning, 3 = Critical.", + }, RedfishMemoryHealthLabels), + RedfishPowerState: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishPowerState), + Help: "Indicates the power state of the system. 1 = ON, 2 = OFF.", + }, RedfishPowerStateLabels), + RedfishProcessorHealth: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishProcessorHealth), + Help: "Indicates the health status of the processor. 1 = OK, 2 = Warning, 3 = Critical.", + }, RedfishProcessorStateLabels), + RedfishStorageHealth: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: string(RedfishStorageHealth), + Help: "Indicates the health status of the storage. 1 = OK, 2 = Warning, 3 = Critical.", + }, RedfishStorageHealthLabels), + }, } +} - for _, metric := range metrics { - b.metrics[metric.GetID()] = metric +func (b *Metrics) SetGauge(id ID, labels prometheus.Labels, value float64) { + if collector, ok := b.collectors[id]; ok { + if gauge, ok := collector.(*prometheus.GaugeVec); ok { + metric := gauge.With(labels) + metric.Set(value) + } } } func (b *Metrics) Registry() *prometheus.Registry { registry := prometheus.NewRegistry() - for _, collector := range b.metrics { + for id, collector := range b.collectors { + log.Printf("Registering collector %q.", id) registry.MustRegister(collector) }