package exporters import ( "context" "log" "github.com/dnaeon/go-ucs/api" "github.com/prometheus/client_golang/prometheus" "golang.org/x/sync/errgroup" ) type UcsExporters struct { // Define each type of metric here UcsmTemperatures *prometheus.Desc UcsmVnicStatsRxTotalPkts *prometheus.Desc UcsmVnicStatsTxTotalPkts *prometheus.Desc UcsmVnicStatsRxTotalBytes *prometheus.Desc UcsmVnicStatsTxTotalBytes *prometheus.Desc UcsmVnicStatsRxDropped *prometheus.Desc UcsmVnicStatsTxDropped *prometheus.Desc UcsmVnicStatsRxError *prometheus.Desc UcsmVnicStatsTxError *prometheus.Desc // Additional properties required ucsClient *api.Client ctx context.Context } func NewUcsmExporters(client *api.Client, ctx context.Context) *UcsExporters { return &UcsExporters{ ucsClient: client, ctx: ctx, // UCS Temperatures UcsmTemperatures: prometheus.NewDesc("ucsm_temperature_sensor", "UCSM temperature sensor for motherboard/cpu/psu", []string{"server", "component", "description"}, nil, ), // UCS Network statistics UcsmVnicStatsRxTotalPkts: prometheus.NewDesc("ucsm_vnic_rx_total_packets", "UCSM Ethernet RX counter: total_packets", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsTxTotalPkts: prometheus.NewDesc("ucsm_vnic_tx_total_packets", "UCSM Ethernet TX counter: total_packets", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsRxTotalBytes: prometheus.NewDesc("ucsm_vnic_rx_total_bytes", "UCSM Ethernet RX counter: total_bytes", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsTxTotalBytes: prometheus.NewDesc("ucsm_vnic_tx_total_bytes", "UCSM Ethernet TX counter: total_bytes", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsRxDropped: prometheus.NewDesc("ucsm_vnic_rx_dropped", "UCSM Ethernet Rx Dropped counter: total_count", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsTxDropped: prometheus.NewDesc("ucsm_vnic_tx_dropped", "UCSM Ethernet Tx Dropped counter: total_count", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsRxError: prometheus.NewDesc("ucsm_vnic_rx_error", "UCSM Ethernet Rx Error counter: total_count", []string{"server", "component", "description"}, nil, ), UcsmVnicStatsTxError: prometheus.NewDesc("ucsm_vnic_tx_error", "UCSM Ethernet Tx Error counter: total_count", []string{"server", "component", "description"}, nil, ), } } // Describe prometheus describe func (u *UcsExporters) Describe(ch chan<- *prometheus.Desc) { log.Printf("Running Describe for UcsExporters\n") // UCS Temperatures ch <- u.UcsmTemperatures // UCS Network statistics ch <- u.UcsmVnicStatsRxTotalPkts ch <- u.UcsmVnicStatsTxTotalPkts ch <- u.UcsmVnicStatsRxTotalBytes ch <- u.UcsmVnicStatsTxTotalBytes ch <- u.UcsmVnicStatsRxDropped ch <- u.UcsmVnicStatsTxDropped ch <- u.UcsmVnicStatsRxError ch <- u.UcsmVnicStatsTxError } // Collect prometheus collect func (u *UcsExporters) Collect(ch chan<- prometheus.Metric) { // TODO - refresh UCS Manager login session //var wg = sync.WaitGroup{} g, gCtx := errgroup.WithContext(u.ctx) // Create channels to receive values ucsmTempsChannel := make(chan []UcsmTemperatures) ucsmPortStatsChannel := make(chan []UcsmVnicPortStats) log.Printf("Running Collect for UCS Temperatures\n") g.Go(func() error { u.GetUcsmTemperatures(gCtx, ucsmTempsChannel) return nil }) log.Printf("Running Collect for UCS Network Statistics\n") g.Go(func() error { u.GetUcsmPortStats(gCtx, ucsmPortStatsChannel) return nil }) // Receive results from exporter channels ucsmTempResults := <-ucsmTempsChannel ucsmVnicStatsResults := <-ucsmPortStatsChannel //wg.Wait() // Send results back to prometheus channel for _, blade := range ucsmTempResults { log.Printf("Generating constant metric for component %s with value %f\n", blade.Component, blade.Value) ch <- prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, blade.Value, blade.Server, blade.Component, blade.Description) } for _, vnic := range ucsmVnicStatsResults { log.Printf("Generating constant metric for component %s\n", vnic.Component) ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxTotalPkts, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_total_packets"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_total_packets") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxTotalPkts, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_total_packets"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_total_packets") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxTotalBytes, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_total_bytes"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_total_bytes") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxTotalBytes, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_total_bytes"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_total_bytes") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxDropped, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_dropped"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_dropped") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxDropped, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_dropped"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_dropped") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxError, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_error"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_error") ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxError, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_error"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_error") } }