This commit is contained in:
@@ -56,7 +56,7 @@ func main() {
|
||||
log.Printf("Got authentication cookie: %s\n", ucsClient.Cookie)
|
||||
|
||||
// Register prometheus exporters
|
||||
exporter := exporters.NewUcsmTemperatureCollector(ucsClient, ctx)
|
||||
exporter := exporters.NewUcsmExporters(ucsClient, ctx)
|
||||
prometheus.MustRegister(exporter)
|
||||
|
||||
// Start prometheus exporter
|
||||
@@ -64,4 +64,6 @@ func main() {
|
||||
|
||||
// TODO - run this in a go routine to avoid blocking, as per cbs code
|
||||
log.Fatal(http.ListenAndServe(*listenPort, nil))
|
||||
|
||||
// TODO - log off from UCS manager
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@@ -5,6 +5,7 @@ go 1.21.0
|
||||
require (
|
||||
github.com/dnaeon/go-ucs v0.0.0-20180427075322-a04ea35bf5de
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
golang.org/x/sync v0.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
4
go.sum
4
go.sum
@@ -4,8 +4,6 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dnaeon/go-ucs v0.0.0-20180427075322-a04ea35bf5de h1:TPQ2PEbeZy0m8Y/zO+IQx9pUDMqfanACLJqREaLroJU=
|
||||
github.com/dnaeon/go-ucs v0.0.0-20180427075322-a04ea35bf5de/go.mod h1:CnATpmPv6+QWYn/4O/qrRmxhSvfsiTMB4mVBfsWwKs8=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
@@ -25,6 +23,8 @@ github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr
|
||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
|
@@ -1,77 +0,0 @@
|
||||
package exporters
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"log"
|
||||
|
||||
"github.com/dnaeon/go-ucs/api"
|
||||
"github.com/dnaeon/go-ucs/mo"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type UcsmBladeCollector struct {
|
||||
ucsClient *api.Client
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/*
|
||||
type ComputeMbTempStats struct {
|
||||
XMLName xml.Name `xml:"computeMbTempStats"`
|
||||
Dn string `xml:"dn,attr,omitempty"`
|
||||
FmTempSenIo string `xml:"fmTempSenIo,attr,omitempty"`
|
||||
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
|
||||
}
|
||||
*/
|
||||
func NewUcsmBladeCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
|
||||
return &UcsmTemperaturesCollector{
|
||||
ucsClient: client,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Describe prometheus describe
|
||||
func (u *UcsmBladeCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
log.Printf("Running Describe for UcsmTemperaturesCollector\n")
|
||||
ch <- prometheus.NewDesc("ucsm_temperature_sensor",
|
||||
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||
[]string{"server", "component", "description"}, nil,
|
||||
)
|
||||
ch <- prometheus.NewDesc("ucsm_temperature_sensor",
|
||||
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||
[]string{"server", "component", "description"}, nil,
|
||||
)
|
||||
}
|
||||
|
||||
// Collect prometheus collect
|
||||
func (u *UcsmBladeCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
// The type into which we unmarshal the result data
|
||||
type blades struct {
|
||||
XMLName xml.Name
|
||||
Blades []mo.ComputeBlade `xml:"computeBlade"`
|
||||
}
|
||||
|
||||
bladeRequest := api.ConfigResolveClassRequest{
|
||||
Cookie: u.ucsClient.Cookie,
|
||||
ClassId: "computeBlade",
|
||||
InHierarchical: "false",
|
||||
}
|
||||
|
||||
var bladeList blades
|
||||
|
||||
log.Println("Retrieving managed objects with class `computeBlade`")
|
||||
|
||||
if err := u.ucsClient.ConfigResolveClass(u.ctx, bladeRequest, &bladeList); err != nil {
|
||||
log.Fatalf("Unable to retrieve `computeBlade` managed object: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("Retrieved %d compute blades\n", len(bladeList.Blades))
|
||||
for _, blade := range bladeList.Blades {
|
||||
log.Printf("%s:\n", blade.Dn)
|
||||
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
|
||||
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
|
||||
log.Printf("\tModel: %s\n", blade.Model)
|
||||
log.Printf("\tVendor: %s\n", blade.Vendor)
|
||||
}
|
||||
|
||||
}
|
123
internal/exporters/UcsmPortStats.go
Normal file
123
internal/exporters/UcsmPortStats.go
Normal file
@@ -0,0 +1,123 @@
|
||||
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
|
||||
}
|
@@ -8,9 +8,17 @@ import (
|
||||
|
||||
"github.com/dnaeon/go-ucs/api"
|
||||
"github.com/dnaeon/go-ucs/mo"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Define the fields we will send back to the collector
|
||||
type UcsmTemperatures struct {
|
||||
Server string
|
||||
Component string
|
||||
Description string
|
||||
Value float64
|
||||
}
|
||||
|
||||
/*
|
||||
type UcsmTemperaturesCollector struct {
|
||||
ucsClient *api.Client
|
||||
ctx context.Context
|
||||
@@ -18,6 +26,7 @@ type UcsmTemperaturesCollector struct {
|
||||
}
|
||||
|
||||
var metrics []prometheus.Desc
|
||||
*/
|
||||
|
||||
//var ucsClient *api.Client
|
||||
//var ctx context.Context
|
||||
@@ -30,64 +39,44 @@ var metrics []prometheus.Desc
|
||||
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
|
||||
}
|
||||
*/
|
||||
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
|
||||
/*
|
||||
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsExporters {
|
||||
|
||||
/*
|
||||
ucsClient = client
|
||||
ctx = ctx
|
||||
*/
|
||||
/*
|
||||
return &main.Collector{
|
||||
UcsmTemperature: prometheus.NewDesc("ucsm_temperature_sensor",
|
||||
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||
[]string{"server", "component", "description"}, nil,
|
||||
),
|
||||
}
|
||||
*/
|
||||
|
||||
return &UcsmTemperaturesCollector{
|
||||
return &UcsExporters{
|
||||
ucsClient: client,
|
||||
ctx: ctx,
|
||||
metrics: []*prometheus.Desc{
|
||||
prometheus.NewDesc(
|
||||
"ucsm_temperature_sensor",
|
||||
UcsmTemperatures: prometheus.NewDesc("ucsm_temperature_sensor",
|
||||
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||
[]string{"server", "component", "description"}, nil,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Describe prometheus describe
|
||||
func (u *UcsmTemperaturesCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
func (u *UcsExporters) Describe(ch chan<- *prometheus.Desc) {
|
||||
log.Printf("Running Describe for UcsmTemperaturesCollector\n")
|
||||
|
||||
// Describe the metrics and send them on the channel
|
||||
for _, desc := range u.metrics {
|
||||
ch <- desc
|
||||
}
|
||||
|
||||
/*
|
||||
metricDesc := prometheus.NewDesc("ucsm_temperature_sensor",
|
||||
"UCSM temperature sensor for motherboard/cpu/psu",
|
||||
[]string{"server", "component", "description"}, nil)
|
||||
|
||||
fmt.Printf("metricDesc: %v\n", *metricDesc)
|
||||
|
||||
metrics = append(metrics, *metricDesc)
|
||||
ch <- metricDesc
|
||||
*/
|
||||
ch <- u.UcsmTemperatures
|
||||
}
|
||||
*/
|
||||
|
||||
// Collect prometheus collect
|
||||
func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
func (u *UcsExporters) GetUcsmTemperatures(ctx context.Context, ucsmTempsChannel chan []UcsmTemperatures) {
|
||||
/*
|
||||
wg.Add(1)
|
||||
defer wg.Done()
|
||||
defer close(ucsmTempsChannel)
|
||||
*/
|
||||
temperatureResults := make([]UcsmTemperatures, 0)
|
||||
|
||||
// The type into which we unmarshal the result data
|
||||
type temps struct {
|
||||
XMLName xml.Name
|
||||
Temperatures []mo.ComputeMbTempStats `xml:"computeMbTempStats"`
|
||||
}
|
||||
|
||||
// Define the request we are making to UCS Manager
|
||||
tempRequest := api.ConfigResolveClassRequest{
|
||||
Cookie: u.ucsClient.Cookie,
|
||||
ClassId: "computeMbTempStats",
|
||||
@@ -96,6 +85,7 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
|
||||
var boardTempList temps
|
||||
|
||||
//cswg := new(sync.WaitGroup)
|
||||
log.Println("Retrieving managed objects with class `computeMbTempStats`")
|
||||
|
||||
if err := u.ucsClient.ConfigResolveClass(u.ctx, tempRequest, &boardTempList); err != nil {
|
||||
@@ -111,28 +101,41 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
log.Printf("Front Temperature: %v\n", temps.FmTempSenIo)
|
||||
log.Printf("Rear Temperature: %v\n", temps.FmTempSenRear)
|
||||
|
||||
boardTempFront := UcsmTemperatures{
|
||||
Server: bladeDn,
|
||||
Component: temps.Dn,
|
||||
Description: "motherboard_front_temperature",
|
||||
Value: temps.FmTempSenIo,
|
||||
}
|
||||
|
||||
boardTempRear := UcsmTemperatures{
|
||||
Server: bladeDn,
|
||||
Component: temps.Dn,
|
||||
Description: "motherboard_rear_temperature",
|
||||
Value: temps.FmTempSenRear,
|
||||
}
|
||||
|
||||
temperatureResults = append(temperatureResults, boardTempFront)
|
||||
temperatureResults = append(temperatureResults, boardTempRear)
|
||||
|
||||
/*
|
||||
// TODO - work out a better way of running this twice, once for each temperature sensor
|
||||
|
||||
// Collect the actual metric values and send them on the channel
|
||||
for _, desc := range u.metrics {
|
||||
|
||||
// populate the labels array
|
||||
//labelValues := []string{bladeDn, temps.Dn, "motherboard_rear_temperature"}
|
||||
|
||||
// generate the metric
|
||||
metric1 := prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, temps.FmTempSenIo, bladeDn, temps.Dn, "motherboard_rear_temperature")
|
||||
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(desc, prometheus.GaugeValue, temps.FmTempSenRear, bladeDn, temps.Dn, "motherboard_front_temperature")
|
||||
metric2 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenRear, bladeDn, temps.Dn, "motherboard_front_temperature")
|
||||
// send the data
|
||||
ch <- metric2
|
||||
*/
|
||||
}
|
||||
//cswg.Wait()
|
||||
|
||||
//ch <- prometheus.MustNewConstMetric()
|
||||
}
|
||||
|
||||
log.Printf("GetUcsmTemperatures sending results to channel\n")
|
||||
ucsmTempsChannel <- temperatureResults
|
||||
//return
|
||||
}
|
||||
|
||||
/*
|
||||
|
141
internal/exporters/exporters.go
Normal file
141
internal/exporters/exporters.go
Normal file
@@ -0,0 +1,141 @@
|
||||
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")
|
||||
}
|
||||
|
||||
}
|
1
internal/exporters/structs.go
Normal file
1
internal/exporters/structs.go
Normal file
@@ -0,0 +1 @@
|
||||
package exporters
|
@@ -359,6 +359,26 @@ type ProcessorUnit struct {
|
||||
Voltage string `xml:"voltage,attr,omitempty"`
|
||||
}
|
||||
|
||||
// AdaptorVnicStats is a managed object representing statistics for a network adaptor
|
||||
// Added by Nathan. Incomplete representation of all data available
|
||||
type AdaptorVnicStats struct {
|
||||
XMLName xml.Name `xml:"adaptorVnicStats"`
|
||||
Dn string `xml:"dn,attr,omitempty"`
|
||||
Rn string `xml:"rn,attr,omitempty"`
|
||||
BytesRx uint64 `xml:"bytesRx,attr,omitempty"`
|
||||
BytesRxDelta uint64 `xml:"bytesRxDelta,attr,omitempty"`
|
||||
BytesTx uint64 `xml:"bytesTx,attr,omitempty"`
|
||||
BytesTxDelta uint64 `xml:"bytesTxDelta,attr,omitempty"`
|
||||
PacketsRx uint64 `xml:"packetsRx,attr,omitempty"`
|
||||
PacketsRxDelta uint64 `xml:"packetsRxDelta,attr,omitempty"`
|
||||
PacketsTx uint64 `xml:"packetsTx,attr,omitempty"`
|
||||
PacketsTxDelta uint64 `xml:"packetsTxDelta,attr,omitempty"`
|
||||
DroppedRx uint64 `xml:"droppedRx,attr,omitempty"`
|
||||
DroppedTx uint64 `xml:"droppedTx,attr,omitempty"`
|
||||
ErrorsRx uint64 `xml:"errorsRx,attr,omitempty"`
|
||||
ErrorsTx uint64 `xml:"errorsTx,attr,omitempty"`
|
||||
}
|
||||
|
||||
// AdaptorUnit is a managed object representing a network adaptor unit such as a
|
||||
// card that has NIC and/or HBA, SCSI functionality.
|
||||
type AdaptorUnit struct {
|
||||
|
Reference in New Issue
Block a user