Skip to content

Commit

Permalink
fix(meminfo): account for optional unit field so values are accurate
Browse files Browse the repository at this point in the history
Addresses: #565

Previously, this function was ignoring the optional unit field, leading
to incorrect results on systems that do report the field. This uses the
humanize lib used elsewhere within the Prometheus ecosystem to normalize
the value to bytes, including when a unit is provided.

Signed-off-by: TJ Hoplock <[email protected]>
  • Loading branch information
tjhop committed Sep 15, 2023
1 parent c05b611 commit f6b7f75
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 35 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/prometheus/procfs
go 1.19

require (
github.com/dustin/go-humanize v1.0.1
github.com/google/go-cmp v0.5.9
golang.org/x/sync v0.3.0
golang.org/x/sys v0.11.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
Expand Down
27 changes: 20 additions & 7 deletions meminfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"strconv"
"strings"

"github.com/dustin/go-humanize"

"github.com/prometheus/procfs/internal/util"
)

Expand Down Expand Up @@ -162,15 +164,26 @@ func parseMemInfo(r io.Reader) (*Meminfo, error) {
var m Meminfo
s := bufio.NewScanner(r)
for s.Scan() {
// Each line has at least a name and value; we ignore the unit.
fields := strings.Fields(s.Text())
if len(fields) < 2 {
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, s.Text())
}
var v uint64

v, err := strconv.ParseUint(fields[1], 0, 64)
if err != nil {
return nil, err
switch len(fields) {
case 2:
// No unit present, parse the value as bytes directly.
val, err := strconv.ParseUint(fields[1], 0, 64)
if err != nil {
return nil, err
}
v = val
case 3:
// Unit present, convert and normalize to bytes.
val, err := humanize.ParseBytes(fmt.Sprintf("%s %s", fields[1], fields[2]))
if err != nil {
return nil, err
}
v = val
default:
return nil, fmt.Errorf("%w: Malformed line %q", ErrFileParse, s.Text())
}

switch fields[0] {
Expand Down
56 changes: 28 additions & 28 deletions meminfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,48 @@ import (

func TestMeminfo(t *testing.T) {
expected := Meminfo{
MemTotal: newuint64(15666184),
MemFree: newuint64(440324),
Buffers: newuint64(1020128),
Cached: newuint64(12007640),
MemTotal: newuint64(15666184000),
MemFree: newuint64(440324000),
Buffers: newuint64(1020128000),
Cached: newuint64(12007640000),
SwapCached: newuint64(0),
Active: newuint64(6761276),
Inactive: newuint64(6532708),
ActiveAnon: newuint64(267256),
InactiveAnon: newuint64(268),
ActiveFile: newuint64(6494020),
InactiveFile: newuint64(6532440),
Active: newuint64(6761276000),
Inactive: newuint64(6532708000),
ActiveAnon: newuint64(267256000),
InactiveAnon: newuint64(268000),
ActiveFile: newuint64(6494020000),
InactiveFile: newuint64(6532440000),
Unevictable: newuint64(0),
Mlocked: newuint64(0),
SwapTotal: newuint64(0),
SwapFree: newuint64(0),
Dirty: newuint64(768),
Dirty: newuint64(768000),
Writeback: newuint64(0),
AnonPages: newuint64(266216),
Mapped: newuint64(44204),
Shmem: newuint64(1308),
Slab: newuint64(1807264),
SReclaimable: newuint64(1738124),
SUnreclaim: newuint64(69140),
KernelStack: newuint64(1616),
PageTables: newuint64(5288),
AnonPages: newuint64(266216000),
Mapped: newuint64(44204000),
Shmem: newuint64(1308000),
Slab: newuint64(1807264000),
SReclaimable: newuint64(1738124000),
SUnreclaim: newuint64(69140000),
KernelStack: newuint64(1616000),
PageTables: newuint64(5288000),
NFSUnstable: newuint64(0),
Bounce: newuint64(0),
WritebackTmp: newuint64(0),
CommitLimit: newuint64(7833092),
CommittedAS: newuint64(530844),
VmallocTotal: newuint64(34359738367),
VmallocUsed: newuint64(36596),
VmallocChunk: newuint64(34359637840),
CommitLimit: newuint64(7833092000),
CommittedAS: newuint64(530844000),
VmallocTotal: newuint64(34359738367000),
VmallocUsed: newuint64(36596000),
VmallocChunk: newuint64(34359637840000),
HardwareCorrupted: newuint64(0),
AnonHugePages: newuint64(12288),
AnonHugePages: newuint64(12288000),
HugePagesTotal: newuint64(0),
HugePagesFree: newuint64(0),
HugePagesRsvd: newuint64(0),
HugePagesSurp: newuint64(0),
Hugepagesize: newuint64(2048),
DirectMap4k: newuint64(91136),
DirectMap2M: newuint64(16039936),
Hugepagesize: newuint64(2048000),
DirectMap4k: newuint64(91136000),
DirectMap2M: newuint64(16039936000),
}

have, err := getProcFixtures(t).Meminfo()
Expand Down

0 comments on commit f6b7f75

Please sign in to comment.