mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-12-28 23:19:46 -08:00
Merge pull request #253 from prometheus/superq/md_raid0
Add support for raid0 devices in mdadm_linux collector.
This commit is contained in:
commit
344fe2c4c5
|
@ -486,6 +486,7 @@ node_load5 0.37
|
|||
# HELP node_md_blocks Total number of blocks on device.
|
||||
# TYPE node_md_blocks gauge
|
||||
node_md_blocks{device="md0"} 248896
|
||||
node_md_blocks{device="md10"} 3.14159265e+08
|
||||
node_md_blocks{device="md127"} 3.12319552e+08
|
||||
node_md_blocks{device="md3"} 5.853468288e+09
|
||||
node_md_blocks{device="md4"} 4.883648e+06
|
||||
|
@ -496,6 +497,7 @@ node_md_blocks{device="md9"} 523968
|
|||
# HELP node_md_blocks_synced Number of blocks synced on device.
|
||||
# TYPE node_md_blocks_synced gauge
|
||||
node_md_blocks_synced{device="md0"} 248896
|
||||
node_md_blocks_synced{device="md10"} 3.14159265e+08
|
||||
node_md_blocks_synced{device="md127"} 3.12319552e+08
|
||||
node_md_blocks_synced{device="md3"} 5.853468288e+09
|
||||
node_md_blocks_synced{device="md4"} 4.883648e+06
|
||||
|
@ -506,6 +508,7 @@ node_md_blocks_synced{device="md9"} 523968
|
|||
# HELP node_md_disks Total number of disks of device.
|
||||
# TYPE node_md_disks gauge
|
||||
node_md_disks{device="md0"} 2
|
||||
node_md_disks{device="md10"} 2
|
||||
node_md_disks{device="md127"} 2
|
||||
node_md_disks{device="md3"} 8
|
||||
node_md_disks{device="md4"} 2
|
||||
|
@ -516,6 +519,7 @@ node_md_disks{device="md9"} 4
|
|||
# HELP node_md_disks_active Number of active disks of device.
|
||||
# TYPE node_md_disks_active gauge
|
||||
node_md_disks_active{device="md0"} 2
|
||||
node_md_disks_active{device="md10"} 2
|
||||
node_md_disks_active{device="md127"} 2
|
||||
node_md_disks_active{device="md3"} 8
|
||||
node_md_disks_active{device="md4"} 2
|
||||
|
@ -526,6 +530,7 @@ node_md_disks_active{device="md9"} 4
|
|||
# HELP node_md_is_active Indicator whether the md-device is active or not.
|
||||
# TYPE node_md_is_active gauge
|
||||
node_md_is_active{device="md0"} 1
|
||||
node_md_is_active{device="md10"} 1
|
||||
node_md_is_active{device="md127"} 1
|
||||
node_md_is_active{device="md3"} 1
|
||||
node_md_is_active{device="md4"} 0
|
||||
|
|
|
@ -27,5 +27,7 @@ md9 : active raid1 sdc2[2] sdd2[3] sdb2[1] sda2[0]
|
|||
523968 blocks super 1.2 [4/4] [UUUU]
|
||||
resync=DELAYED
|
||||
|
||||
md10 : active raid0 sda1[0] sdb1[1]
|
||||
314159265 blocks 64k chunks
|
||||
|
||||
unused devices: <none>
|
||||
|
|
5
collector/fixtures/proc/mdstat_invalid
Normal file
5
collector/fixtures/proc/mdstat_invalid
Normal file
|
@ -0,0 +1,5 @@
|
|||
Personalities : [invalid]
|
||||
md3 : invalid
|
||||
314159265 blocks 64k chunks
|
||||
|
||||
unused devices: <none>
|
|
@ -29,6 +29,7 @@ import (
|
|||
|
||||
var (
|
||||
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
|
||||
raid0lineRE = regexp.MustCompile(`(\d+) blocks \d+k chunks`)
|
||||
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
|
||||
)
|
||||
|
||||
|
@ -76,6 +77,21 @@ func evalStatusline(statusline string) (active, total, size int64, err error) {
|
|||
return active, total, size, nil
|
||||
}
|
||||
|
||||
func evalRaid0line(statusline string) (size int64, err error) {
|
||||
matches := raid0lineRE.FindStringSubmatch(statusline)
|
||||
|
||||
if len(matches) != 2 {
|
||||
return 0, fmt.Errorf("invalid raid0 status line: %s", statusline)
|
||||
}
|
||||
|
||||
size, err = strconv.ParseInt(matches[1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%s in statusline: %s", err, statusline)
|
||||
}
|
||||
|
||||
return size, nil
|
||||
}
|
||||
|
||||
// Gets the size that has already been synced out of the sync-line.
|
||||
func evalBuildline(buildline string) (int64, error) {
|
||||
matches := buildlineRE.FindStringSubmatch(buildline)
|
||||
|
@ -108,7 +124,11 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
|
|||
mdStatusFile := string(content)
|
||||
|
||||
lines := strings.Split(mdStatusFile, "\n")
|
||||
var currentMD string
|
||||
var (
|
||||
currentMD string
|
||||
personality string
|
||||
active, total, size int64
|
||||
)
|
||||
|
||||
// Each md has at least the deviceline, statusline and one empty line afterwards
|
||||
// so we will have probably something of the order len(lines)/3 devices
|
||||
|
@ -133,17 +153,25 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
|
|||
}
|
||||
|
||||
mainLine := strings.Split(l, " ")
|
||||
if len(mainLine) < 3 {
|
||||
if len(mainLine) < 4 {
|
||||
return mdStates, fmt.Errorf("error parsing mdline: %s", l)
|
||||
}
|
||||
currentMD = mainLine[0] // name of md-device
|
||||
isActive := (mainLine[2] == "active") // activity status of said md-device
|
||||
currentMD = mainLine[0] // The name of the md-device.
|
||||
isActive := (mainLine[2] == "active") // The activity status of the md-device.
|
||||
personality = mainLine[3] // The personality type of the md-device.
|
||||
|
||||
if len(lines) <= i+3 {
|
||||
return mdStates, fmt.Errorf("error parsing mdstat: entry for %s has fewer lines than expected", currentMD)
|
||||
}
|
||||
|
||||
active, total, size, err := evalStatusline(lines[i+1]) // parse statusline, always present
|
||||
switch personality {
|
||||
case "raid0":
|
||||
active = int64(len(mainLine) - 4) // Get the number of devices from the main line.
|
||||
total = active // Raid0 active and total is always the same if active.
|
||||
size, err = evalRaid0line(lines[i+1]) // Parse statusline, always present.
|
||||
default:
|
||||
active, total, size, err = evalStatusline(lines[i+1]) // Parse statusline, always present.
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return mdStates, fmt.Errorf("error parsing mdstat: %s", err)
|
||||
|
|
|
@ -33,6 +33,7 @@ func TestMdadm(t *testing.T) {
|
|||
"md8": {"md8", true, 2, 2, 195310144, 16775552},
|
||||
"md7": {"md7", true, 3, 4, 7813735424, 7813735424},
|
||||
"md9": {"md9", true, 4, 4, 523968, 523968},
|
||||
"md10": {"md10", true, 2, 2, 314159265, 314159265},
|
||||
}
|
||||
|
||||
for _, md := range mdStates {
|
||||
|
@ -45,3 +46,11 @@ func TestMdadm(t *testing.T) {
|
|||
t.Errorf("expected number of parsed md-device to be %d, but was %d", len(refs), len(mdStates))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidMdstat(t *testing.T) {
|
||||
_, err := parseMdstat("fixtures/proc/mdstat_invalid")
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("parsing of invalid reference file did not find any errors")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue