1 /* 2 Purpose : Parse /proc/meminfo 3 Author : Ky-Anh Huynh 4 Date : 2017 Sep 10th 5 Licens : MIT 6 */ 7 8 module dusybox.meminfo; 9 10 import std.stdio; 11 import std.format; 12 13 /* 14 $ cat /proc/meminfo 15 MemTotal: 16337684 kB 16 MemFree: 2612196 kB 17 MemAvailable: 12543580 kB 18 Buffers: 1127916 kB 19 Cached: 7467756 kB 20 ... 21 */ 22 size_t[string] meminfo(in string[] lines) { 23 size_t[string] results; 24 25 foreach(string line; lines) { 26 string key; 27 size_t value; 28 auto line_st = line; 29 try { 30 line_st.formattedRead!"%s: %s"(key, value); 31 results[key] = value; 32 } 33 catch (Exception exc) { 34 debug(2) stderr.write("meminfo: Unable to parse (key, value) from line '%s'", line); 35 } 36 } 37 38 if ("Cached" !in results 39 || "MemAvailable" !in results 40 || "MemTotal" !in results 41 || "MemFree" !in results 42 || "Buffers" !in results 43 || "Shmem" !in results 44 || "SReclaimable" !in results) { 45 46 stderr.writeln("meminfo: Missing some memory information."); 47 return results; 48 } 49 50 results["PageCached"] = results["Cached"]; 51 results["Cached"] = results["PageCached"] + results["SReclaimable"]; 52 53 /* 54 See https://gitlab.com/procps-ng/procps/blob/master/proc/sysinfo.c#L792 55 56 Quoted: 57 if kb_main_available is greater than kb_main_total or our calculation of 58 mem_used overflows, that's symptomatic of running within a lxc container 59 where such values will be dramatically distorted over those of the host. 60 */ 61 if (results["MemAvailable"] > results["MemTotal"]) { 62 results["MemAvailable"] = results["MemFree"]; 63 } 64 auto mem_used = results["MemTotal"] - results["MemFree"]; 65 if (mem_used >= results["Buffers"] + results["Cached"]) { 66 mem_used -= results["Buffers"] + results["Cached"]; 67 } 68 69 results["MemUsed"] = mem_used; 70 71 return results; 72 } 73 74 size_t[string] meminfo(in string filename = "/proc/meminfo") { 75 string[] lines; 76 77 foreach(string line; std.stdio.lines(filename.File("r"))) { 78 lines ~= line; 79 } 80 return meminfo(lines); 81 } 82 83 unittest { 84 string[] empty_arr; 85 size_t[string] empty_result; 86 87 assert(empty_result == meminfo(empty_arr)); 88 89 const string[] lines = [ 90 "MemTotal: 10000 kB\n", 91 "MemFree: 1000 kB\n"]; 92 93 auto results = meminfo(lines); 94 95 assert(results["MemTotal"] == 10000, "Unable to read MemTotal."); 96 assert(results["MemFree"] == 1000, "Unable to read MemFree."); 97 98 results = meminfo(); 99 assert(results["Active"] > 0); 100 }