Reading Linux System Info With C++

Ever wondered where utilities like top, jnettop, free and mpstat get their information on CPU usage, network throughput, free RAM etc. from? Well, the majority of it is hidden within the /proc filesystem, most of the rest can be found in /sys and the last few scraps have to be gleaned from elsewhere.

Some of the information held within /proc can also be obtained more directly with the use of a few C libraries. /proc has its own man page which is worth a read but here follows a summary of the files held within it and /sys that are useful for basic system monitoring:

Note: Where a ‘?’ appears in a filename, you must substitute a suitable alphabetic or numeric value for your system in its place.

CPU Utilisation (%)

  • Command: mpstat 1 1
  • File in proc: /proc/stat

For the output of mpstat, add all % columns except “idle” to get the the overall processor usage. By default mpstat reports overall processor usage since power-on, so to get a snapshot of processor usage over the last second, mpstat 1 1 is the command to run.

The values in /proc/stat for CPU utilisation are in 1/100ths of a second since power-on and are presented in a different order to the output of mpstat. See the /proc/stat section here for more information. To get a value for current processor usage, a delta of two readings will have to be made and divided by the time interval between them.

  • Command: uptime
  • File in proc: /proc/loadavg
  • C library: <sys/sysinfo.h>

The uptime command dispays the system uptime and the system load averages taken over time periods of 1, 5 and 15 minutes. In the sysinfo.h library, the struct sysinfo also holds this information.

CPU Temperature

  • Command: sensors
  • File in sys: /sys/bus/platform/devices/coretemp.?/temp?_input

This is a statistic that may not be stored in /proc or /sys and obtaining it may instead rely on the user installing a utility like sensors (lm-sensors) to query, on demand, a hardware specific I2C device on the motherboard. sensors may also provide you with other useful information like GPU temperature and fan speeds that cannot be found in /proc or /sys.

However, if you do have the correct file in proc, the file temp?_input stores the current temperature in 1/1000ths of a degree Celsius. The associated files temp?_label, temp?_max, temp?_crit and temp?_crit_alarm store the CPU/core name and fixed temperature limits. They should all correlate with the output of sensors.

Hard Disk Temperature

  • Command: smartctl -l scttempsts /dev/sda
  • Command: sudo /usr/sbin/hddtemp /dev/sd[abcde]

Out of the two commands, hddtemp produces a much neater output and the square-bracketed section of the command shows how it is easy to fetch temperature data for multiple drives with a single command (something that smartctl cannot do). Adding the -n flag to the hddtemp command produces a more easily parsable output with just a single Celsius value per line.

Hard Disk I/O Statistics (read/write kB/s)

  • Command: iostat
  • File in proc: /proc/diskstats
  • File in sys: /sys/block/?d?/stat

To recreate the numbers that iostat provides for kB read/written per second requires a bit more effort than recreating the other statistics.

The data within /proc is concentrated in a single file, whereas the disk I/O statistics in /sys are spread out in a one-disk-per-file arrangement.

To start with, we need the “sectors read/written” data from one of the aforementioned files taken at two different time intervals as the values in the files are cumulative since power-on. The delta of these two is divided by the interval and then multiplied by a conversion factor. i.e:

(sectors_read_latest_value – sectors_read_last_value) / interval_between_measurements) * conversion_factor

The “sectors read/written” values are from the 6th/10th column of /proc/diskstats or the 3rd/7th colum of /sys/block/?d?/stat. For a final value in kB/s, the conversion factor is 2. For a final value in MB/s, the conversion factor is 2048. The, at first glance, odd, conversion factors stem from the fact that the units of “sectors_read” are blocks of 512 Bytes. Hence 2 * 512 = 1 kB.

For the total amount of data read since power-on, the calculation is sectors_read * conversion_factor.

Hard Disk Size & Free Space

  • Command: df
  • File in sys: /sys/block/?d?/size (drive/partition size in sectors)
  • File in sys: /sys/block/?d?/queue/logical_block_size
  • C library: <sys/statvfs>

Using the /sys files, drive size in bytes is found with the calculation is drive_size_in_sectors * hw_sector_size. Documentation for the queue directory is here.

Using the statvfs library, the free space in bytes can be calculated from multiplying the members f_bsize and f_bfree (or f_bavail) of the statvfs struct, while total capacity in bytes can be calculated by multiplying f_blocks and f_frsize.

RAM Utilisation

  • Command: free
  • File in proc: /proc/meminfo
  • C library: <sys/sysinfo.h>
  • C library: <proc/sysinfo.h> (NB: need to link to procps)

In the output from free, the corresponding numbers in /proc/meminfo are

  • total = MemTotal
  • used = MemTotal – MemFree
  • free = MemFree
  • -/+ buffers/cache used = MemTotal – MemFree – Buffers – Cached
  • -/+ buffers/cache free = MemFree + Buffers + Cached

It is the “-/+ buffers/cache” numbers that are more useful.

The library sys/sysinfo provides values for total. free. buffer and shared RAM

Network Statistics

  • Command: netstat -i
  • Command: netstat -ie
  • File in proc: /proc/net/dev

The number of bytes sent/received given in /proc/net/dev are cumulative since boot, so as with the disk throughput, to get measurements in kB/s, the delta of two readings from the file must be divided by the time interval between them.

Time Information

  • Command: uptime
  • Command: date
  • File in proc: /proc/uptime
  • File in proc: /proc/stat
  • C library: <sys/sysinfo.h>
  • C library: <time>
  • C library: <chrono>

in /proc/uptime, the first number in the file is the number of seconds since power-on, the second is the number of seconds spent idle. In the library <sys/sysinfo.h>, the uptime member of the struct sysinfo also gives the number of seconds since power-on.

In /proc/stat, the field btime gives the time at which the system booted, in seconds since the Unix epoch.

The date command displays the current calendar date and local time. However, obtaining calendar dates and times is better done with the <ctime> library.

Leave a Reply

Your email address will not be published. Required fields are marked *