diff --git a/q/psutil/psutil.q b/q/psutil/psutil.q new file mode 100644 index 0000000..eb9b19d --- /dev/null +++ b/q/psutil/psutil.q @@ -0,0 +1,37 @@ +// only implemented for linux +if[not(first string .z.o)in"l"; + '`nyi; + ] + +.finos.dep.include"../util/util.q" + +/// +// Get memory information about a process, possibly including USS, PSS, and swap. +// @param x pid +// @return A dictionary of memory information about the process. +.finos.psutil.memory_full_info:{ + pagesize:"J"$first system"getconf PAGE_SIZE"; + attrs:`vms`rss`shared`text`lib`data`dirty; + memory_info:pagesize*first flip attrs!("JJJJJJJ";" ")0:.finos.util.read0f .Q.dd[`:/proc;x,`statm]; + memory_info:`rss`vms xcols memory_info; + + smaps:.Q.dd[`:/proc]x,`smaps; + has_smaps:not not type key smaps; + memory_info_maps:$[has_smaps; + [ + r:.finos.util.read0f smaps; + r:{y where x y}[{$[2=count t:":"vs x;any(first t)like/:("Private_*";"Pss";"Swap");0b]}']r; + r:1024*sum each"J"${y group x}."S:\n"0:` sv -3_'r; + r:{?[x;();();`uss`pss`swap!((sum;enlist,{x where x like"Private_*"}key x);`Pss;`Swap)]}r; + r]; + ()]; + + memory_info,memory_info_maps} + +/// +// Get some memory statistic for a process as a fraction of total physical system memory. +// The statistic should be one of the symbol keys of the dictionary returned by memory_full_info. +// @param x statistic +// @param y pid +// @return A float of the memory statistic for the process divided by total physical system memory. +.finos.psutil.memory_fraction:{.finos.psutil.memory_full_info[y][x]%last system"w"} diff --git a/q/util/util.q b/q/util/util.q new file mode 100644 index 0000000..b0dd0a3 --- /dev/null +++ b/q/util/util.q @@ -0,0 +1,15 @@ +// General-purpose utility functions. + +/// +// read0, but compatible with non-seekable files (fifos, /proc, etc.). +// @param x file symbol +// @return A list of strings containing the contents of the file. +// @see read0 +.finos.util.read0f:{r:{y,read0 x}[h:hopen`$":fifo://",1_string x]over();hclose h;r} + +/// +// read1, but compatible with non-seekable files (fifos, /proc, etc.). +// @param x file symbol +// @return A byte vector containing the contents of the file. +// @see read1 +.finos.util.read1f:{r:{y,read1 x}[h:hopen`$":fifo://",1_string x]over();hclose h;r} diff --git a/tests/psutil/test.q b/tests/psutil/test.q new file mode 100644 index 0000000..72a8d32 --- /dev/null +++ b/tests/psutil/test.q @@ -0,0 +1,4 @@ +.finos.dep.loadScriptIn["finos/kdb";"psutil/psutil.q"] + +.finos.psutil.memory_full_info .z.i +.finos.psutil.memory_fraction[`rss].z.i