From 448eac68b04b9a4bbc54825b318d37a8151efc12 Mon Sep 17 00:00:00 2001 From: dongjiang1989 Date: Fri, 13 Oct 2023 14:42:20 +0800 Subject: [PATCH 1/3] Add commit_stats statistics Signed-off-by: dongjiang1989 --- btrfs/btrfs.go | 10 +++++++ btrfs/get.go | 62 ++++++++++++++++++++++++++++++++++++++++++ btrfs/get_test.go | 54 ++++++++++++++++++++++++++---------- testdata/fixtures.ttar | 8 ++++++ 4 files changed, 120 insertions(+), 14 deletions(-) diff --git a/btrfs/btrfs.go b/btrfs/btrfs.go index 094c898aa..90e45938a 100644 --- a/btrfs/btrfs.go +++ b/btrfs/btrfs.go @@ -25,6 +25,7 @@ type Stats struct { NodeSize uint64 QuotaOverride uint64 SectorSize uint64 + CommitStats CommitStats } // Allocation contains allocation statistics for data, metadata and system data. @@ -65,3 +66,12 @@ type LayoutUsage struct { type Device struct { Size uint64 } + +// Number of commits and various time related statistics. +// See Linux fs/btrfs/sysfs.c with 6.x version +type CommitStats struct { + Commits uint64 + LastCommitMs uint64 + MaxCommitMs uint64 + TotalCommitMs uint64 +} diff --git a/btrfs/get.go b/btrfs/get.go index 77c72e127..178e75f4e 100644 --- a/btrfs/get.go +++ b/btrfs/get.go @@ -14,6 +14,8 @@ package btrfs import ( + "bufio" + "fmt" "os" "path" "path/filepath" @@ -245,6 +247,66 @@ func (r *reader) readFilesystemStats() (s *Stats) { Metadata: r.readAllocationStats("allocation/metadata"), System: r.readAllocationStats("allocation/system"), }, + + // Read commit stats data + CommitStats: r.readCommitStats("commit_stats"), } return } + +// readCommitStats returns the commit_stats information for commit stats metrics. +func (r *reader) readCommitStats(p string) CommitStats { + stats := CommitStats{} + + f, err := os.Open(path.Join(r.path, p)) + if err != nil { + // if commit_stats not found. maybe btrfs version < 6.0 + if !os.IsNotExist(err) { + r.err = err + } + return stats + } + defer f.Close() + + scanner := bufio.NewScanner(f) + + for scanner.Scan() { + line := scanner.Text() + parts := strings.Fields(scanner.Text()) + // require + if len(parts) != 2 { + r.err = fmt.Errorf("invalid commit_stats line %q", line) + return stats + } + + value, err := strconv.ParseUint(parts[1], 10, 64) + if err != nil { + r.err = fmt.Errorf("error parsing commit_stats line: %w", err) + return stats + } + + switch metricName := parts[0]; metricName { + case "commits": + stats.Commits = value + case "last_commit_ms": + stats.LastCommitMs = value + case "max_commit_ms": + stats.MaxCommitMs = value + case "total_commit_ms": + stats.TotalCommitMs = value + default: + continue + } + if err != nil { + r.err = fmt.Errorf("errors parsing commit_stats metric line: %w", err) + return stats + } + } + + if err := scanner.Err(); err != nil { + r.err = fmt.Errorf("error scanning commit_stats file: %w", err) + return stats + } + + return stats +} diff --git a/btrfs/get_test.go b/btrfs/get_test.go index 23059c628..e2d09e1b6 100644 --- a/btrfs/get_test.go +++ b/btrfs/get_test.go @@ -19,6 +19,7 @@ type testVector struct { uuid, label string devices, features int data, meta, system alloc + commitstats commit } type alloc struct { @@ -27,6 +28,13 @@ type alloc struct { ratio float64 } +type commit struct { + commits uint64 + lastCommitMs uint64 + maxCommitMs uint64 + totalCommitMs uint64 +} + func TestFSBtrfsStats(t *testing.T) { btrfs, err := NewFS("testdata/fixtures/sys") if err != nil { @@ -39,22 +47,24 @@ func TestFSBtrfsStats(t *testing.T) { tests := []testVector{ { - uuid: "0abb23a9-579b-43e6-ad30-227ef47fcb9d", - label: "fixture", - devices: 2, - features: 4, - data: alloc{"raid0", 2147483648, 1}, - meta: alloc{"raid1", 1073741824, 2}, - system: alloc{"raid1", 8388608, 2}, + uuid: "0abb23a9-579b-43e6-ad30-227ef47fcb9d", + label: "fixture", + devices: 2, + features: 4, + data: alloc{"raid0", 2147483648, 1}, + meta: alloc{"raid1", 1073741824, 2}, + system: alloc{"raid1", 8388608, 2}, + commitstats: commit{258051, 1000, 51462, 47836090}, }, { - uuid: "7f07c59f-6136-449c-ab87-e1cf2328731b", - label: "", - devices: 4, - features: 5, - data: alloc{"raid5", 644087808, 4. / 3.}, - meta: alloc{"raid6", 429391872, 4. / 2.}, - system: alloc{"raid6", 16777216, 4. / 2.}, + uuid: "7f07c59f-6136-449c-ab87-e1cf2328731b", + label: "", + devices: 4, + features: 5, + data: alloc{"raid5", 644087808, 4. / 3.}, + meta: alloc{"raid6", 429391872, 4. / 2.}, + system: alloc{"raid6", 16777216, 4. / 2.}, + commitstats: commit{0, 0, 0, 0}, }, } @@ -98,5 +108,21 @@ func TestFSBtrfsStats(t *testing.T) { if want, got := tt.system.ratio, stats[i].Allocation.System.Layouts[tt.system.layout].Ratio; want != got { t.Errorf("fs %q unexpected system ratio:\nwant: %f\nhave: %f", tt.uuid, want, got) } + + if want, got := tt.commitstats.commits, stats[i].CommitStats.Commits; want != got { + t.Errorf("fs %q unexpected commit stats commits:\nwant: %d\nhave: %d", tt.uuid, want, got) + } + + if want, got := tt.commitstats.lastCommitMs, stats[i].CommitStats.LastCommitMs; want != got { + t.Errorf("fs %q unexpected commit stats last_commit_ms:\nwant: %d\nhave: %d", tt.uuid, want, got) + } + + if want, got := tt.commitstats.maxCommitMs, stats[i].CommitStats.MaxCommitMs; want != got { + t.Errorf("fs %q unexpected commit stats max_commit_ms:\nwant: %d\nhave: %d", tt.uuid, want, got) + } + + if want, got := tt.commitstats.totalCommitMs, stats[i].CommitStats.TotalCommitMs; want != got { + t.Errorf("fs %q unexpected commit stats total_commit_ms:\nwant: %d\nhave: %d", tt.uuid, want, got) + } } } diff --git a/testdata/fixtures.ttar b/testdata/fixtures.ttar index 92f72fa20..9d7e75d06 100644 --- a/testdata/fixtures.ttar +++ b/testdata/fixtures.ttar @@ -14229,6 +14229,14 @@ Lines: 1 4096 Mode: 444 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/commit_stats +Lines: 4 +commits 258051 +last_commit_ms 1000 +max_commit_ms 51462 +total_commit_ms 47836090EOF +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 9048ec4dcc2c9027083e1ae9286409cc377cc104 Mon Sep 17 00:00:00 2001 From: dongjiang1989 Date: Fri, 13 Oct 2023 14:49:34 +0800 Subject: [PATCH 2/3] fix golang-lint Signed-off-by: dongjiang1989 --- btrfs/btrfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/btrfs/btrfs.go b/btrfs/btrfs.go index 90e45938a..5b4ff350b 100644 --- a/btrfs/btrfs.go +++ b/btrfs/btrfs.go @@ -68,7 +68,7 @@ type Device struct { } // Number of commits and various time related statistics. -// See Linux fs/btrfs/sysfs.c with 6.x version +// See Linux fs/btrfs/sysfs.c with 6.x version. type CommitStats struct { Commits uint64 LastCommitMs uint64 From 711c2f122dedfc1bf8b65cb45a77b6a70a8532ab Mon Sep 17 00:00:00 2001 From: dongjiang1989 Date: Fri, 13 Oct 2023 14:58:48 +0800 Subject: [PATCH 3/3] remove useless code block Signed-off-by: dongjiang1989 --- btrfs/get.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/btrfs/get.go b/btrfs/get.go index 178e75f4e..db0046b6b 100644 --- a/btrfs/get.go +++ b/btrfs/get.go @@ -297,10 +297,6 @@ func (r *reader) readCommitStats(p string) CommitStats { default: continue } - if err != nil { - r.err = fmt.Errorf("errors parsing commit_stats metric line: %w", err) - return stats - } } if err := scanner.Err(); err != nil {