Question

I'm using Node.js to make a monitoring API for my home server à la Nagios and Munin. In doing so I've discovered that I would like more verbose memory information than os.freemem() can give me.

What I'd really love to do is turn something like cat /proc/meminfo into JSON.

/proc/meminfo

MemTotal:        1017948 kB
MemFree:          122180 kB
Buffers:          151336 kB
Cached:           546844 kB
SwapCached:            0 kB
Active:           583256 kB
Inactive:         215544 kB
Active(anon):     100784 kB
Inactive(anon):      276 kB
Active(file):     482472 kB
Inactive(file):   215268 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:        100620 kB
Mapped:            13452 kB
Shmem:               440 kB
Slab:              81232 kB
SReclaimable:      72388 kB
SUnreclaim:         8844 kB
KernelStack:         664 kB
PageTables:         4244 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      508972 kB
Committed_AS:     148780 kB
VmallocTotal:   34359738367 kB
VmallocUsed:        4136 kB
VmallocChunk:   34359725048 kB
HardwareCorrupted:     0 kB
AnonHugePages:     45056 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       30708 kB
DirectMap2M:     1017856 kB

In that vein what I've got is:

mem.js

var fs = require('fs');

function info() {
    var data = fs.readFileSync('/proc/meminfo').toString();
    var lines = data.split(/\n/g).map(function(line){
        return line.split(':');
    });

    return lines;
}

console.log(info());

This yields a two-dimensional array like so:

[ [ 'MemTotal', '        1017948 kB' ],
  [ 'MemFree', '          120612 kB' ],
  [ 'Buffers', '          151492 kB' ],
  [ 'Cached', '           547424 kB' ],
  [ 'SwapCached', '            0 kB' ],
  [ 'Active', '           585824 kB' ],
  [ 'Inactive', '         215456 kB' ],
  [ 'Active(anon)', '     102528 kB' ],
  [ 'Inactive(anon)', '      268 kB' ],
  [ 'Active(file)', '     483296 kB' ],
  [ 'Inactive(file)', '   215188 kB' ],
  [ 'Unevictable', '           0 kB' ],
  [ 'Mlocked', '               0 kB' ],
  [ 'SwapTotal', '             0 kB' ],
  [ 'SwapFree', '              0 kB' ],
  [ 'Dirty', '                88 kB' ],
  [ 'Writeback', '             0 kB' ],
  [ 'AnonPages', '        102412 kB' ],
  [ 'Mapped', '            13416 kB' ],
  [ 'Shmem', '               432 kB' ],
  [ 'Slab', '              81224 kB' ],
  [ 'SReclaimable', '      72408 kB' ],
  [ 'SUnreclaim', '         8816 kB' ],
  [ 'KernelStack', '         648 kB' ],
  [ 'PageTables', '         3632 kB' ],
  [ 'NFS_Unstable', '          0 kB' ],
  [ 'Bounce', '                0 kB' ],
  [ 'WritebackTmp', '          0 kB' ],
  [ 'CommitLimit', '      508972 kB' ],
  [ 'Committed_AS', '     141360 kB' ],
  [ 'VmallocTotal', '   34359738367 kB' ],
  [ 'VmallocUsed', '        4136 kB' ],
  [ 'VmallocChunk', '   34359725048 kB' ],
  [ 'HardwareCorrupted', '     0 kB' ],
  [ 'AnonHugePages', '     45056 kB' ],
  [ 'HugePages_Total', '       0' ],
  [ 'HugePages_Free', '        0' ],
  [ 'HugePages_Rsvd', '        0' ],
  [ 'HugePages_Surp', '        0' ],
  [ 'Hugepagesize', '       2048 kB' ],
  [ 'DirectMap4k', '       30708 kB' ],
  [ 'DirectMap2M', '     1017856 kB' ],
  [ '' ] ]

I could imagine a doubly-nested for loop iterating through the return of info() and assigning elements to a new object, but this seems inelegant.

What's a better way to convert the contents of /proc/meminfo into JSON?

Was it helpful?

Solution

I have modified a little bit your code to return a plain object with no padding. This function is untested (I'm on a Windows machine!), but somewhat like this will work:

function info() {
    var info = {};
    var data = fs.readFileSync('/proc/meminfo').toString();
    data.split(/\n/g).forEach(function(line){
        line = line.split(':');

        // Ignore invalid lines, if any
        if (line.length < 2) {
            return;
        }

        // Remove parseInt call to make all values strings
        info[line[0]] = parseInt(line[1].trim(), 10);
    });

    return info;
}

The expected result is the following:

{
    'MemTotal': 1017948,
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top