6
6
"os"
7
7
"os/exec"
8
8
"regexp"
9
+ "strconv"
9
10
"strings"
10
11
11
12
"github.com/pkg/errors"
@@ -20,6 +21,7 @@ const subsystem = "sbd"
20
21
const SBD_STATUS_UNHEALTHY = "unhealthy"
21
22
const SBD_STATUS_HEALTHY = "healthy"
22
23
24
+ // NewCollector create a new sbd collector
23
25
func NewCollector (sbdPath string , sbdConfigPath string ) (* sbdCollector , error ) {
24
26
err := checkArguments (sbdPath , sbdConfigPath )
25
27
if err != nil {
@@ -33,6 +35,7 @@ func NewCollector(sbdPath string, sbdConfigPath string) (*sbdCollector, error) {
33
35
}
34
36
35
37
c .SetDescriptor ("devices" , "SBD devices; one line per device" , []string {"device" , "status" })
38
+ c .SetDescriptor ("timeouts" , "SBD timeouts for each device and type" , []string {"device" , "type" })
36
39
37
40
return c , nil
38
41
}
@@ -68,6 +71,15 @@ func (c *sbdCollector) CollectWithError(ch chan<- prometheus.Metric) error {
68
71
ch <- c .MakeGaugeMetric ("devices" , 1 , sbdDev , sbdStatus )
69
72
}
70
73
74
+ sbdWatchdogs , sbdMsgWaits := c .getSbdTimeouts (sbdDevices )
75
+ for sbdDev , sbdWatchdog := range sbdWatchdogs {
76
+ ch <- c .MakeGaugeMetric ("timeouts" , sbdWatchdog , sbdDev , "watchdog" )
77
+ }
78
+
79
+ for sbdDev , sbdMsgWait := range sbdMsgWaits {
80
+ ch <- c .MakeGaugeMetric ("timeouts" , sbdMsgWait , sbdDev , "msgwait" )
81
+ }
82
+
71
83
return nil
72
84
}
73
85
@@ -132,3 +144,39 @@ func (c *sbdCollector) getSbdDeviceStatuses(sbdDevices []string) map[string]stri
132
144
133
145
return sbdStatuses
134
146
}
147
+
148
+ // for each sbd device, extract the watchdog and msgwait timeout via regex
149
+ func (c * sbdCollector ) getSbdTimeouts (sbdDevices []string ) (map [string ]float64 , map [string ]float64 ) {
150
+ sbdWatchdogs := make (map [string ]float64 )
151
+ sbdMsgWaits := make (map [string ]float64 )
152
+ for _ , sbdDev := range sbdDevices {
153
+ sbdDump , _ := exec .Command (c .sbdPath , "-d" , sbdDev , "dump" ).Output ()
154
+
155
+ regexW := regexp .MustCompile (`Timeout \(msgwait\) *: \d+` )
156
+ regex := regexp .MustCompile (`Timeout \(watchdog\) *: \d+` )
157
+
158
+ msgWaitLine := regexW .FindStringSubmatch (string (sbdDump ))
159
+ watchdogLine := regex .FindStringSubmatch (string (sbdDump ))
160
+
161
+ if watchdogLine == nil || msgWaitLine == nil {
162
+ continue
163
+ }
164
+
165
+ // get the timeout from the line
166
+ regexNumber := regexp .MustCompile (`\d+` )
167
+ watchdogTimeout := regexNumber .FindString (string (watchdogLine [0 ]))
168
+ msgWaitTimeout := regexNumber .FindString (string (msgWaitLine [0 ]))
169
+
170
+ // map the timeout to the device
171
+ if s , err := strconv .ParseFloat (watchdogTimeout , 64 ); err == nil {
172
+ sbdWatchdogs [sbdDev ] = s
173
+ }
174
+
175
+ // map the timeout to the device
176
+ if s , err := strconv .ParseFloat (msgWaitTimeout , 64 ); err == nil {
177
+ sbdMsgWaits [sbdDev ] = s
178
+ }
179
+
180
+ }
181
+ return sbdWatchdogs , sbdMsgWaits
182
+ }
0 commit comments