From a09bbaacd12741265c60139470d6b5126c727e8c Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Mon, 6 Jun 2016 23:18:09 +0200 Subject: [PATCH] Add support for raid0 devices in mdadm_linux collector. --- collector/fixtures/e2e-output.txt | 5 ++++ collector/fixtures/proc/mdstat | 2 ++ collector/mdadm_linux.go | 38 +++++++++++++++++++++++++++---- collector/mdadm_linux_test.go | 1 + 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/collector/fixtures/e2e-output.txt b/collector/fixtures/e2e-output.txt index 2d949d63..23e13bd4 100644 --- a/collector/fixtures/e2e-output.txt +++ b/collector/fixtures/e2e-output.txt @@ -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 diff --git a/collector/fixtures/proc/mdstat b/collector/fixtures/proc/mdstat index b17f3fb2..adca5971 100644 --- a/collector/fixtures/proc/mdstat +++ b/collector/fixtures/proc/mdstat @@ -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: diff --git a/collector/mdadm_linux.go b/collector/mdadm_linux.go index 03224970..7b9ac3eb 100644 --- a/collector/mdadm_linux.go +++ b/collector/mdadm_linux.go @@ -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) diff --git a/collector/mdadm_linux_test.go b/collector/mdadm_linux_test.go index 120dc6d1..f86a4e0e 100644 --- a/collector/mdadm_linux_test.go +++ b/collector/mdadm_linux_test.go @@ -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 {