github.com/netdata/go.d.plugin@v0.58.1/modules/vsphere/collect.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package vsphere 4 5 import ( 6 "errors" 7 "fmt" 8 "time" 9 10 rs "github.com/netdata/go.d.plugin/modules/vsphere/resources" 11 12 "github.com/vmware/govmomi/performance" 13 ) 14 15 // ManagedEntityStatus 16 var overallStatuses = []string{"green", "red", "yellow", "gray"} 17 18 func (vs *VSphere) collect() (map[string]int64, error) { 19 vs.collectionLock.Lock() 20 defer vs.collectionLock.Unlock() 21 22 vs.Debug("starting collection process") 23 t := time.Now() 24 mx := make(map[string]int64) 25 26 err := vs.collectHosts(mx) 27 if err != nil { 28 return nil, err 29 } 30 31 err = vs.collectVMs(mx) 32 if err != nil { 33 return nil, err 34 } 35 36 vs.updateCharts() 37 38 vs.Debugf("metrics collected, process took %s", time.Since(t)) 39 40 return mx, nil 41 } 42 43 func (vs *VSphere) collectHosts(mx map[string]int64) error { 44 if len(vs.resources.Hosts) == 0 { 45 return nil 46 } 47 // NOTE: returns unsorted if at least one types.PerfMetricId Instance is not "" 48 metrics := vs.ScrapeHosts(vs.resources.Hosts) 49 if len(metrics) == 0 { 50 return errors.New("failed to scrape hosts metrics") 51 } 52 53 vs.collectHostsMetrics(mx, metrics) 54 55 return nil 56 } 57 58 func (vs *VSphere) collectHostsMetrics(mx map[string]int64, metrics []performance.EntityMetric) { 59 for k := range vs.discoveredHosts { 60 vs.discoveredHosts[k]++ 61 } 62 63 for _, metric := range metrics { 64 if host := vs.resources.Hosts.Get(metric.Entity.Value); host != nil { 65 vs.discoveredHosts[host.ID] = 0 66 writeHostMetrics(mx, host, metric.Value) 67 } 68 } 69 } 70 71 func writeHostMetrics(mx map[string]int64, host *rs.Host, metrics []performance.MetricSeries) { 72 for _, metric := range metrics { 73 if len(metric.Value) == 0 || metric.Value[0] == -1 { 74 continue 75 } 76 key := fmt.Sprintf("%s_%s", host.ID, metric.Name) 77 mx[key] = metric.Value[0] 78 } 79 for _, v := range overallStatuses { 80 key := fmt.Sprintf("%s_overall.status.%s", host.ID, v) 81 mx[key] = boolToInt(host.OverallStatus == v) 82 } 83 } 84 85 func (vs *VSphere) collectVMs(mx map[string]int64) error { 86 if len(vs.resources.VMs) == 0 { 87 return nil 88 } 89 // NOTE: returns unsorted if at least one types.PerfMetricId Instance is not "" 90 ems := vs.ScrapeVMs(vs.resources.VMs) 91 if len(ems) == 0 { 92 return errors.New("failed to scrape vms metrics") 93 } 94 95 vs.collectVMsMetrics(mx, ems) 96 97 return nil 98 } 99 100 func (vs *VSphere) collectVMsMetrics(mx map[string]int64, metrics []performance.EntityMetric) { 101 for id := range vs.discoveredVMs { 102 vs.discoveredVMs[id]++ 103 } 104 105 for _, metric := range metrics { 106 if vm := vs.resources.VMs.Get(metric.Entity.Value); vm != nil { 107 writeVMMetrics(mx, vm, metric.Value) 108 vs.discoveredVMs[vm.ID] = 0 109 } 110 } 111 } 112 113 func writeVMMetrics(mx map[string]int64, vm *rs.VM, metrics []performance.MetricSeries) { 114 for _, metric := range metrics { 115 if len(metric.Value) == 0 || metric.Value[0] == -1 { 116 continue 117 } 118 key := fmt.Sprintf("%s_%s", vm.ID, metric.Name) 119 mx[key] = metric.Value[0] 120 } 121 for _, v := range overallStatuses { 122 key := fmt.Sprintf("%s_overall.status.%s", vm.ID, v) 123 mx[key] = boolToInt(vm.OverallStatus == v) 124 } 125 } 126 127 func boolToInt(v bool) int64 { 128 if v { 129 return 1 130 } 131 return 0 132 }