master
go 146 lines 2.77 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package powervault
4
5 import (
6 "sync"
7 "time"
8
9 "github.com/netdata/netdata/go/plugins/plugin/go.d/collector/powervault/client"
10 )
11
12 const discoveryEvery = 10
13
14 func (c *Collector) collect() error {
15 c.runs++
16 needsDiscovery := !c.lastDiscoveryOK || c.runs%discoveryEvery == 0
17 wasOK := c.lastDiscoveryOK
18
19 if needsDiscovery {
20 if err := c.discovery(); err != nil {
21 // Initial discovery must succeed.
22 if !wasOK {
23 return err
24 }
25 // Refresh failure — continue with previous data.
26 c.Warningf("discovery refresh failed, using previous data: %v", err)
27 }
28 }
29
30 var wg sync.WaitGroup
31 for _, fn := range []func(){
32 c.collectControllerStats,
33 c.collectVolumeStats,
34 c.collectPortStats,
35 c.collectPhyStats,
36 } {
37 wg.Add(1)
38 go func(f func()) {
39 defer wg.Done()
40 f()
41 }(fn)
42 }
43 wg.Wait()
44
45 // These use cached discovery data, no API calls.
46 c.collectHardwareHealth()
47 c.collectDriveMetrics()
48 c.collectSensorMetrics()
49 c.collectPoolCapacity()
50 c.collectSystemHealth()
51
52 return nil
53 }
54
55 func (c *Collector) discovery() error {
56 start := time.Now()
57 c.Debugf("starting discovery")
58
59 var d discovered
60
61 sys, err := c.client.System()
62 if err != nil {
63 c.lastDiscoveryOK = false
64 return err
65 }
66 d.system = sys
67
68 controllers, err := c.client.Controllers()
69 if err != nil {
70 c.lastDiscoveryOK = false
71 return err
72 }
73 d.controllers = controllers
74
75 drives, err := c.client.Drives()
76 if err != nil {
77 c.lastDiscoveryOK = false
78 return err
79 }
80 d.drives = drives
81
82 fans, err := c.client.Fans()
83 if err != nil {
84 c.lastDiscoveryOK = false
85 return err
86 }
87 d.fans = fans
88
89 psus, err := c.client.PowerSupplies()
90 if err != nil {
91 c.lastDiscoveryOK = false
92 return err
93 }
94 d.psus = psus
95
96 sensors, err := c.client.Sensors()
97 if err != nil {
98 c.lastDiscoveryOK = false
99 return err
100 }
101 d.sensors = sensors
102
103 frus, err := c.client.FRUs()
104 if err != nil {
105 c.lastDiscoveryOK = false
106 return err
107 }
108 d.frus = frus
109
110 volumes, err := c.client.Volumes()
111 if err != nil {
112 c.lastDiscoveryOK = false
113 return err
114 }
115 d.volumes = make(map[string]client.Volume, len(volumes))
116 for _, v := range volumes {
117 if c.volumeMatches(v.VolumeName) {
118 d.volumes[v.VolumeName] = v
119 }
120 }
121
122 pools, err := c.client.Pools()
123 if err != nil {
124 c.lastDiscoveryOK = false
125 return err
126 }
127 d.pools = pools
128
129 ports, err := c.client.Ports()
130 if err != nil {
131 c.lastDiscoveryOK = false
132 return err
133 }
134 d.ports = ports
135
136 // Atomic swap on full success.
137 c.discovered = d
138 c.lastDiscoveryOK = true
139
140 c.Debugf("discovery: %d controllers, %d drives, %d fans, %d PSUs, %d sensors, %d FRUs, %d volumes, %d pools, %d ports (took %s)",
141 len(d.controllers), len(d.drives), len(d.fans), len(d.psus),
142 len(d.sensors), len(d.frus), len(d.volumes), len(d.pools), len(d.ports),
143 time.Since(start))
144
145 return nil
146 }