package exporters import ( "context" "encoding/xml" "log" "strings" "github.com/dnaeon/go-ucs/api" "github.com/dnaeon/go-ucs/mo" ) // Define the fields we will send back to the collector type UcsmVnicPortStats struct { Server string Component string Metrics map[string]uint64 } func (u *UcsExporters) GetUcsmPortStats(ctx context.Context, ucsmPortStatsChannel chan []UcsmVnicPortStats) { portStatsResults := make([]UcsmVnicPortStats, 0) // The type into which we unmarshal the result data type vnicStats struct { XMLName xml.Name VnicStats []mo.AdaptorVnicStats `xml:"adaptorVnicStats"` } // Define the request we are making to UCS Manager vnicStatsRequest := api.ConfigResolveClassRequest{ Cookie: u.ucsClient.Cookie, ClassId: "adaptorVnicStats", InHierarchical: "false", } var vnicStatsObject vnicStats log.Println("Retrieving managed objects with class `adaptorVnicStats`") if err := u.ucsClient.ConfigResolveClass(u.ctx, vnicStatsRequest, &vnicStatsObject); err != nil { log.Fatalf("Unable to retrieve `computeMbTempStats` managed object: %s", err) } log.Printf("Retrieved port stats for %d vnics\n", len(vnicStatsObject.VnicStats)) for _, vnic := range vnicStatsObject.VnicStats { var bladeDn string // Extract the bladeDn startIndex := strings.Index(vnic.Dn, "/adaptor-") if startIndex != -1 { bladeDn = vnic.Dn[:startIndex] } else { bladeDn = vnic.Dn } log.Printf("Network stats for blade %s and component %s:\n", bladeDn, vnic.Dn) log.Printf("Bytes Rx: %d, Bytes Tx: %d\n", vnic.BytesRx, vnic.BytesTx) log.Printf("Packets Rx: %d, Packets Tx: %d\n", vnic.PacketsRx, vnic.PacketsTx) log.Printf("Dropped Rx: %d, Dropped Tx: %d\n", vnic.DroppedRx, vnic.DroppedTx) log.Printf("Error Rx: %d, Error Tx: %d\n", vnic.ErrorsRx, vnic.ErrorsTx) // Create a map of all the values we care about portMetrics := make(map[string]uint64) portMetrics["ucsm_vnic_rx_total_packets"] = vnic.PacketsRx portMetrics["ucsm_vnic_tx_total_packets"] = vnic.PacketsTx portMetrics["ucsm_vnic_rx_total_bytes"] = vnic.BytesRx portMetrics["ucsm_vnic_tx_total_bytes"] = vnic.BytesTx portMetrics["ucsm_vnic_rx_dropped"] = vnic.DroppedRx portMetrics["ucsm_vnic_tx_dropped"] = vnic.DroppedTx portMetrics["ucsm_vnic_rx_error"] = vnic.ErrorsRx portMetrics["ucsm_vnic_tx_error"] = vnic.ErrorsTx // Add the metrics along with the other properties to the results vnicPortStats := UcsmVnicPortStats{ Server: bladeDn, Component: vnic.Dn, Metrics: portMetrics, } portStatsResults = append(portStatsResults, vnicPortStats) /* // Substring the Dn for the temperatures to get the Dn for the parent blade itself bladeDn := strings.Replace(temps.Dn, "/board/temp-stats", "", -1) log.Printf("Temps for blade %s:\n", bladeDn) log.Printf("Front Temperature: %v\n", temps.FmTempSenIo) log.Printf("Rear Temperature: %v\n", temps.FmTempSenRear) boardTempFront := UcsmPortStats{ Server: bladeDn, Component: temps.Dn, Description: "motherboard_front_temperature", Value: temps.FmTempSenIo, } boardTempRear := UcsmPortStats{ Server: bladeDn, Component: temps.Dn, Description: "motherboard_rear_temperature", Value: temps.FmTempSenRear, } portStatsResults = append(portStatsResults, boardTempFront) portStatsResults = append(portStatsResults, boardTempRear) */ /* // TODO - work out a better way of running this twice, once for each temperature sensor metric1 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenIo, bladeDn, temps.Dn, "motherboard_rear_temperature") // send the data ch <- metric1 // generate the metric metric2 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenRear, bladeDn, temps.Dn, "motherboard_front_temperature") // send the data ch <- metric2 */ } log.Printf("GetUcsmPortStats sending results to channel\n") ucsmPortStatsChannel <- portStatsResults }