package metrics import ( "strconv" "time" "github.com/prometheus/client_golang/prometheus" "lostak.dev/pve-exporter/proxmox" ) // PVE Storage state collector. type PveStorageCollector struct { apiClient *proxmox.PveApiClient // PVE API client instance. registry *TTLRegistry // TTL metrics registry. state *TTLGaugeVec // Storage state prometheus gauge. total *TTLGaugeVec // Storage total bytes prometheus gauge. avail *TTLGaugeVec // Storage available bytes prometheus gauge. used *TTLGaugeVec // Storage used bytes prometheus gauge. } // Create new instance of PVE SDN collector. func NewPveStorageCollector(apiClient *proxmox.PveApiClient, registry *TTLRegistry) *PveStorageCollector { c := PveStorageCollector{apiClient: apiClient} c.registry = registry // Storage state. c.state = NewTTLGaugeVec( prometheus.GaugeOpts{ Name: "pve_storage_up", Help: "Node storage UP state.", }, []string{"cluster", "node", "storage", "type", "content", "shared"}, 5*time.Minute, ) c.registry.Register(c.state) // Storage total bytes. c.total = NewTTLGaugeVec( prometheus.GaugeOpts{ Name: "pve_storage_total_bytes", Help: "Node storage total capacity in bytes.", }, []string{"cluster", "node", "storage", "type", "content", "shared"}, 5*time.Minute, ) c.registry.Register(c.total) // Storage available bytes. c.avail = NewTTLGaugeVec( prometheus.GaugeOpts{ Name: "pve_storage_avail_bytes", Help: "Node storage available capacity in bytes.", }, []string{"cluster", "node", "storage", "type", "content", "shared"}, 5*time.Minute, ) c.registry.Register(c.avail) // Storage used bytes. c.used = NewTTLGaugeVec( prometheus.GaugeOpts{ Name: "pve_storage_used_bytes", Help: "Node storage used capacity in bytes.", }, []string{"cluster", "node", "storage", "type", "content", "shared"}, 5*time.Minute, ) c.registry.Register(c.used) return &c } // PveMetricsCollector interface implementation. func (c *PveStorageCollector) CollectMetrics() error { cluster, err := c.apiClient.GetClusterStatus() if err != nil { return err } for _, node := range cluster.NodeStatuses { storages, err := c.apiClient.GetNodeStorages(node.Name) if err != nil { return err } for _, storage := range *storages { // Skip disabled storages. if storage.Enabled == 0 { continue } labels := prometheus.Labels{ "cluster": cluster.GetClusterName(), "node": node.Name, "storage": storage.Storage, "type": storage.Type, "content": storage.GetContentSorted(), "shared": strconv.Itoa(storage.Shared), } c.state.With(labels).Set(float64(storage.Active)) c.total.With(labels).Set(float64(storage.Total)) c.avail.With(labels).Set(float64(storage.Avail)) c.used.With(labels).Set(float64(storage.Used)) } } return nil } // PveMetricsCollector interface implementation. func (c *PveStorageCollector) GetName() string { return "Storage" }