66 "os"
77 "os/exec"
88 "regexp"
9+ "strconv"
910 "strings"
1011
1112 "github.com/pkg/errors"
@@ -20,6 +21,7 @@ const subsystem = "sbd"
2021const SBD_STATUS_UNHEALTHY = "unhealthy"
2122const SBD_STATUS_HEALTHY = "healthy"
2223
24+ // NewCollector create a new sbd collector
2325func NewCollector (sbdPath string , sbdConfigPath string ) (* sbdCollector , error ) {
2426 err := checkArguments (sbdPath , sbdConfigPath )
2527 if err != nil {
@@ -33,6 +35,7 @@ func NewCollector(sbdPath string, sbdConfigPath string) (*sbdCollector, error) {
3335 }
3436
3537 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" })
3639
3740 return c , nil
3841}
@@ -68,6 +71,15 @@ func (c *sbdCollector) CollectWithError(ch chan<- prometheus.Metric) error {
6871 ch <- c .MakeGaugeMetric ("devices" , 1 , sbdDev , sbdStatus )
6972 }
7073
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+
7183 return nil
7284}
7385
@@ -132,3 +144,39 @@ func (c *sbdCollector) getSbdDeviceStatuses(sbdDevices []string) map[string]stri
132144
133145 return sbdStatuses
134146}
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